@symbiote-native/vue 0.5.0 → 2.0.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 (115) hide show
  1. package/README.md +28 -13
  2. package/babel-jsx.cjs +52 -0
  3. package/build/components/activity-indicator-props.d.ts +5 -0
  4. package/build/components/activity-indicator-props.js +1 -0
  5. package/build/components/button-props.d.ts +5 -0
  6. package/build/components/button-props.js +1 -0
  7. package/build/components/flat-list/index.d.ts +3 -3
  8. package/build/components/flat-list/index.js +2 -2
  9. package/build/components/image-background-props.d.ts +7 -0
  10. package/build/components/image-background-props.js +1 -0
  11. package/build/components/image-props.d.ts +5 -0
  12. package/build/components/image-props.js +5 -0
  13. package/build/components/{input-accessory-view.d.ts → input-accessory-view-props.d.ts} +1 -3
  14. package/build/components/input-accessory-view-props.js +5 -0
  15. package/build/components/keyboard-avoiding-view.js +3 -3
  16. package/build/components/modal/index.js +1 -1
  17. package/build/components/pressable-props.d.ts +29 -0
  18. package/build/components/pressable-props.js +12 -0
  19. package/build/components/refresh-control-props.d.ts +16 -0
  20. package/build/components/refresh-control-props.js +9 -0
  21. package/build/components/safe-area-view-props.d.ts +6 -0
  22. package/build/components/safe-area-view-props.js +5 -0
  23. package/build/components/scroll-view/{shared.d.ts → scroll-view-props.d.ts} +4 -27
  24. package/build/components/scroll-view/scroll-view-props.js +1 -0
  25. package/build/components/section-list/index.d.ts +3 -3
  26. package/build/components/switch/switch-props.d.ts +6 -0
  27. package/build/components/switch/switch-props.js +1 -0
  28. package/build/components/text-input/text-input-props.d.ts +5 -0
  29. package/build/components/text-input/text-input-props.js +1 -0
  30. package/build/components/text-props.d.ts +24 -0
  31. package/build/components/text-props.js +6 -0
  32. package/build/components/touchable-native-feedback-props.d.ts +6 -0
  33. package/build/components/touchable-native-feedback-props.js +1 -0
  34. package/build/components/touchable-props.d.ts +15 -0
  35. package/build/components/touchable-props.js +1 -0
  36. package/build/components/touchable-without-feedback-props.d.ts +3 -0
  37. package/build/components/touchable-without-feedback-props.js +1 -0
  38. package/build/components/view-props.d.ts +29 -0
  39. package/build/components/view-props.js +5 -0
  40. package/build/components/virtualized-list/index.d.ts +3 -3
  41. package/build/components/virtualized-list/index.js +42 -37
  42. package/build/components/virtualized-section-list/index.d.ts +3 -3
  43. package/build/composables/use-raw-attrs.d.ts +1 -0
  44. package/build/composables/use-raw-attrs.js +26 -0
  45. package/build/descriptor-to-vue.js +2 -2
  46. package/build/host-instance/index.js +4 -5
  47. package/build/index.d.ts +25 -27
  48. package/build/index.js +35 -15
  49. package/build/intrinsic-elements.d.ts +19 -0
  50. package/build/intrinsic-elements.js +1 -0
  51. package/build/jsx-runtime.d.ts +67 -0
  52. package/build/jsx-runtime.js +1 -0
  53. package/build/modules/animated/create-animated-component.d.ts +1 -1
  54. package/build/modules/animated/create-animated-component.js +18 -4
  55. package/build/modules/animated/index.d.ts +3 -1
  56. package/build/modules/animated/index.js +20 -19
  57. package/build/modules/image/index.d.ts +3 -0
  58. package/build/modules/image/index.js +13 -0
  59. package/build/register.d.ts +1 -0
  60. package/build/register.js +15 -0
  61. package/build/renderer/index.js +112 -12
  62. package/build/runtime-helpers/index.d.ts +14 -1
  63. package/build/runtime-helpers/index.js +250 -9
  64. package/build/utils/normalize-attrs.d.ts +1 -0
  65. package/build/utils/normalize-attrs.js +21 -15
  66. package/intrinsic-tags.cjs +52 -0
  67. package/metro-css-parser.cjs +2 -1
  68. package/metro-vue-transformer.cjs +83 -13
  69. package/package.json +33 -8
  70. package/build/components/activity-indicator/index.android.d.ts +0 -4
  71. package/build/components/activity-indicator/index.android.js +0 -10
  72. package/build/components/activity-indicator/index.d.ts +0 -1
  73. package/build/components/activity-indicator/index.ios.d.ts +0 -4
  74. package/build/components/activity-indicator/index.ios.js +0 -10
  75. package/build/components/activity-indicator/index.js +0 -4
  76. package/build/components/activity-indicator/shared.d.ts +0 -8
  77. package/build/components/activity-indicator/shared.js +0 -48
  78. package/build/components/button.d.ts +0 -14
  79. package/build/components/button.js +0 -59
  80. package/build/components/image-background.d.ts +0 -9
  81. package/build/components/image-background.js +0 -103
  82. package/build/components/image.d.ts +0 -9
  83. package/build/components/image.js +0 -90
  84. package/build/components/input-accessory-view.js +0 -41
  85. package/build/components/pressable.d.ts +0 -58
  86. package/build/components/pressable.js +0 -214
  87. package/build/components/refresh-control.d.ts +0 -20
  88. package/build/components/refresh-control.js +0 -47
  89. package/build/components/safe-area-view.d.ts +0 -8
  90. package/build/components/safe-area-view.js +0 -33
  91. package/build/components/scroll-view/index.android.d.ts +0 -4
  92. package/build/components/scroll-view/index.android.js +0 -64
  93. package/build/components/scroll-view/index.d.ts +0 -1
  94. package/build/components/scroll-view/index.ios.d.ts +0 -4
  95. package/build/components/scroll-view/index.ios.js +0 -17
  96. package/build/components/scroll-view/index.js +0 -4
  97. package/build/components/scroll-view/shared.js +0 -271
  98. package/build/components/scroll-view/sticky-header.d.ts +0 -7
  99. package/build/components/scroll-view/sticky-header.js +0 -208
  100. package/build/components/switch/index.android.d.ts +0 -12
  101. package/build/components/switch/index.android.js +0 -13
  102. package/build/components/switch/index.d.ts +0 -2
  103. package/build/components/switch/index.ios.d.ts +0 -12
  104. package/build/components/switch/index.ios.js +0 -11
  105. package/build/components/switch/index.js +0 -5
  106. package/build/components/switch/shared.d.ts +0 -23
  107. package/build/components/switch/shared.js +0 -126
  108. package/build/components/text-input/index.d.ts +0 -24
  109. package/build/components/text-input/index.js +0 -242
  110. package/build/components/touchable-native-feedback.d.ts +0 -24
  111. package/build/components/touchable-native-feedback.js +0 -77
  112. package/build/components/touchable.d.ts +0 -50
  113. package/build/components/touchable.js +0 -278
  114. package/build/components.d.ts +0 -51
  115. package/build/components.js +0 -29
@@ -1,126 +0,0 @@
1
- // Switch, the Vue lifecycle half. The logic (lastNativeReport reducer, valueFromChange, the
2
- // snap-back decision) lives in @symbiote-native/components/state and the render in
3
- // @symbiote-native/components/view, both shared verbatim with React. Vue supplies the
4
- // reactivity: a ref holds what native last reported, a function ref grabs the host node, and a
5
- // post-flush watch snaps native back when the parent rejects a toggle.
6
- //
7
- // Inputs arrive as attrs (untyped), so each is narrowed with a runtime guard, never a cast.
8
- // onValueChange MUST be stripped from the forwarded attrs: it is not a ViewConfig event, so
9
- // leaking it would reach Fabric as a function prop and crash Android's folly::dynamic.
10
- import { defineComponent, ref, shallowRef, watch } from '@vue/runtime-core';
11
- import { renderSwitch, switchReducer, createInitialSwitchState, shouldSnapBack, valueFromChange, } from '@symbiote-native/components';
12
- import { dispatchViewCommand, isSymbioteNode, dlog, } from '@symbiote-native/engine';
13
- import { descriptorToVue } from '../../descriptor-to-vue.js';
14
- import { normalizeVueAttrs } from '../../utils/normalize-attrs.js';
15
- import { resolveModelValue, emitModelUpdate } from '../../utils/model-binding.js';
16
- function isRecord(value) {
17
- return typeof value === 'object' && value !== null && !Array.isArray(value);
18
- }
19
- function asString(value) {
20
- return typeof value === 'string' ? value : undefined;
21
- }
22
- function isBoolean(value) {
23
- return typeof value === 'boolean';
24
- }
25
- function normalizeTrackColor(value) {
26
- if (!isRecord(value))
27
- return undefined;
28
- const trackColor = {};
29
- if (typeof value.false === 'string')
30
- trackColor.false = value.false;
31
- if (typeof value.true === 'string')
32
- trackColor.true = value.true;
33
- return trackColor;
34
- }
35
- // The render fn's style param is a plain object; array/registered styles degrade to undefined
36
- // (the engine flattens those on its own).
37
- function isViewStyleObject(value) {
38
- return typeof value === 'object' && value !== null && !Array.isArray(value);
39
- }
40
- // Everything else forwards onto the host node. onValueChange is pure JS and must never reach Fabric.
41
- const HANDLED_ATTRS = [
42
- 'value',
43
- 'modelValue',
44
- 'disabled',
45
- 'trackColor',
46
- 'thumbColor',
47
- 'ios_backgroundColor',
48
- 'style',
49
- 'onValueChange',
50
- ];
51
- function forwardAttrs(attrs) {
52
- const result = {};
53
- for (const key of Object.keys(attrs)) {
54
- if (!HANDLED_ATTRS.includes(key))
55
- result[key] = attrs[key];
56
- }
57
- return result;
58
- }
59
- export function createSwitch(platform) {
60
- return defineComponent((_props, { attrs: rawAttrs, emit }) => {
61
- // shallowRef, NOT ref: a plain ref() would hand back a reactive Proxy the engine's WeakMap
62
- // mirror doesn't recognize, so every imperative command would silently no-op. General rule
63
- // for this adapter: host nodes live in shallowRef / markRaw.
64
- const nodeRef = shallowRef(null);
65
- const state = ref(createInitialSwitchState());
66
- const setNodeRef = (el) => {
67
- nodeRef.value = isSymbioteNode(el) ? el : null;
68
- };
69
- const handleChange = (event) => {
70
- const next = valueFromChange(event);
71
- dlog(`Switch onChange value=${String(next)} eventCount=${String(event.nativeEvent.eventCount)}`);
72
- if (next === undefined)
73
- return;
74
- emit('valueChange', next, event);
75
- emitModelUpdate(emit, next);
76
- state.value = switchReducer(state.value, {
77
- type: 'native-reported',
78
- value: next,
79
- });
80
- };
81
- // Snap-back: when native reported a value the parent rejected, command the JS value back
82
- // down (the controlled-Switch correction RN does via SwitchCommands.setValue). The
83
- // decision is shared with React (shouldSnapBack); only the command name is platform-
84
- // imperative. flush:'post' so the node is committed before the command reads its Fabric handle.
85
- watch(() => ({
86
- fabricValue: resolveModelValue(rawAttrs, isBoolean) === true,
87
- switchState: state.value,
88
- }), ({ fabricValue, switchState }) => {
89
- const node = nodeRef.value;
90
- if (node === null)
91
- return;
92
- if (!shouldSnapBack(switchState, fabricValue)) {
93
- dlog(`Switch snap-back no-op reported=${String(switchState.lastNativeReport)} value=${fabricValue}`);
94
- return;
95
- }
96
- dlog(`Switch ${platform.snapBackCommand} snap-back reported=${String(switchState.lastNativeReport)} value=${fabricValue}`);
97
- dispatchViewCommand(node, platform.snapBackCommand, [fabricValue]);
98
- }, { flush: 'post' });
99
- return () => {
100
- const attrs = normalizeVueAttrs(rawAttrs);
101
- return descriptorToVue(renderSwitch({
102
- value: resolveModelValue(attrs, isBoolean) === true,
103
- disabled: typeof attrs.disabled === 'boolean'
104
- ? attrs.disabled
105
- : undefined,
106
- trackColor: normalizeTrackColor(attrs.trackColor),
107
- thumbColor: asString(attrs.thumbColor),
108
- ios_backgroundColor: asString(attrs.ios_backgroundColor),
109
- style: isViewStyleObject(attrs.style) ? attrs.style : undefined,
110
- passthrough: {
111
- ...forwardAttrs(attrs),
112
- ref: setNodeRef,
113
- onChange: handleChange,
114
- },
115
- }, platform));
116
- };
117
- }, {
118
- name: 'Switch',
119
- inheritAttrs: false,
120
- emits: {
121
- valueChange: (_value, _event) => true,
122
- 'update:modelValue': (_value) => true,
123
- 'update:value': (_value) => true,
124
- },
125
- });
126
- }
@@ -1,24 +0,0 @@
1
- import { type ITextInputProps as ITextInputBaseProps, type ITextInputHandle } from '@symbiote-native/components';
2
- import { type IClassNameValue, type ISymbioteEvent } from '@symbiote-native/engine';
3
- export type ITextInputProps = Omit<ITextInputBaseProps, 'onValueChange' | 'onFocus' | 'onBlur'> & {
4
- modelValue?: string;
5
- class?: IClassNameValue;
6
- };
7
- export type { ITextInputHandle };
8
- type ITextInputEmits = {
9
- valueChange: (text: string, event: ISymbioteEvent) => boolean;
10
- focus: (event: ISymbioteEvent) => boolean;
11
- blur: (event: ISymbioteEvent) => boolean;
12
- 'update:modelValue': (text: string) => boolean;
13
- 'update:value': (text: string) => boolean;
14
- };
15
- export declare const TextInput: import("vue").DefineSetupFnComponent<ITextInputProps, ITextInputEmits, {}, Omit<ITextInputBaseProps, "onFocus" | "onBlur" | "onValueChange"> & {
16
- modelValue?: string;
17
- class?: IClassNameValue;
18
- } & {
19
- "onUpdate:modelValue"?: ((text: string) => any) | undefined;
20
- "onUpdate:value"?: ((text: string) => any) | undefined;
21
- onValueChange?: ((text: string, event: ISymbioteEvent) => any) | undefined;
22
- onFocus?: ((event: ISymbioteEvent) => any) | undefined;
23
- onBlur?: ((event: ISymbioteEvent) => any) | undefined;
24
- }, import("vue").PublicProps>;
@@ -1,242 +0,0 @@
1
- // TextInput, the Vue lifecycle half. The folds/maps (value->text, W3C/alias resolution) and the
2
- // controlled-write predicate live in @symbiote-native/components/state, the render in
3
- // @symbiote-native/components/view, both shared verbatim with React. Vue supplies only the
4
- // reactivity: a shallowRef holds the host node, a ref holds the acknowledged event count, setup-
5
- // scope `let`s hold the last native text + focus flag, a post-flush watch runs the
6
- // controlled-write command, and expose() wires the imperative handle.
7
- //
8
- // Inputs arrive as attrs (untyped), so each is narrowed with a runtime guard, never a cast.
9
- // onValueChange MUST be stripped from the forwarded attrs: it is not a ViewConfig event, so
10
- // leaking it would reach Fabric as a function prop and crash Android's folly::dynamic.
11
- import { defineComponent, onBeforeUnmount, ref, shallowRef, watch, } from '@vue/runtime-core';
12
- import { resolveAccessibilityProps, resolveTextInputProps, renderTextInput, foldText, textFromChange, eventCountFromChange, shouldCommandText, INITIAL_EVENT_COUNT, SELECTION_NONE, } from '@symbiote-native/components';
13
- import { dispatchViewCommand, isSymbioteNode, dlog, blurTextInput, setInputFocused, setInputBlurred, whenCommitted, } from '@symbiote-native/engine';
14
- import { descriptorToVue } from '../../descriptor-to-vue.js';
15
- import { normalizeVueAttrs } from '../../utils/normalize-attrs.js';
16
- import { resolveModelValue, emitModelUpdate } from '../../utils/model-binding.js';
17
- function isRecord(value) {
18
- return typeof value === 'object' && value !== null && !Array.isArray(value);
19
- }
20
- function asString(value) {
21
- return typeof value === 'string' ? value : undefined;
22
- }
23
- function isString(value) {
24
- return typeof value === 'string';
25
- }
26
- function asBoolean(value) {
27
- return typeof value === 'boolean' ? value : undefined;
28
- }
29
- function normalizeSelection(value) {
30
- if (!isRecord(value))
31
- return undefined;
32
- if (typeof value.start !== 'number')
33
- return undefined;
34
- const selection = { start: value.start };
35
- if (typeof value.end === 'number')
36
- selection.end = value.end;
37
- return selection;
38
- }
39
- // Everything else forwards onto the host node. onFocus/onBlur are re-supplied as our wrapped
40
- // handlers; onValueChange is pure JS and must never reach Fabric.
41
- const HANDLED_ATTRS = [
42
- 'value',
43
- 'modelValue',
44
- 'defaultValue',
45
- 'multiline',
46
- 'selection',
47
- 'inputMode',
48
- 'enterKeyHint',
49
- 'readOnly',
50
- 'submitBehavior',
51
- 'blurOnSubmit',
52
- 'cursorColor',
53
- 'selectionColor',
54
- 'selectionHandleColor',
55
- 'keyboardType',
56
- 'returnKeyType',
57
- 'editable',
58
- 'autoComplete',
59
- 'textContentType',
60
- 'autoFocus',
61
- 'showSoftInputOnFocus',
62
- 'underlineColorAndroid',
63
- 'onValueChange',
64
- 'onFocus',
65
- 'onBlur',
66
- ];
67
- function forwardAttrs(attrs) {
68
- const result = {};
69
- for (const key of Object.keys(attrs)) {
70
- if (!HANDLED_ATTRS.includes(key))
71
- result[key] = attrs[key];
72
- }
73
- return result;
74
- }
75
- export const TextInput = defineComponent((_props, { attrs: rawAttrs, emit, expose }) => {
76
- // shallowRef, NOT ref: a plain ref() would hand back a reactive Proxy the engine's WeakMap
77
- // mirror doesn't recognize, so every imperative command would silently no-op. Same rule as
78
- // the Switch / ScrollView host node.
79
- const nodeRef = shallowRef(null);
80
- const setNodeRef = (el) => {
81
- nodeRef.value = isSymbioteNode(el) ? el : null;
82
- };
83
- // The count native last acknowledged. A ref so render echoes it as mostRecentEventCount; the
84
- // controlled write commands it so native's eventLag lands on 0.
85
- const mostRecentEventCount = ref(INITIAL_EVENT_COUNT);
86
- // Seeded from the mount-time value (the `text` prop already carries it down via createNode,
87
- // so the FIRST controlled value is not a divergence and must NOT re-command).
88
- let lastNativeText = foldText(resolveModelValue(rawAttrs, isString), asString(rawAttrs.defaultValue));
89
- // Mirrored from focus/blur events for isFocused(): native exposes no synchronous focus getter.
90
- let focused = false;
91
- // Guard so a later node identity change does not re-focus.
92
- let autoFocused = false;
93
- const handleChange = (event) => {
94
- // iOS and Android Fabric can key the change payload differently, so log the actual shape.
95
- dlog(`TextInput change keys=[${Object.keys(event.nativeEvent).join(',')}] ` +
96
- `text=${JSON.stringify(event.nativeEvent.text)} count=${JSON.stringify(event.nativeEvent.eventCount)}`);
97
- const text = textFromChange(event);
98
- if (text !== undefined) {
99
- // Record the text first, so the count never runs ahead of the text it stands for.
100
- lastNativeText = text;
101
- emit('valueChange', text, event);
102
- emitModelUpdate(emit, text);
103
- }
104
- const count = eventCountFromChange(event);
105
- if (count !== undefined)
106
- mostRecentEventCount.value = count;
107
- };
108
- const handleFocus = (event) => {
109
- focused = true;
110
- // Track focus app-wide so Keyboard.dismiss can blur this input without a ref.
111
- const node = nodeRef.value;
112
- if (node !== null)
113
- setInputFocused(node);
114
- emit('focus', event);
115
- };
116
- const handleBlur = (event) => {
117
- focused = false;
118
- const node = nodeRef.value;
119
- if (node !== null)
120
- setInputBlurred(node);
121
- emit('blur', event);
122
- };
123
- // Controlled write: when JS-side `value` diverges from what native reported, command the new
124
- // text down with the acknowledged count - a plain prop re-push would race the user's
125
- // keystrokes. flush:'post' so the node is committed before the command reads its Fabric handle.
126
- watch(() => resolveModelValue(rawAttrs, isString), value => {
127
- const node = nodeRef.value;
128
- if (node === null)
129
- return;
130
- if (!shouldCommandText(lastNativeText, value))
131
- return;
132
- const selection = normalizeSelection(rawAttrs.selection);
133
- const selStart = selection?.start ?? SELECTION_NONE;
134
- const selEnd = selection?.end ?? selection?.start ?? SELECTION_NONE;
135
- dlog(`TextInput setTextAndSelection count=${mostRecentEventCount.value} text=${JSON.stringify(value)}`);
136
- dispatchViewCommand(node, 'setTextAndSelection', [
137
- mostRecentEventCount.value,
138
- value,
139
- selStart,
140
- selEnd,
141
- ]);
142
- lastNativeText = value;
143
- }, { flush: 'post' });
144
- // autoFocus is driven in JS: once the node first commits, command `focus` down once. Under
145
- // Vue's async-batched commit the node has no Fabric tag yet at post-flush, so
146
- // whenCommitted defers it to the commit that assigns the tag. Cancelled on unmount so an
147
- // un-committed pending focus can't leak.
148
- let cancelAutoFocus;
149
- watch(nodeRef, node => {
150
- if (autoFocused || node === null || rawAttrs.autoFocus !== true)
151
- return;
152
- autoFocused = true;
153
- dlog('TextInput autoFocus -> focus command');
154
- cancelAutoFocus = whenCommitted(node, () => dispatchViewCommand(node, 'focus', []));
155
- }, { flush: 'post' });
156
- onBeforeUnmount(() => cancelAutoFocus?.());
157
- // Methods read nodeRef.value / the count LIVE, so no stale capture. clear/setSelection reuse
158
- // setTextAndSelection, the same path as a controlled write.
159
- expose({
160
- focus: () => {
161
- const node = nodeRef.value;
162
- if (node !== null)
163
- dispatchViewCommand(node, 'focus', []);
164
- },
165
- blur: () => {
166
- // Routes through TextInputState so the app-wide focus tracking clears too.
167
- blurTextInput(nodeRef.value);
168
- },
169
- clear: () => {
170
- const node = nodeRef.value;
171
- if (node === null)
172
- return;
173
- dispatchViewCommand(node, 'setTextAndSelection', [
174
- mostRecentEventCount.value,
175
- '',
176
- 0,
177
- 0,
178
- ]);
179
- lastNativeText = '';
180
- },
181
- isFocused: () => focused,
182
- setSelection: (start, end) => {
183
- const node = nodeRef.value;
184
- if (node === null)
185
- return;
186
- const current = lastNativeText ?? '';
187
- dispatchViewCommand(node, 'setTextAndSelection', [
188
- mostRecentEventCount.value,
189
- current,
190
- start,
191
- end,
192
- ]);
193
- },
194
- });
195
- return () => {
196
- const attrs = normalizeVueAttrs(rawAttrs);
197
- const multiline = attrs.multiline === true;
198
- const folded = resolveTextInputProps({
199
- inputMode: asString(attrs.inputMode),
200
- keyboardType: asString(attrs.keyboardType),
201
- enterKeyHint: asString(attrs.enterKeyHint),
202
- returnKeyType: asString(attrs.returnKeyType),
203
- readOnly: asBoolean(attrs.readOnly),
204
- editable: asBoolean(attrs.editable),
205
- submitBehavior: asString(attrs.submitBehavior),
206
- blurOnSubmit: asBoolean(attrs.blurOnSubmit),
207
- multiline,
208
- cursorColor: asString(attrs.cursorColor),
209
- selectionColor: asString(attrs.selectionColor),
210
- selectionHandleColor: asString(attrs.selectionHandleColor),
211
- autoComplete: asString(attrs.autoComplete),
212
- textContentType: asString(attrs.textContentType),
213
- showSoftInputOnFocus: asBoolean(attrs.showSoftInputOnFocus),
214
- underlineColorAndroid: asString(attrs.underlineColorAndroid),
215
- });
216
- const text = foldText(resolveModelValue(attrs, isString), asString(attrs.defaultValue));
217
- return descriptorToVue(renderTextInput({
218
- multiline,
219
- text,
220
- mostRecentEventCount: mostRecentEventCount.value,
221
- selection: normalizeSelection(attrs.selection),
222
- folded,
223
- passthrough: {
224
- ...resolveAccessibilityProps(forwardAttrs(attrs)),
225
- ref: setNodeRef,
226
- onChange: handleChange,
227
- onFocus: handleFocus,
228
- onBlur: handleBlur,
229
- },
230
- }));
231
- };
232
- }, {
233
- name: 'TextInput',
234
- inheritAttrs: false,
235
- emits: {
236
- valueChange: (_text, _event) => true,
237
- focus: (_event) => true,
238
- blur: (_event) => true,
239
- 'update:modelValue': (_text) => true,
240
- 'update:value': (_text) => true,
241
- },
242
- });
@@ -1,24 +0,0 @@
1
- import { canUseNativeForeground, rippleBackground, selectableBackground, selectableBackgroundBorderless, type INativeFeedbackBackground } from '@symbiote-native/components';
2
- import { type IPressableEmits, type IPressableProps } from './pressable';
3
- export type { INativeFeedbackBackground, IThemeAttrBackground, IRippleBackground, } from '@symbiote-native/components';
4
- export type ITouchableNativeFeedbackProps = Omit<IPressableProps, 'style'> & {
5
- background?: INativeFeedbackBackground;
6
- useForeground?: boolean;
7
- };
8
- export declare const TouchableNativeFeedback: import("vue").DefineSetupFnComponent<ITouchableNativeFeedbackProps, IPressableEmits, {}, Omit<IPressableProps, "style"> & {
9
- background?: INativeFeedbackBackground;
10
- useForeground?: boolean;
11
- } & {
12
- onPress?: ((event: import("@symbiote-native/engine").ISymbioteEvent) => any) | undefined;
13
- onPressIn?: ((event: import("@symbiote-native/engine").ISymbioteEvent) => any) | undefined;
14
- onPressOut?: ((event: import("@symbiote-native/engine").ISymbioteEvent) => any) | undefined;
15
- onPressMove?: ((event: import("@symbiote-native/engine").ISymbioteEvent) => any) | undefined;
16
- onLongPress?: ((event: import("@symbiote-native/engine").ISymbioteEvent) => any) | undefined;
17
- onHoverIn?: ((event: import("@symbiote-native/engine").ISymbioteEvent) => any) | undefined;
18
- onHoverOut?: ((event: import("@symbiote-native/engine").ISymbioteEvent) => any) | undefined;
19
- }, import("vue").PublicProps> & {
20
- SelectableBackground: typeof selectableBackground;
21
- SelectableBackgroundBorderless: typeof selectableBackgroundBorderless;
22
- Ripple: typeof rippleBackground;
23
- canUseNativeForeground: typeof canUseNativeForeground;
24
- };
@@ -1,77 +0,0 @@
1
- // TouchableNativeFeedback for Vue: Android's ripple/state-drawable touchable, built on Pressable
2
- // like the rest of the family (the Vue twin of the React adapter). The native ripple props
3
- // (nativeBackgroundAndroid / nativeForegroundAndroid) ride a dedicated feedback View nested under
4
- // the Pressable; on iOS they are inert. The static factories + background mapping are shared in
5
- // @symbiote-native/components/view; Vue only attaches them onto the component value and nests the View.
6
- import { defineComponent, h } from '@vue/runtime-core';
7
- import { backgroundProps, canUseNativeForeground, rippleBackground, selectableBackground, selectableBackgroundBorderless, } from '@symbiote-native/components';
8
- import { dlog } from '@symbiote-native/engine';
9
- import { View } from '../components.js';
10
- import { Pressable, emitPressableEvents, PRESSABLE_EMITS, } from './pressable.js';
11
- import { normalizeVueAttrs } from '../utils/normalize-attrs.js';
12
- const HANDLED = ['background', 'useForeground'];
13
- function forwardAttrs(attrs) {
14
- const result = {};
15
- for (const key of Object.keys(attrs)) {
16
- if (!HANDLED.includes(key))
17
- result[key] = attrs[key];
18
- }
19
- return result;
20
- }
21
- function isRecord(value) {
22
- return typeof value === 'object' && value !== null && !Array.isArray(value);
23
- }
24
- // `background` arrives untyped; narrow it to the discriminated union the mapping reads, else
25
- // undefined (the impl then defaults to SelectableBackground, like RN).
26
- function asBackground(value) {
27
- if (!isRecord(value))
28
- return undefined;
29
- if (value.type === 'ThemeAttrAndroid') {
30
- if (value.attribute === 'selectableItemBackground' ||
31
- value.attribute === 'selectableItemBackgroundBorderless') {
32
- return {
33
- type: 'ThemeAttrAndroid',
34
- attribute: value.attribute,
35
- rippleRadius: typeof value.rippleRadius === 'number'
36
- ? value.rippleRadius
37
- : undefined,
38
- };
39
- }
40
- return undefined;
41
- }
42
- if (value.type === 'RippleAndroid') {
43
- return {
44
- type: 'RippleAndroid',
45
- color: typeof value.color === 'string' ? value.color : null,
46
- borderless: value.borderless === true,
47
- rippleRadius: typeof value.rippleRadius === 'number' ? value.rippleRadius : undefined,
48
- };
49
- }
50
- return undefined;
51
- }
52
- const TouchableNativeFeedbackImpl = defineComponent((_props, { slots, attrs: rawAttrs, emit }) => {
53
- return () => {
54
- const attrs = normalizeVueAttrs(rawAttrs);
55
- const useForeground = attrs.useForeground === true;
56
- // RN defaults a missing background to SelectableBackground() so the touchable always shows
57
- // feedback; mirror that here.
58
- const resolved = asBackground(attrs.background) ?? selectableBackground();
59
- dlog(`TouchableNativeFeedback render ${resolved.type} useForeground ${useForeground}`);
60
- const nativeProps = backgroundProps(resolved, useForeground);
61
- const children = slots.default !== undefined ? slots.default() : [];
62
- const feedback = h(View, nativeProps, () => children);
63
- return h(Pressable, { ...forwardAttrs(attrs), ...emitPressableEvents(emit) }, { default: () => [feedback] });
64
- };
65
- }, {
66
- name: 'TouchableNativeFeedback',
67
- inheritAttrs: false,
68
- emits: PRESSABLE_EMITS,
69
- });
70
- // The static factories live on the component value so callers reach TouchableNativeFeedback.Ripple(…)
71
- // exactly like RN. Object.assign onto the defineComponent return (a plain object) keeps the typing.
72
- export const TouchableNativeFeedback = Object.assign(TouchableNativeFeedbackImpl, {
73
- SelectableBackground: selectableBackground,
74
- SelectableBackgroundBorderless: selectableBackgroundBorderless,
75
- Ripple: rippleBackground,
76
- canUseNativeForeground,
77
- });
@@ -1,50 +0,0 @@
1
- import { type IPressTimingProps } from '@symbiote-native/components';
2
- import { type ISymbioteEvent, type IStyleProp, type IViewStyle } from '@symbiote-native/engine';
3
- import { type IPressableEmits, type IPressableProps } from './pressable';
4
- type ITouchableBaseProps = Omit<IPressableProps, 'style'> & IPressTimingProps & {
5
- style?: IStyleProp<IViewStyle>;
6
- };
7
- export interface ITouchableOpacityProps extends ITouchableBaseProps {
8
- activeOpacity?: number;
9
- }
10
- export interface ITouchableHighlightProps extends ITouchableBaseProps {
11
- activeOpacity?: number;
12
- underlayColor?: string;
13
- }
14
- export type ITouchableWithoutFeedbackProps = ITouchableBaseProps;
15
- export type ITouchableHighlightEmits = IPressableEmits & {
16
- showUnderlay: () => boolean;
17
- hideUnderlay: () => boolean;
18
- };
19
- export declare const TouchableOpacity: import("vue").DefineSetupFnComponent<ITouchableOpacityProps, IPressableEmits, {}, ITouchableOpacityProps & {
20
- onPress?: ((event: ISymbioteEvent) => any) | undefined;
21
- onPressIn?: ((event: ISymbioteEvent) => any) | undefined;
22
- onPressOut?: ((event: ISymbioteEvent) => any) | undefined;
23
- onPressMove?: ((event: ISymbioteEvent) => any) | undefined;
24
- onLongPress?: ((event: ISymbioteEvent) => any) | undefined;
25
- onHoverIn?: ((event: ISymbioteEvent) => any) | undefined;
26
- onHoverOut?: ((event: ISymbioteEvent) => any) | undefined;
27
- }, import("vue").PublicProps>;
28
- export declare const TouchableHighlight: import("vue").DefineSetupFnComponent<ITouchableHighlightProps, ITouchableHighlightEmits, {}, ITouchableHighlightProps & {
29
- onPress?: ((event: ISymbioteEvent) => any) | undefined;
30
- onPressIn?: ((event: ISymbioteEvent) => any) | undefined;
31
- onPressOut?: ((event: ISymbioteEvent) => any) | undefined;
32
- onPressMove?: ((event: ISymbioteEvent) => any) | undefined;
33
- onLongPress?: ((event: ISymbioteEvent) => any) | undefined;
34
- onHoverIn?: ((event: ISymbioteEvent) => any) | undefined;
35
- onHoverOut?: ((event: ISymbioteEvent) => any) | undefined;
36
- onShowUnderlay?: (() => any) | undefined;
37
- onHideUnderlay?: (() => any) | undefined;
38
- }, import("vue").PublicProps>;
39
- export declare const TouchableWithoutFeedback: import("vue").DefineSetupFnComponent<ITouchableBaseProps, IPressableEmits, {}, Omit<IPressableProps, "style"> & IPressTimingProps & {
40
- style?: IStyleProp<IViewStyle>;
41
- } & {
42
- onPress?: ((event: ISymbioteEvent) => any) | undefined;
43
- onPressIn?: ((event: ISymbioteEvent) => any) | undefined;
44
- onPressOut?: ((event: ISymbioteEvent) => any) | undefined;
45
- onPressMove?: ((event: ISymbioteEvent) => any) | undefined;
46
- onLongPress?: ((event: ISymbioteEvent) => any) | undefined;
47
- onHoverIn?: ((event: ISymbioteEvent) => any) | undefined;
48
- onHoverOut?: ((event: ISymbioteEvent) => any) | undefined;
49
- }, import("vue").PublicProps>;
50
- export {};