@symbiote-native/angular 3.2.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/babel-register-composed.cjs +2 -0
  2. package/build/angular/accessibility-inputs.d.ts +2 -1
  3. package/build/angular/accessibility-inputs.js +4 -1
  4. package/build/angular/accessibility-inputs.js.map +1 -1
  5. package/build/angular/callback-host.d.ts +1 -1
  6. package/build/angular/callback-host.js +57 -9
  7. package/build/angular/callback-host.js.map +1 -1
  8. package/build/angular/components/checkbox-props.d.ts +2 -0
  9. package/build/angular/components/checkbox-props.js +2 -0
  10. package/build/angular/components/checkbox-props.js.map +1 -0
  11. package/build/angular/components/flat-list/flat-list-handle.d.ts +35 -0
  12. package/build/angular/components/flat-list/flat-list-handle.js +48 -0
  13. package/build/angular/components/flat-list/flat-list-handle.js.map +1 -0
  14. package/build/angular/components/flat-list/flat-list-template.d.ts +1 -1
  15. package/build/angular/components/flat-list/flat-list-template.js +16 -0
  16. package/build/angular/components/flat-list/flat-list-template.js.map +1 -1
  17. package/build/angular/components/flat-list/index.d.ts +6 -30
  18. package/build/angular/components/flat-list/index.js +6 -36
  19. package/build/angular/components/flat-list/index.js.map +1 -1
  20. package/build/angular/components/image-inputs.d.ts +4 -0
  21. package/build/angular/components/image-inputs.js +81 -0
  22. package/build/angular/components/image-inputs.js.map +1 -0
  23. package/build/angular/components/image-props-resolve.d.ts +3 -0
  24. package/build/angular/components/image-props-resolve.js +133 -0
  25. package/build/angular/components/image-props-resolve.js.map +1 -0
  26. package/build/angular/components/image-shared.d.ts +8 -6
  27. package/build/angular/components/image-shared.js +23 -212
  28. package/build/angular/components/image-shared.js.map +1 -1
  29. package/build/angular/components/input-accessory-view-props.d.ts +4 -4
  30. package/build/angular/components/keyboard-avoiding-view/index.d.ts +3 -6
  31. package/build/angular/components/keyboard-avoiding-view/index.js +29 -56
  32. package/build/angular/components/keyboard-avoiding-view/index.js.map +1 -1
  33. package/build/angular/components/layout-conformance-props.d.ts +4 -0
  34. package/build/angular/components/layout-conformance-props.js +2 -0
  35. package/build/angular/components/layout-conformance-props.js.map +1 -0
  36. package/build/angular/components/modal/index.d.ts +6 -5
  37. package/build/angular/components/modal/index.js +17 -2
  38. package/build/angular/components/modal/index.js.map +1 -1
  39. package/build/angular/components/refresh-control-props.d.ts +7 -7
  40. package/build/angular/components/scroll-view-props.d.ts +8 -5
  41. package/build/angular/components/section-list/index.d.ts +17 -8
  42. package/build/angular/components/section-list/index.js +37 -28
  43. package/build/angular/components/section-list/index.js.map +1 -1
  44. package/build/angular/components/touchable-props.d.ts +2 -2
  45. package/build/angular/components/virtualized-list/cell-renderer-context.d.ts +12 -0
  46. package/build/angular/components/virtualized-list/cell-renderer-context.js +16 -0
  47. package/build/angular/components/virtualized-list/cell-renderer-context.js.map +1 -0
  48. package/build/angular/components/virtualized-list/directives.d.ts +26 -6
  49. package/build/angular/components/virtualized-list/directives.js +59 -5
  50. package/build/angular/components/virtualized-list/directives.js.map +1 -1
  51. package/build/angular/components/virtualized-list/index.d.ts +19 -15
  52. package/build/angular/components/virtualized-list/index.js +91 -61
  53. package/build/angular/components/virtualized-list/index.js.map +1 -1
  54. package/build/angular/components/virtualized-list/list-bags.d.ts +5 -1
  55. package/build/angular/components/virtualized-list/list-bags.js +31 -19
  56. package/build/angular/components/virtualized-list/list-bags.js.map +1 -1
  57. package/build/angular/components/virtualized-list/list-effects.d.ts +2 -2
  58. package/build/angular/components/virtualized-list/list-effects.js +17 -27
  59. package/build/angular/components/virtualized-list/list-effects.js.map +1 -1
  60. package/build/angular/components/virtualized-list/list-handle.d.ts +4 -1
  61. package/build/angular/components/virtualized-list/list-handle.js +13 -3
  62. package/build/angular/components/virtualized-list/list-handle.js.map +1 -1
  63. package/build/angular/components/virtualized-list/list-inputs.d.ts +19 -5
  64. package/build/angular/components/virtualized-list/list-inputs.js +47 -4
  65. package/build/angular/components/virtualized-list/list-inputs.js.map +1 -1
  66. package/build/angular/components/virtualized-list/list-props.d.ts +9 -3
  67. package/build/angular/components/virtualized-list/list-rows.d.ts +25 -0
  68. package/build/angular/components/virtualized-list/list-rows.js +25 -0
  69. package/build/angular/components/virtualized-list/list-rows.js.map +1 -0
  70. package/build/angular/components/virtualized-list/list-styles.d.ts +4 -0
  71. package/build/angular/components/virtualized-list/list-styles.js +10 -2
  72. package/build/angular/components/virtualized-list/list-styles.js.map +1 -1
  73. package/build/angular/components/virtualized-list/list-template.d.ts +1 -1
  74. package/build/angular/components/virtualized-list/list-template.js +159 -73
  75. package/build/angular/components/virtualized-list/list-template.js.map +1 -1
  76. package/build/angular/components/virtualized-list/nested-scope.d.ts +6 -0
  77. package/build/angular/components/virtualized-list/nested-scope.js +17 -0
  78. package/build/angular/components/virtualized-list/nested-scope.js.map +1 -0
  79. package/build/angular/components/virtualized-section-list/directives.d.ts +21 -9
  80. package/build/angular/components/virtualized-section-list/directives.js +8 -28
  81. package/build/angular/components/virtualized-section-list/directives.js.map +1 -1
  82. package/build/angular/components/virtualized-section-list/index.d.ts +39 -60
  83. package/build/angular/components/virtualized-section-list/index.js +67 -33
  84. package/build/angular/components/virtualized-section-list/index.js.map +1 -1
  85. package/build/angular/components/virtualized-section-list/section-cell.d.ts +29 -0
  86. package/build/angular/components/virtualized-section-list/section-cell.js +82 -0
  87. package/build/angular/components/virtualized-section-list/section-cell.js.map +1 -0
  88. package/build/angular/components/virtualized-section-list/section-list-props.d.ts +56 -0
  89. package/build/angular/components/virtualized-section-list/section-list-props.js +3 -0
  90. package/build/angular/components/virtualized-section-list/section-list-props.js.map +1 -0
  91. package/build/angular/components/virtualized-section-list/section-list-template.d.ts +1 -1
  92. package/build/angular/components/virtualized-section-list/section-list-template.js +34 -26
  93. package/build/angular/components/virtualized-section-list/section-list-template.js.map +1 -1
  94. package/build/angular/components.d.ts +8 -3
  95. package/build/angular/components.js +2 -1
  96. package/build/angular/components.js.map +1 -1
  97. package/build/angular/descriptor-to-angular/descriptor-host.d.ts +8 -0
  98. package/build/angular/descriptor-to-angular/descriptor-host.js +38 -0
  99. package/build/angular/descriptor-to-angular/descriptor-host.js.map +1 -0
  100. package/build/angular/descriptor-to-angular/index.d.ts +1 -0
  101. package/build/angular/descriptor-to-angular/index.js +4 -0
  102. package/build/angular/descriptor-to-angular/index.js.map +1 -1
  103. package/build/angular/element-base.d.ts +169 -0
  104. package/build/angular/element-base.js +304 -0
  105. package/build/angular/element-base.js.map +1 -0
  106. package/build/angular/element-props.d.ts +7 -7
  107. package/build/angular/element-text-input-native.d.ts +27 -0
  108. package/build/angular/element-text-input-native.js +52 -0
  109. package/build/angular/element-text-input-native.js.map +1 -0
  110. package/build/angular/elements-controls.d.ts +171 -0
  111. package/build/angular/elements-controls.js +394 -0
  112. package/build/angular/elements-controls.js.map +1 -0
  113. package/build/angular/elements-layout.d.ts +139 -0
  114. package/build/angular/elements-layout.js +276 -0
  115. package/build/angular/elements-layout.js.map +1 -0
  116. package/build/angular/elements-press.d.ts +103 -0
  117. package/build/angular/elements-press.js +239 -0
  118. package/build/angular/elements-press.js.map +1 -0
  119. package/build/angular/elements.d.ts +6 -516
  120. package/build/angular/elements.js +9 -1091
  121. package/build/angular/elements.js.map +1 -1
  122. package/build/angular/host-instance/index.d.ts +2 -0
  123. package/build/angular/host-instance/index.js +4 -4
  124. package/build/angular/host-instance/index.js.map +1 -1
  125. package/build/angular/index.d.ts +17 -9
  126. package/build/angular/index.js +24 -27
  127. package/build/angular/index.js.map +1 -1
  128. package/build/angular/modules/animated/create-animated-component.d.ts +1 -1
  129. package/build/angular/modules/animated/create-animated-component.js +1 -1
  130. package/build/angular/modules/animated/create-animated-component.js.map +1 -1
  131. package/build/angular/modules/animated/index.d.ts +54 -41
  132. package/build/angular/modules/animated/index.js +2 -26
  133. package/build/angular/modules/animated/index.js.map +1 -1
  134. package/build/angular/modules/app-registry/index.d.ts +3 -3
  135. package/build/angular/modules/app-registry/index.js +2 -2
  136. package/build/angular/modules/app-registry/index.js.map +1 -1
  137. package/build/angular/modules/status-bar/index.d.ts +9 -5
  138. package/build/angular/modules/status-bar/index.js +21 -10
  139. package/build/angular/modules/status-bar/index.js.map +1 -1
  140. package/build/angular/native-view-base.d.ts +10 -2
  141. package/build/angular/native-view-base.js +23 -2
  142. package/build/angular/native-view-base.js.map +1 -1
  143. package/build/angular/primitives/index.d.ts +4 -0
  144. package/build/angular/primitives/index.js +12 -0
  145. package/build/angular/primitives/index.js.map +1 -1
  146. package/build/angular/services/color-scheme.service.d.ts +1 -1
  147. package/build/angular/services/index.d.ts +1 -0
  148. package/build/angular/services/index.js +1 -0
  149. package/build/angular/services/index.js.map +1 -1
  150. package/build/angular/services/inject-event.d.ts +6 -0
  151. package/build/angular/services/inject-event.js +24 -0
  152. package/build/angular/services/inject-event.js.map +1 -0
  153. package/package.json +6 -6
  154. package/src/accessibility-inputs.ts +3 -0
  155. package/src/callback-host.ts +56 -8
  156. package/src/components/checkbox-props.ts +12 -0
  157. package/src/components/flat-list/flat-list-handle.ts +64 -0
  158. package/src/components/flat-list/flat-list-template.ts +16 -0
  159. package/src/components/flat-list/index.ts +6 -48
  160. package/src/components/image-inputs.ts +94 -0
  161. package/src/components/image-props-resolve.ts +172 -0
  162. package/src/components/image-shared.ts +26 -291
  163. package/src/components/input-accessory-view-props.ts +12 -8
  164. package/src/components/keyboard-avoiding-view/index.ts +39 -79
  165. package/src/components/layout-conformance-props.ts +8 -0
  166. package/src/components/modal/index.ts +42 -20
  167. package/src/components/refresh-control-props.ts +29 -25
  168. package/src/components/scroll-view-props.ts +84 -76
  169. package/src/components/section-list/index.ts +34 -37
  170. package/src/components/touchable-props.ts +6 -2
  171. package/src/components/virtualized-list/cell-renderer-context.ts +36 -0
  172. package/src/components/virtualized-list/directives.ts +84 -8
  173. package/src/components/virtualized-list/index.ts +118 -85
  174. package/src/components/virtualized-list/list-bags.ts +38 -19
  175. package/src/components/virtualized-list/list-effects.ts +20 -32
  176. package/src/components/virtualized-list/list-handle.ts +17 -4
  177. package/src/components/virtualized-list/list-inputs.ts +47 -0
  178. package/src/components/virtualized-list/list-props.ts +57 -50
  179. package/src/components/virtualized-list/list-rows.ts +66 -0
  180. package/src/components/virtualized-list/list-styles.ts +30 -1
  181. package/src/components/virtualized-list/list-template.ts +159 -73
  182. package/src/components/virtualized-list/nested-scope.ts +22 -0
  183. package/src/components/virtualized-section-list/directives.ts +41 -40
  184. package/src/components/virtualized-section-list/index.ts +114 -118
  185. package/src/components/virtualized-section-list/section-cell.ts +109 -0
  186. package/src/components/virtualized-section-list/section-list-props.ts +79 -0
  187. package/src/components/virtualized-section-list/section-list-template.ts +34 -26
  188. package/src/components.ts +9 -0
  189. package/src/descriptor-to-angular/descriptor-host.ts +27 -0
  190. package/src/descriptor-to-angular/index.ts +5 -0
  191. package/src/element-base.ts +289 -0
  192. package/src/element-props.ts +35 -33
  193. package/src/element-text-input-native.ts +31 -0
  194. package/src/elements-controls.ts +290 -0
  195. package/src/elements-layout.ts +168 -0
  196. package/src/elements-press.ts +153 -0
  197. package/src/elements.ts +76 -788
  198. package/src/host-instance/index.ts +4 -4
  199. package/src/index.ts +78 -23
  200. package/src/modules/animated/index.ts +2 -47
  201. package/src/modules/app-registry/index.ts +3 -1
  202. package/src/modules/status-bar/index.ts +24 -11
  203. package/src/native-view-base.ts +37 -2
  204. package/src/primitives/index.ts +7 -0
  205. package/src/services/color-scheme.service.ts +1 -1
  206. package/src/services/index.ts +1 -0
  207. package/src/services/inject-event.ts +52 -0
@@ -0,0 +1,290 @@
1
+ import {
2
+ Directive,
3
+ ElementRef,
4
+ EventEmitter,
5
+ Input,
6
+ Output,
7
+ Renderer2,
8
+ forwardRef,
9
+ inject,
10
+ } from '@angular/core';
11
+ import type { OnDestroy } from '@angular/core';
12
+ import { NG_VALUE_ACCESSOR, type ControlValueAccessor } from '@angular/forms';
13
+ import { VALUE_CHANGE_EVENT } from './renderer/value-change';
14
+ import type {
15
+ IActivityIndicatorProps,
16
+ IInputAccessoryViewViewProps,
17
+ ILayoutConformanceMode,
18
+ IModalViewProps,
19
+ ISwitchProps,
20
+ ITextInputProps,
21
+ } from '@symbiote-native/components';
22
+ import type { IStickyHeaderElementProps } from './element-props';
23
+ import type { IAngularRefreshControlProps } from './components/refresh-control-props';
24
+ import { TextInputNativeInputs } from './element-text-input-native';
25
+ import {
26
+ ReadBackElement,
27
+ SymbioteElement,
28
+ ValueChangeElement,
29
+ } from './element-base';
30
+
31
+ @Directive({ selector: 'text-input', standalone: true })
32
+ export class TextInputElement extends TextInputNativeInputs {
33
+ @Input() value?: ITextInputProps['value'];
34
+ @Input() defaultValue?: ITextInputProps['defaultValue'];
35
+ @Input() placeholder?: ITextInputProps['placeholder'];
36
+ @Input() placeholderTextColor?: ITextInputProps['placeholderTextColor'];
37
+ @Input() multiline?: ITextInputProps['multiline'];
38
+ @Input() numberOfLines?: ITextInputProps['numberOfLines'];
39
+ @Input() maxLength?: ITextInputProps['maxLength'];
40
+ @Input() editable?: ITextInputProps['editable'];
41
+ @Input() readOnly?: ITextInputProps['readOnly'];
42
+ @Input() autoFocus?: ITextInputProps['autoFocus'];
43
+ @Input() autoCapitalize?: ITextInputProps['autoCapitalize'];
44
+ @Input() autoComplete?: ITextInputProps['autoComplete'];
45
+ @Input() autoCorrect?: ITextInputProps['autoCorrect'];
46
+ @Input() blurOnSubmit?: ITextInputProps['blurOnSubmit'];
47
+ @Input() submitBehavior?: ITextInputProps['submitBehavior'];
48
+ @Input() cursorColor?: ITextInputProps['cursorColor'];
49
+ @Input() enterKeyHint?: ITextInputProps['enterKeyHint'];
50
+ @Input() returnKeyType?: ITextInputProps['returnKeyType'];
51
+ @Input() inputMode?: ITextInputProps['inputMode'];
52
+ @Input() keyboardType?: ITextInputProps['keyboardType'];
53
+ @Input() inputAccessoryViewID?: ITextInputProps['inputAccessoryViewID'];
54
+ @Input() scrollEnabled?: ITextInputProps['scrollEnabled'];
55
+ @Input() secureTextEntry?: ITextInputProps['secureTextEntry'];
56
+ @Input() selectTextOnFocus?: ITextInputProps['selectTextOnFocus'];
57
+ @Input() selection?: ITextInputProps['selection'];
58
+ @Input() selectionColor?: ITextInputProps['selectionColor'];
59
+ @Input() selectionHandleColor?: ITextInputProps['selectionHandleColor'];
60
+ @Input() showSoftInputOnFocus?: ITextInputProps['showSoftInputOnFocus'];
61
+ @Input() textAlign?: ITextInputProps['textAlign'];
62
+ @Input() textContentType?: ITextInputProps['textContentType'];
63
+ @Input() underlineColorAndroid?: ITextInputProps['underlineColorAndroid'];
64
+ @Input() onValueChange?: ITextInputProps['onValueChange'];
65
+ @Input() onChangeText?: ITextInputProps['onChangeText'];
66
+ @Input() onContentSizeChange?: ITextInputProps['onContentSizeChange'];
67
+ @Input() onEndEditing?: ITextInputProps['onEndEditing'];
68
+ @Input() onKeyPress?: ITextInputProps['onKeyPress'];
69
+ @Input() onSelectionChange?: ITextInputProps['onSelectionChange'];
70
+ @Input() onSubmitEditing?: ITextInputProps['onSubmitEditing'];
71
+
72
+ // NonNullable, not the prop type: `[(value)]="name"` binds a `string`, and an emitter that can
73
+ // also emit `undefined` fails the two-way assignability check ngtsc runs on the event half.
74
+ @Output() readonly valueChange = new EventEmitter<
75
+ NonNullable<ITextInputProps['value']>
76
+ >();
77
+
78
+ protected hasValueSubscriber(): boolean {
79
+ return this.valueChange.observed;
80
+ }
81
+
82
+ protected emitValue(value: unknown): void {
83
+ if (typeof value === 'string') this.valueChange.emit(value);
84
+ }
85
+ }
86
+
87
+ @Directive({ selector: 'text-input-multiline', standalone: true })
88
+ export class MultilineTextInputElement extends TextInputElement {}
89
+
90
+ @Directive({ selector: 'switch, symbiote-switch', standalone: true })
91
+ export class SwitchElement extends ValueChangeElement {
92
+ @Input() value?: ISwitchProps['value'];
93
+ @Input() disabled?: ISwitchProps['disabled'];
94
+ @Input() trackColor?: ISwitchProps['trackColor'];
95
+ @Input() thumbColor?: ISwitchProps['thumbColor'];
96
+ @Input() ios_backgroundColor?: ISwitchProps['ios_backgroundColor'];
97
+ @Input() onValueChange?: ISwitchProps['onValueChange'];
98
+
99
+ @Output() readonly valueChange = new EventEmitter<
100
+ NonNullable<ISwitchProps['value']>
101
+ >();
102
+
103
+ protected hasValueSubscriber(): boolean {
104
+ return this.valueChange.observed;
105
+ }
106
+
107
+ protected emitValue(value: unknown): void {
108
+ if (typeof value === 'boolean') this.valueChange.emit(value);
109
+ }
110
+ }
111
+
112
+ /**
113
+ * `[(ngModel)]` / `formControlName` on a `<text-input>` or a `<switch>`.
114
+ *
115
+ * The wrappers provided `NG_VALUE_ACCESSOR` themselves; a tag has no class for @angular/forms to
116
+ * call into, so the accessor moves onto a directive of its own rather than being dropped — the
117
+ * shape Angular's own `DefaultValueAccessor` takes for `<input>`. Providing it unconditionally is
118
+ * safe: @angular/forms looks the accessor up only when an `ngModel` / `formControl*` directive sits
119
+ * on the SAME element, so a plain `<switch [(value)]>` never reaches it.
120
+ *
121
+ * Everything below goes through `Renderer2`, which is the adapter's own — `setProperty` lands in
122
+ * `routeProp` and `listen('valueChange')` is already unwrapped to a bare value there, so this
123
+ * directive holds no fold of its own.
124
+ */
125
+ @Directive()
126
+ abstract class SymbioteValueAccessor
127
+ implements ControlValueAccessor, OnDestroy
128
+ {
129
+ private readonly renderer = inject(Renderer2);
130
+ private readonly host = inject(ElementRef);
131
+ private unlisten?: () => void;
132
+
133
+ // The prop that spells "not editable" for this tag: RN's TextInput has no `disabled`, it has
134
+ // `editable` (inverted), while Switch takes `disabled` straight.
135
+ protected abstract writeDisabled(isDisabled: boolean): void;
136
+
137
+ protected setProp(name: string, value: unknown): void {
138
+ this.renderer.setProperty(this.host.nativeElement, name, value);
139
+ }
140
+
141
+ writeValue(value: unknown): void {
142
+ this.setProp('value', value ?? undefined);
143
+ }
144
+
145
+ registerOnChange(fn: (value: unknown) => void): void {
146
+ this.unlisten?.();
147
+ this.unlisten = this.renderer.listen(
148
+ this.host.nativeElement,
149
+ VALUE_CHANGE_EVENT,
150
+ (value: unknown) => {
151
+ // THE HALF THE DOM DOES FOR FREE, and without it a controlled input undoes every
152
+ // keystroke. `<text-input>`'s behavior re-commands the native text whenever `props.value`
153
+ // disagrees with what native last reported — that is what makes it controlled — and the
154
+ // read-back flush exists so the app's new value is on the node by the time the commit runs.
155
+ // @angular/forms does not reach the node in that window: `NgModel.ngOnChanges` defers
156
+ // `_updateValue` through `resolvedPromise.then`, so `writeValue` lands a MICROTASK after
157
+ // the flush, and the commit in between still reads the value from before the keystroke.
158
+ //
159
+ // In a browser there is nothing to do here: `input.value` already holds what the user
160
+ // typed. `node.props.value` is the same slot, and nothing else writes it — so the accessor
161
+ // mirrors it, which is the shape rather than a workaround. A later `writeValue` still wins,
162
+ // so an app that transforms or refuses the value keeps doing so, one microtask on.
163
+ //
164
+ // Without this, every character snaps the field back to its mounted text.
165
+ this.setProp('value', value);
166
+ fn(value);
167
+ },
168
+ );
169
+ }
170
+
171
+ // Native has no blur-driven "touched" signal distinct from `blur`, and RN's own onBlur is what an
172
+ // app binds — so touched is driven off the same event rather than a second channel.
173
+ registerOnTouched(fn: () => void): void {
174
+ this.setProp('onBlur', () => fn());
175
+ }
176
+
177
+ setDisabledState(isDisabled: boolean): void {
178
+ this.writeDisabled(isDisabled);
179
+ }
180
+
181
+ ngOnDestroy(): void {
182
+ this.unlisten?.();
183
+ }
184
+ }
185
+
186
+ @Directive({
187
+ selector:
188
+ 'text-input[ngModel], text-input[formControl], text-input[formControlName], text-input-multiline[ngModel], text-input-multiline[formControl], text-input-multiline[formControlName]',
189
+ standalone: true,
190
+ providers: [
191
+ {
192
+ provide: NG_VALUE_ACCESSOR,
193
+ useExisting: forwardRef(() => TextInputValueAccessor),
194
+ multi: true,
195
+ },
196
+ ],
197
+ })
198
+ export class TextInputValueAccessor extends SymbioteValueAccessor {
199
+ protected override writeDisabled(isDisabled: boolean): void {
200
+ this.setProp('editable', !isDisabled);
201
+ }
202
+ }
203
+
204
+ @Directive({
205
+ selector: 'switch[ngModel], switch[formControl], switch[formControlName]',
206
+ standalone: true,
207
+ providers: [
208
+ {
209
+ provide: NG_VALUE_ACCESSOR,
210
+ useExisting: forwardRef(() => SwitchValueAccessor),
211
+ multi: true,
212
+ },
213
+ ],
214
+ })
215
+ export class SwitchValueAccessor extends SymbioteValueAccessor {
216
+ protected override writeDisabled(isDisabled: boolean): void {
217
+ this.setProp('disabled', isDisabled);
218
+ }
219
+ }
220
+
221
+ // The HOST — RN's centering RCTView (ActivityIndicator.js:112), which is the tag an app writes.
222
+ // The four spinner props are declared here because that is where the app writes them; the engine's
223
+ // behavior redirects them onto the spinner it builds underneath (`slotProps`).
224
+ @Directive({ selector: 'activity-indicator', standalone: true })
225
+ export class ActivityIndicatorElement extends SymbioteElement {
226
+ @Input() animating?: IActivityIndicatorProps['animating'];
227
+ @Input() color?: IActivityIndicatorProps['color'];
228
+ @Input() size?: IActivityIndicatorProps['size'];
229
+ @Input() hidesWhenStopped?: IActivityIndicatorProps['hidesWhenStopped'];
230
+ }
231
+
232
+ // The native spinner. Built by the behavior's `buildStructure` and by the wrapper's render fn, never
233
+ // written in an app template — declared only so the tag alphabet stays covered, the same as
234
+ // `scroll-content`.
235
+ @Directive({ selector: 'activity-indicator-spinner', standalone: true })
236
+ export class ActivityIndicatorSpinnerElement extends ActivityIndicatorElement {}
237
+
238
+ @Directive({ selector: 'safe-area-view', standalone: true })
239
+ export class SafeAreaViewElement extends SymbioteElement {}
240
+
241
+ // RN's `experimental_LayoutConformance`: the tag paints as `display: contents` through its fold
242
+ @Directive({ selector: 'layout-conformance', standalone: true })
243
+ export class LayoutConformanceElement extends SymbioteElement {
244
+ @Input() mode?: ILayoutConformanceMode;
245
+ }
246
+
247
+ @Directive({ selector: 'modal, symbiote-modal', standalone: true })
248
+ export class ModalElement extends SymbioteElement {
249
+ @Input() visible?: IModalViewProps['visible'];
250
+ @Input() transparent?: IModalViewProps['transparent'];
251
+ @Input() animationType?: IModalViewProps['animationType'];
252
+ @Input() presentationStyle?: IModalViewProps['presentationStyle'];
253
+ @Input() supportedOrientations?: IModalViewProps['supportedOrientations'];
254
+ @Input() hardwareAccelerated?: IModalViewProps['hardwareAccelerated'];
255
+ @Input() statusBarTranslucent?: IModalViewProps['statusBarTranslucent'];
256
+ @Input()
257
+ navigationBarTranslucent?: IModalViewProps['navigationBarTranslucent'];
258
+ @Input() allowSwipeDismissal?: IModalViewProps['allowSwipeDismissal'];
259
+ @Input() backdropColor?: IModalViewProps['backdropColor'];
260
+ }
261
+
262
+ @Directive({ selector: 'refresh-control', standalone: true })
263
+ export class RefreshControlElement extends ReadBackElement {
264
+ @Input() refreshing?: IAngularRefreshControlProps['refreshing'];
265
+ @Input() enabled?: IAngularRefreshControlProps['enabled'];
266
+ @Input() colors?: IAngularRefreshControlProps['colors'];
267
+ @Input() tintColor?: IAngularRefreshControlProps['tintColor'];
268
+ @Input() title?: IAngularRefreshControlProps['title'];
269
+ @Input() titleColor?: IAngularRefreshControlProps['titleColor'];
270
+ @Input() size?: IAngularRefreshControlProps['size'];
271
+ @Input()
272
+ progressBackgroundColor?: IAngularRefreshControlProps['progressBackgroundColor'];
273
+ @Input()
274
+ progressViewOffset?: IAngularRefreshControlProps['progressViewOffset'];
275
+ @Input() onRefresh?: IAngularRefreshControlProps['onRefresh'];
276
+ }
277
+
278
+ @Directive({ selector: 'sticky-header', standalone: true })
279
+ export class StickyHeaderElement extends SymbioteElement {
280
+ @Input() inverted?: IStickyHeaderElementProps['inverted'];
281
+ @Input() nextHeaderLayoutY?: IStickyHeaderElementProps['nextHeaderLayoutY'];
282
+ @Input()
283
+ scrollAnimatedValue?: IStickyHeaderElementProps['scrollAnimatedValue'];
284
+ @Input() scrollViewHeight?: IStickyHeaderElementProps['scrollViewHeight'];
285
+ }
286
+
287
+ @Directive({ selector: 'input-accessory-view', standalone: true })
288
+ export class InputAccessoryViewElement extends SymbioteElement {
289
+ @Input() backgroundColor?: IInputAccessoryViewViewProps['backgroundColor'];
290
+ }
@@ -0,0 +1,168 @@
1
+ import { Directive, Input } from '@angular/core';
2
+ import type { IImageProps } from '@symbiote-native/components';
3
+ import type { IAngularImageBackgroundProps } from './components/image-background-props';
4
+ import type { IAngularScrollViewProps } from './components/scroll-view-props';
5
+ import { SymbioteElement } from './element-base';
6
+
7
+ @Directive({ selector: 'image, symbiote-image', standalone: true })
8
+ export class ImageElement extends SymbioteElement {
9
+ @Input() source?: IImageProps['source'];
10
+ @Input() src?: IImageProps['src'];
11
+ @Input() srcSet?: IImageProps['srcSet'];
12
+ @Input() alt?: IImageProps['alt'];
13
+ @Input() width?: IImageProps['width'];
14
+ @Input() height?: IImageProps['height'];
15
+ @Input() resizeMode?: IImageProps['resizeMode'];
16
+ @Input() resizeMethod?: IImageProps['resizeMethod'];
17
+ @Input() resizeMultiplier?: IImageProps['resizeMultiplier'];
18
+ @Input() defaultSource?: IImageProps['defaultSource'];
19
+ @Input() loadingIndicatorSource?: IImageProps['loadingIndicatorSource'];
20
+ @Input() blurRadius?: IImageProps['blurRadius'];
21
+ @Input() capInsets?: IImageProps['capInsets'];
22
+ @Input() crossOrigin?: IImageProps['crossOrigin'];
23
+ @Input() referrerPolicy?: IImageProps['referrerPolicy'];
24
+ @Input() fadeDuration?: IImageProps['fadeDuration'];
25
+ @Input()
26
+ progressiveRenderingEnabled?: IImageProps['progressiveRenderingEnabled'];
27
+ @Input() tintColor?: IImageProps['tintColor'];
28
+ @Input() onLoad?: IImageProps['onLoad'];
29
+ @Input() onLoadStart?: IImageProps['onLoadStart'];
30
+ @Input() onLoadEnd?: IImageProps['onLoadEnd'];
31
+ @Input() onError?: IImageProps['onError'];
32
+ @Input() onProgress?: IImageProps['onProgress'];
33
+ @Input() onPartialLoad?: IImageProps['onPartialLoad'];
34
+ }
35
+
36
+ // The box, not the image. Every Image prop below rides the engine's `slotPropsExcept` redirect onto
37
+ // the absolutely-filled image the behavior builds, exactly as RN's own `...props` spread does
38
+ // (ImageBackground.js:81) — so this directive declares them to make the BINDING legal, and the
39
+ // engine decides which node each lands on.
40
+ @Directive({ selector: 'image-background', standalone: true })
41
+ export class ImageBackgroundElement extends SymbioteElement {
42
+ @Input() imageStyle?: IAngularImageBackgroundProps['imageStyle'];
43
+ @Input() source?: IImageProps['source'];
44
+ @Input() src?: IImageProps['src'];
45
+ @Input() srcSet?: IImageProps['srcSet'];
46
+ @Input() alt?: IImageProps['alt'];
47
+ @Input() width?: IImageProps['width'];
48
+ @Input() height?: IImageProps['height'];
49
+ @Input() resizeMode?: IImageProps['resizeMode'];
50
+ @Input() resizeMethod?: IImageProps['resizeMethod'];
51
+ @Input() resizeMultiplier?: IImageProps['resizeMultiplier'];
52
+ @Input() defaultSource?: IImageProps['defaultSource'];
53
+ @Input() loadingIndicatorSource?: IImageProps['loadingIndicatorSource'];
54
+ @Input() blurRadius?: IImageProps['blurRadius'];
55
+ @Input() capInsets?: IImageProps['capInsets'];
56
+ @Input() crossOrigin?: IImageProps['crossOrigin'];
57
+ @Input() referrerPolicy?: IImageProps['referrerPolicy'];
58
+ @Input() fadeDuration?: IImageProps['fadeDuration'];
59
+ @Input()
60
+ progressiveRenderingEnabled?: IImageProps['progressiveRenderingEnabled'];
61
+ @Input() tintColor?: IImageProps['tintColor'];
62
+ @Input() onLoad?: IImageProps['onLoad'];
63
+ @Input() onLoadStart?: IImageProps['onLoadStart'];
64
+ @Input() onLoadEnd?: IImageProps['onLoadEnd'];
65
+ @Input() onError?: IImageProps['onError'];
66
+ @Input() onProgress?: IImageProps['onProgress'];
67
+ @Input() onPartialLoad?: IImageProps['onPartialLoad'];
68
+ }
69
+
70
+ @Directive({ selector: 'scroll-view', standalone: true })
71
+ export class ScrollViewElement extends SymbioteElement {
72
+ // No `horizontal` @Input: the axis is the TAG you write, never a prop — see
73
+ // `../components/scroll-view-props.ts`'s header. `HorizontalScrollViewElement` below is the
74
+ // other spelling, not a variant of this one.
75
+ @Input() scrollEnabled?: IAngularScrollViewProps['scrollEnabled'];
76
+ @Input() scrollEventThrottle?: IAngularScrollViewProps['scrollEventThrottle'];
77
+ @Input()
78
+ contentContainerStyle?: IAngularScrollViewProps['contentContainerStyle'];
79
+ @Input() contentInset?: IAngularScrollViewProps['contentInset'];
80
+ @Input()
81
+ contentInsetAdjustmentBehavior?: IAngularScrollViewProps['contentInsetAdjustmentBehavior'];
82
+ @Input() contentOffset?: IAngularScrollViewProps['contentOffset'];
83
+ @Input()
84
+ scrollIndicatorInsets?: IAngularScrollViewProps['scrollIndicatorInsets'];
85
+ @Input()
86
+ showsHorizontalScrollIndicator?: IAngularScrollViewProps['showsHorizontalScrollIndicator'];
87
+ @Input()
88
+ showsVerticalScrollIndicator?: IAngularScrollViewProps['showsVerticalScrollIndicator'];
89
+ @Input()
90
+ alwaysBounceHorizontal?: IAngularScrollViewProps['alwaysBounceHorizontal'];
91
+ @Input()
92
+ alwaysBounceVertical?: IAngularScrollViewProps['alwaysBounceVertical'];
93
+ @Input() bounces?: IAngularScrollViewProps['bounces'];
94
+ @Input() bouncesZoom?: IAngularScrollViewProps['bouncesZoom'];
95
+ @Input() centerContent?: IAngularScrollViewProps['centerContent'];
96
+ @Input() decelerationRate?: IAngularScrollViewProps['decelerationRate'];
97
+ @Input()
98
+ directionalLockEnabled?: IAngularScrollViewProps['directionalLockEnabled'];
99
+ @Input()
100
+ disableIntervalMomentum?: IAngularScrollViewProps['disableIntervalMomentum'];
101
+ @Input() endFillColor?: IAngularScrollViewProps['endFillColor'];
102
+ @Input() fadingEdgeLength?: IAngularScrollViewProps['fadingEdgeLength'];
103
+ @Input() indicatorStyle?: IAngularScrollViewProps['indicatorStyle'];
104
+ @Input() invertStickyHeaders?: IAngularScrollViewProps['invertStickyHeaders'];
105
+ @Input() keyboardDismissMode?: IAngularScrollViewProps['keyboardDismissMode'];
106
+ @Input()
107
+ keyboardShouldPersistTaps?: IAngularScrollViewProps['keyboardShouldPersistTaps'];
108
+ @Input()
109
+ automaticallyAdjustKeyboardInsets?: IAngularScrollViewProps['automaticallyAdjustKeyboardInsets'];
110
+ @Input()
111
+ maintainVisibleContentPosition?: IAngularScrollViewProps['maintainVisibleContentPosition'];
112
+ @Input() maximumZoomScale?: IAngularScrollViewProps['maximumZoomScale'];
113
+ @Input() minimumZoomScale?: IAngularScrollViewProps['minimumZoomScale'];
114
+ @Input() zoomScale?: IAngularScrollViewProps['zoomScale'];
115
+ @Input() nestedScrollEnabled?: IAngularScrollViewProps['nestedScrollEnabled'];
116
+ @Input() overScrollMode?: IAngularScrollViewProps['overScrollMode'];
117
+ @Input() pagingEnabled?: IAngularScrollViewProps['pagingEnabled'];
118
+ @Input() persistentScrollbar?: IAngularScrollViewProps['persistentScrollbar'];
119
+ @Input() pinchGestureEnabled?: IAngularScrollViewProps['pinchGestureEnabled'];
120
+ @Input() snapToAlignment?: IAngularScrollViewProps['snapToAlignment'];
121
+ @Input() snapToEnd?: IAngularScrollViewProps['snapToEnd'];
122
+ @Input() snapToInterval?: IAngularScrollViewProps['snapToInterval'];
123
+ @Input() snapToOffsets?: IAngularScrollViewProps['snapToOffsets'];
124
+ @Input() snapToStart?: IAngularScrollViewProps['snapToStart'];
125
+ @Input() stickyHeaderIndices?: IAngularScrollViewProps['stickyHeaderIndices'];
126
+ @Input() onScroll?: IAngularScrollViewProps['onScroll'];
127
+ @Input() onScrollBeginDrag?: IAngularScrollViewProps['onScrollBeginDrag'];
128
+ @Input() onScrollEndDrag?: IAngularScrollViewProps['onScrollEndDrag'];
129
+ @Input()
130
+ onMomentumScrollBegin?: IAngularScrollViewProps['onMomentumScrollBegin'];
131
+ @Input() onMomentumScrollEnd?: IAngularScrollViewProps['onMomentumScrollEnd'];
132
+ @Input() onScrollToTop?: IAngularScrollViewProps['onScrollToTop'];
133
+ @Input() onContentSizeChange?: IAngularScrollViewProps['onContentSizeChange'];
134
+ @Input()
135
+ onKeyboardWillShow?: IAngularScrollViewProps['onKeyboardWillShow'];
136
+ @Input()
137
+ onKeyboardWillHide?: IAngularScrollViewProps['onKeyboardWillHide'];
138
+ @Input() onKeyboardDidShow?: IAngularScrollViewProps['onKeyboardDidShow'];
139
+ @Input() onKeyboardDidHide?: IAngularScrollViewProps['onKeyboardDidHide'];
140
+ @Input()
141
+ automaticallyAdjustContentInsets?: IAngularScrollViewProps['automaticallyAdjustContentInsets'];
142
+ @Input()
143
+ automaticallyAdjustsScrollIndicatorInsets?: IAngularScrollViewProps['automaticallyAdjustsScrollIndicatorInsets'];
144
+ @Input()
145
+ canCancelContentTouches?: IAngularScrollViewProps['canCancelContentTouches'];
146
+ @Input()
147
+ experimental_endDraggingSensitivityMultiplier?: IAngularScrollViewProps['experimental_endDraggingSensitivityMultiplier'];
148
+ @Input() innerViewRef?: IAngularScrollViewProps['innerViewRef'];
149
+ @Input()
150
+ onScrollAnimationEnd?: IAngularScrollViewProps['onScrollAnimationEnd'];
151
+ @Input() scrollPerfTag?: IAngularScrollViewProps['scrollPerfTag'];
152
+ @Input()
153
+ scrollToOverflowEnabled?: IAngularScrollViewProps['scrollToOverflowEnabled'];
154
+ @Input()
155
+ scrollsChildToFocus?: IAngularScrollViewProps['scrollsChildToFocus'];
156
+ @Input() scrollsToTop?: IAngularScrollViewProps['scrollsToTop'];
157
+ @Input()
158
+ stickyHeaderHiddenOnScroll?: IAngularScrollViewProps['stickyHeaderHiddenOnScroll'];
159
+ }
160
+
161
+ @Directive({ selector: 'horizontal-scroll-view', standalone: true })
162
+ export class HorizontalScrollViewElement extends ScrollViewElement {}
163
+
164
+ @Directive({ selector: 'scroll-content', standalone: true })
165
+ export class ScrollContentElement extends SymbioteElement {}
166
+
167
+ @Directive({ selector: 'horizontal-scroll-content', standalone: true })
168
+ export class HorizontalScrollContentElement extends SymbioteElement {}
@@ -0,0 +1,153 @@
1
+ import { Directive, Input } from '@angular/core';
2
+ import type { INativeFeedbackBackground } from '@symbiote-native/components';
3
+ import type { IColorValue } from '@symbiote-native/engine';
4
+ import type { ITextElementProps } from './element-props';
5
+ import type { ICheckboxProps } from './components/checkbox-props';
6
+ import type { IAngularPressableProps } from './components/pressable-props';
7
+ import type {
8
+ IAngularTouchableHighlightProps,
9
+ IAngularTouchableOpacityProps,
10
+ } from './components/touchable-props';
11
+ import { SymbioteElement } from './element-base';
12
+
13
+ // BOTH SPELLINGS ON THE SEVEN DASHLESS TAGS, and it is a correctness fix rather than a convenience.
14
+ //
15
+ // The renderer has always mapped `symbiote-view` onto `view` (`PRIMITIVE_SELECTOR_ALIAS`), because
16
+ // `CUSTOM_ELEMENTS_SCHEMA` admits an unknown element only when the name carries a hyphen — so the
17
+ // hyphenated form is the spelling an app WITHOUT these directives has to use. It is the same tag and
18
+ // commits the same node.
19
+ //
20
+ // It was not the same tag HERE. A selector of `view` alone meant an app that imports
21
+ // `SYMBIOTE_ELEMENTS` and writes `<symbiote-view>` matched nothing: no type check on its props, no
22
+ // declared inputs, none of `SymbioteElement`'s forwarding or callback wrapping — silently, with the
23
+ // tree still looking right. Measured, that shape also ran ~8.6 us per element FASTER, which is what
24
+ // made it look like an optimization instead of a hole (`angular-directive-cost.itest.ts`).
25
+ //
26
+ // Only the seven dashless tags need it: `hyphenatedIntrinsicAliases` skips any tag that already
27
+ // carries a dash, so `symbiote-scroll-view` resolves nowhere on either side and the two halves agree
28
+ // already.
29
+ @Directive({ selector: 'view, symbiote-view', standalone: true })
30
+ export class ViewElement extends SymbioteElement {}
31
+
32
+ @Directive({ selector: 'pressable, symbiote-pressable', standalone: true })
33
+ export class PressableElement extends SymbioteElement {
34
+ @Input() disabled?: IAngularPressableProps['disabled'];
35
+ @Input() cancelable?: IAngularPressableProps['cancelable'];
36
+ @Input()
37
+ blockNativeResponder?: IAngularPressableProps['blockNativeResponder'];
38
+ @Input() delayLongPress?: IAngularPressableProps['delayLongPress'];
39
+ @Input() delayHoverIn?: IAngularPressableProps['delayHoverIn'];
40
+ @Input() delayHoverOut?: IAngularPressableProps['delayHoverOut'];
41
+ @Input() onHoverIn?: IAngularPressableProps['onHoverIn'];
42
+ @Input() onHoverOut?: IAngularPressableProps['onHoverOut'];
43
+ @Input()
44
+ pressRetentionOffset?: IAngularPressableProps['pressRetentionOffset'];
45
+ @Input() unstable_pressDelay?: IAngularPressableProps['unstable_pressDelay'];
46
+ @Input() android_ripple?: IAngularPressableProps['android_ripple'];
47
+ // ON THE BASE, so both touchables inherit it — the prop is Pressable's AND
48
+ // TouchableHighlight's upstream, and they extend this rather than repeat its surface.
49
+ @Input() testOnly_pressed?: IAngularPressableProps['testOnly_pressed'];
50
+ @Input()
51
+ android_disableSound?: IAngularPressableProps['android_disableSound'];
52
+ @Input() hasTVPreferredFocus?: IAngularPressableProps['hasTVPreferredFocus'];
53
+ @Input() nextFocusDown?: IAngularPressableProps['nextFocusDown'];
54
+ @Input() nextFocusForward?: IAngularPressableProps['nextFocusForward'];
55
+ @Input() nextFocusLeft?: IAngularPressableProps['nextFocusLeft'];
56
+ @Input() nextFocusRight?: IAngularPressableProps['nextFocusRight'];
57
+ @Input() nextFocusUp?: IAngularPressableProps['nextFocusUp'];
58
+ }
59
+
60
+ // RN's TouchableOpacity is a Pressable that also fades, and both halves are on the engine node —
61
+ // so it takes the same inputs and adds only the fade's own knob.
62
+ @Directive({ selector: 'touchable-opacity', standalone: true })
63
+ export class TouchableOpacityElement extends PressableElement {
64
+ @Input() activeOpacity?: number;
65
+ @Input() delayPressIn?: number;
66
+ @Input() delayPressOut?: number;
67
+ @Input() minPressDuration?: number;
68
+ }
69
+
70
+ // RN's TouchableHighlight is a Pressable that swaps its own background while pressed
71
+ // (TouchableHighlight.js), and the underlay machine runs on the engine node — so the tag takes the
72
+ // press surface plus the two knobs that describe the underlay. `onShowUnderlay`/`onHideUnderlay`
73
+ // need no @Input: they are events, bound as `(showUnderlay)` through the renderer's own listen.
74
+ @Directive({ selector: 'touchable-highlight', standalone: true })
75
+ export class TouchableHighlightElement extends PressableElement {
76
+ @Input() activeOpacity?: number;
77
+ @Input() underlayColor?: IColorValue;
78
+ @Input() delayPressIn?: number;
79
+ @Input() delayPressOut?: number;
80
+ @Input() minPressDuration?: number;
81
+ // TouchableHighlight.js:205 — forwarded to Pressability as `android_disableSound`.
82
+ @Input() touchSoundDisabled?: boolean;
83
+ }
84
+
85
+ // RN's TouchableNativeFeedback is a Pressable that CLONES onto its single child instead of
86
+ // rendering anything (TouchableNativeFeedback.js:339) — so the tag takes the press surface plus the
87
+ // two props that pick the Android ripple drawable. The tag itself commits no native view; the
88
+ // behavior configures the child, which is why `elements.test.ts` reads it as an anchor.
89
+ @Directive({ selector: 'touchable-native-feedback', standalone: true })
90
+ export class TouchableNativeFeedbackElement extends PressableElement {
91
+ @Input() background?: INativeFeedbackBackground;
92
+ @Input() useForeground?: boolean;
93
+ // TouchableNativeFeedback.js:228 — forwarded to Pressability as `android_disableSound`.
94
+ @Input() touchSoundDisabled?: boolean;
95
+ }
96
+
97
+ // RN's TouchableWithoutFeedback clones onto its single child the same way
98
+ // (TouchableWithoutFeedback.js:286) and installs no drawable, so it takes the press surface plus the
99
+ // three timing knobs it forwards to Pressability (:186-190) and nothing else. Like the tag above it
100
+ // commits no native view; `elements.test.ts` reads it as an anchor.
101
+ @Directive({ selector: 'touchable-without-feedback', standalone: true })
102
+ export class TouchableWithoutFeedbackElement extends PressableElement {
103
+ @Input() delayPressIn?: number;
104
+ @Input() delayPressOut?: number;
105
+ @Input() minPressDuration?: number;
106
+ // TouchableWithoutFeedback.js:199 — forwarded to Pressability as `android_disableSound`.
107
+ @Input() touchSoundDisabled?: boolean;
108
+ }
109
+
110
+ // RN's Button IS a TouchableOpacity (Button.js:384), and the behavior builds the view and the
111
+ // label under it — so the tag takes the touchable's surface plus the four props Button owns. There
112
+ // is no `style`: RN's Button has no such prop, and the label/background come from `color`.
113
+ @Directive({ selector: 'button, symbiote-button', standalone: true })
114
+ export class ButtonElement extends TouchableOpacityElement {
115
+ @Input() title?: string;
116
+ @Input() color?: IColorValue;
117
+ @Input() touchSoundDisabled?: boolean;
118
+ }
119
+
120
+ // expo-checkbox: View-like box plus the toggle on the engine node, поэтому только свои пять полей
121
+ // Нет `(valueChange)`: тоггл зовёт `onValueChange` как проп, он не engine-событие с read-back
122
+ @Directive({ selector: 'checkbox, symbiote-checkbox', standalone: true })
123
+ export class CheckboxElement extends SymbioteElement {
124
+ @Input() value?: ICheckboxProps['value'];
125
+ @Input() disabled?: ICheckboxProps['disabled'];
126
+ @Input() color?: ICheckboxProps['color'];
127
+ @Input() onValueChange?: ICheckboxProps['onValueChange'];
128
+ }
129
+
130
+ @Directive({ selector: 'text, symbiote-text', standalone: true })
131
+ export class TextElement extends SymbioteElement {
132
+ // Narrows the inherited input to a TEXT style so `fontSize`/`fontWeight` type-check here. The
133
+ // initializer is what TS2612 asks for to accept a redeclaration as deliberate; `declare` would
134
+ // be the other answer and cannot carry a decorator.
135
+ @Input() override style?: ITextElementProps['style'] = undefined;
136
+ @Input() override styleProp?: ITextElementProps['styleProp'] = undefined;
137
+ @Input() numberOfLines?: ITextElementProps['numberOfLines'];
138
+ @Input() ellipsizeMode?: ITextElementProps['ellipsizeMode'];
139
+ @Input() selectable?: ITextElementProps['selectable'];
140
+ @Input() adjustsFontSizeToFit?: ITextElementProps['adjustsFontSizeToFit'];
141
+ @Input() minimumFontScale?: ITextElementProps['minimumFontScale'];
142
+ @Input() allowFontScaling?: ITextElementProps['allowFontScaling'];
143
+ @Input() maxFontSizeMultiplier?: ITextElementProps['maxFontSizeMultiplier'];
144
+ @Input() selectionColor?: ITextElementProps['selectionColor'];
145
+ @Input() disabled?: ITextElementProps['disabled'];
146
+ @Input()
147
+ android_hyphenationFrequency?: ITextElementProps['android_hyphenationFrequency'];
148
+ @Input() dataDetectorType?: ITextElementProps['dataDetectorType'];
149
+ @Input() dynamicTypeRamp?: ITextElementProps['dynamicTypeRamp'];
150
+ @Input() lineBreakMode?: ITextElementProps['lineBreakMode'];
151
+ @Input() lineBreakStrategyIOS?: ITextElementProps['lineBreakStrategyIOS'];
152
+ @Input() textBreakStrategy?: ITextElementProps['textBreakStrategy'];
153
+ }