@ng-native/components 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/pressable.d.ts +3 -3
- package/dist/pressable.js +6 -4
- package/dist/pressable.js.map +1 -1
- package/dist/safe-area-provider.js +3 -2
- package/dist/safe-area-provider.js.map +1 -1
- package/dist/switch.js +2 -1
- package/dist/switch.js.map +1 -1
- package/dist/text.d.ts +6 -0
- package/dist/text.js +11 -0
- package/dist/text.js.map +1 -1
- package/dist/view-base.d.ts +6 -0
- package/dist/view-base.js +15 -0
- package/dist/view-base.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -73,7 +73,7 @@ package under Node (tests, tooling).
|
|
|
73
73
|
[modal](https://ng-native.com/packages/components/modal) and
|
|
74
74
|
[animation](https://ng-native.com/packages/components/animation)
|
|
75
75
|
- [Root README](https://github.com/ng-native/ng-native/blob/main/README.md) and
|
|
76
|
-
[ARCHITECTURE.md](https://github.com/ng-native/ng-native/blob/main/ARCHITECTURE.md)
|
|
76
|
+
[ARCHITECTURE.md](https://github.com/ng-native/ng-native/blob/main/docs/ARCHITECTURE.md)
|
|
77
77
|
|
|
78
78
|
## License
|
|
79
79
|
|
package/dist/pressable.d.ts
CHANGED
|
@@ -175,9 +175,9 @@ export declare abstract class TouchableBase extends ViewBase {
|
|
|
175
175
|
/**
|
|
176
176
|
* A touchable that is a control: `Pressable`, `TouchableOpacity` and `PressBehavior`.
|
|
177
177
|
*
|
|
178
|
-
* The
|
|
179
|
-
*
|
|
180
|
-
*
|
|
178
|
+
* The host bindings every control needs live here rather than on `TouchableBase`, which `Text`
|
|
179
|
+
* extends: the state that follows `disabled`, and the Android ripple. Controls are few enough on
|
|
180
|
+
* a screen to pay for a binding on every pass; texts are not.
|
|
181
181
|
*/
|
|
182
182
|
export declare abstract class ControlBase extends TouchableBase {
|
|
183
183
|
static ɵfac: i0.ɵɵFactoryDeclaration<ControlBase, never>;
|
package/dist/pressable.js
CHANGED
|
@@ -401,13 +401,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImpor
|
|
|
401
401
|
/**
|
|
402
402
|
* A touchable that is a control: `Pressable`, `TouchableOpacity` and `PressBehavior`.
|
|
403
403
|
*
|
|
404
|
-
* The
|
|
405
|
-
*
|
|
406
|
-
*
|
|
404
|
+
* The host bindings every control needs live here rather than on `TouchableBase`, which `Text`
|
|
405
|
+
* extends: the state that follows `disabled`, and the Android ripple. Controls are few enough on
|
|
406
|
+
* a screen to pay for a binding on every pass; texts are not.
|
|
407
407
|
*/
|
|
408
408
|
export class ControlBase extends TouchableBase {
|
|
409
409
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: ControlBase, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
410
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.2.0", type: ControlBase, isStandalone: true, host: { properties: { "accessibilityState": "accessibilityStateProp()", "nativeBackgroundAndroid": "rippleBackground()", "nativeForegroundAndroid": "rippleForeground()" } }, usesInheritance: true, ngImport: i0 });
|
|
410
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.2.0", type: ControlBase, isStandalone: true, host: { properties: { "accessibilityState": "accessibilityStateProp()", "attr.data-disabled": "disabled() ? '' : null", "nativeBackgroundAndroid": "rippleBackground()", "nativeForegroundAndroid": "rippleForeground()" } }, usesInheritance: true, ngImport: i0 });
|
|
411
411
|
}
|
|
412
412
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: ControlBase, decorators: [{
|
|
413
413
|
type: Directive,
|
|
@@ -416,6 +416,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImpor
|
|
|
416
416
|
// `disabled` is an input of ours, so it cannot reach `ngOnChanges` on the base; this is
|
|
417
417
|
// the one binding that keeps the announced state in step with it.
|
|
418
418
|
'[accessibilityState]': 'accessibilityStateProp()',
|
|
419
|
+
// Nor is it left on the node for `:disabled` to read, so this is what a stylesheet matches.
|
|
420
|
+
'[attr.data-disabled]': "disabled() ? '' : null",
|
|
419
421
|
'[nativeBackgroundAndroid]': 'rippleBackground()',
|
|
420
422
|
'[nativeForegroundAndroid]': 'rippleForeground()',
|
|
421
423
|
},
|
package/dist/pressable.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pressable.js","sourceRoot":"","sources":["../src/pressable.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Press handling, built on the engine's responder system as RN's `Pressability` is.\n *\n * `onPress` is not a native event: RN synthesises it in JS from the touch primitives, with a\n * press rectangle, delays and a long-press timer around them. This is that machine, on the same\n * responder negotiation, so a button and an enclosing scroll view agree on who owns a drag.\n */\nimport {\n Directive,\n booleanAttribute,\n forwardRef,\n input,\n numberAttribute,\n output,\n signal,\n} from '@angular/core';\nimport type { NativeSyntheticEvent } from '@ng-native/fabric';\nimport type { Insets, TouchEvent } from './events.ts';\nimport { ViewBase } from './view-base.ts';\n\n/** What a press handler receives: RN's `{nativeEvent}` shape, passed straight through. */\nexport type PressEvent = TouchEvent;\n\n/**\n * Android's ripple, drawn natively. `foreground` paints it over the content rather than behind.\n */\nexport interface AndroidRipple {\n readonly color?: string | number;\n readonly borderless?: boolean;\n readonly radius?: number;\n readonly foreground?: boolean;\n}\n\n/**\n * How far outside its own bounds a control keeps a press: RN's `DEFAULT_PRESS_RECT_OFFSETS`.\n * More room below, because a thumb rolls downwards as it lifts.\n */\nconst DEFAULT_PRESS_RETENTION: Required<Insets> = { top: 20, left: 20, right: 20, bottom: 30 };\n/** RN's `DEFAULT_LONG_PRESS_DELAY_MS`. */\nconst DEFAULT_LONG_PRESS_DELAY = 500;\n/** RN's `DEFAULT_MIN_PRESS_DURATION`: the pressed look stays at least this long on a quick tap. */\nconst DEFAULT_MIN_PRESS_DURATION = 130;\n\n/**\n * Used only until a control has been measured. RN measures the view and cancels when the touch\n * leaves its bounds plus the retention offset; before the first layout arrives there are no\n * bounds to compare against, so fall back to a small movement threshold rather than treating a\n * drag of any length as a tap.\n */\nconst PRESS_CANCEL_DISTANCE = 15;\n\nconst insets = (value: Insets | number | undefined, fallback: Required<Insets>) => {\n if (value === undefined) return fallback;\n if (typeof value === 'number') return { top: value, left: value, right: value, bottom: value };\n return {\n top: value.top ?? 0,\n left: value.left ?? 0,\n right: value.right ?? 0,\n bottom: value.bottom ?? 0,\n };\n};\n\n/** Page-space touch point, tolerating the several shapes a Fabric touch payload can take. */\nfunction touchPoint(event: NativeSyntheticEvent): { x: number; y: number } {\n const native = (event.nativeEvent ?? {}) as {\n pageX?: number;\n pageY?: number;\n touches?: { pageX?: number; pageY?: number }[];\n };\n const touch = native.touches?.[0];\n return {\n x: native.pageX ?? touch?.pageX ?? 0,\n y: native.pageY ?? touch?.pageY ?? 0,\n };\n}\n\n/** What `rippleDrawable` builds: Android's `RippleAndroid` drawable description. */\ninterface RippleDrawable {\n readonly type: 'RippleAndroid';\n readonly color: unknown;\n readonly borderless: boolean;\n readonly rippleRadius: number | undefined;\n}\n\nconst now = (): number => globalThis.performance?.now?.() ?? Date.now();\n\n/**\n * The press machine, and the base of every primitive that takes a touch.\n *\n * It declares no host bindings of its own, because `Text` extends it and a host binding runs on\n * every element that carries it, on every pass. The controls bind theirs through `ControlBase`.\n */\n@Directive()\nexport abstract class TouchableBase extends ViewBase {\n /** Ignore touches entirely. */\n readonly disabled = input(false, { transform: booleanAttribute });\n\n /**\n * How far outside the hit area a touch may wander before the press is cancelled. Native's\n * `hitSlop` grows the area a touch can start in; this grows the area it may move within.\n */\n readonly pressRetentionOffset = input<Insets | number>();\n /** Milliseconds a touch must be held before `(longPress)` fires. */\n readonly delayLongPress = input(DEFAULT_LONG_PRESS_DELAY, { transform: numberAttribute });\n /** Milliseconds between the touch landing and `(pressIn)`, so a scroll can start first. */\n readonly delayPressIn = input(0, { transform: numberAttribute });\n /** Milliseconds between the touch lifting and `(pressOut)`. */\n readonly delayPressOut = input(0, { transform: numberAttribute });\n /** The pressed state lasts at least this long, so a quick tap still shows it. */\n readonly minPressDuration = input(DEFAULT_MIN_PRESS_DURATION, { transform: numberAttribute });\n /** Whether a scrolling ancestor may take the gesture away mid-press. */\n readonly cancelable = input(true, { transform: booleanAttribute });\n /** Android: a native ripple on press. */\n readonly androidRipple = input<AndroidRipple>(undefined, { alias: 'android_ripple' });\n\n /** The touch lifted inside the press area. Not fired after a `(longPress)` that has a listener. */\n readonly press = output<PressEvent>();\n readonly pressIn = output<PressEvent>();\n readonly pressOut = output<PressEvent>();\n /**\n * The touch has been held for `delayLongPress`. With no listener there is no long press, as in\n * React Native, so a slow tap is still a `press`.\n */\n readonly longPress = output<PressEvent>();\n\n /** Whether a press is in progress, for the pressed look. */\n readonly pressed = signal(false);\n\n /**\n * Whether a pointer is over the control, which on this platform means an iPad with a trackpad\n * or a mouse. Always false on a phone, because a phone never sends a pointer event.\n *\n * Opted into by exactly the elements that opt into being measured, which is the same question\n * asked twice: is this a control, or is it a piece of text that merely inherits the machinery.\n * Registering on everything was the first attempt and put two props on every paragraph on\n * screen, which is the most numerous node in an app paying for a state a label cannot use.\n */\n readonly hovered = signal(false);\n\n /*\n * Methods rather than `computed()`s, because nearly every instance has no ripple and a computed\n * is an allocation per element whether or not it ever holds anything. The drawable is kept for as\n * long as the ripple it came from, which is the memo the computed was there to provide: a fresh\n * object on every pass would re-send the prop on every pass.\n */\n protected rippleBackground(): RippleDrawable | undefined {\n const ripple = this.androidRipple();\n return ripple && !ripple.foreground ? this.drawable(ripple) : undefined;\n }\n\n protected rippleForeground(): RippleDrawable | undefined {\n const ripple = this.androidRipple();\n return ripple?.foreground ? this.drawable(ripple) : undefined;\n }\n\n private drawn: { ripple: AndroidRipple; drawable: RippleDrawable } | null = null;\n\n private drawable(ripple: AndroidRipple): RippleDrawable {\n if (this.drawn?.ripple !== ripple)\n this.drawn = { ripple, drawable: this.rippleDrawable(ripple) };\n return this.drawn.drawable;\n }\n\n /**\n * The drawable description Android's `ReactDrawableHelper` reads.\n *\n * `color` goes through the engine the way every other colour prop does, and has to: the helper\n * switches on the value's runtime type and takes a number or a platform-colour map, and anything\n * else - a `'#ff0000'` written at the call site, say - falls through to `null` and the ripple\n * draws in the theme's own `colorControlHighlight` instead. Nothing is logged and nothing throws,\n * so the ripple appears and is simply the wrong colour. RN's own `TouchableNativeFeedback.Ripple`\n * calls `processColor` here for the same reason.\n */\n private rippleDrawable(ripple: AndroidRipple): RippleDrawable {\n return {\n type: 'RippleAndroid' as const,\n color: this.engine.color(ripple.color),\n borderless: ripple.borderless ?? false,\n rippleRadius: ripple.radius,\n };\n }\n\n /** Where the touch started, so a drag can be told apart from a tap. */\n private origin: { x: number; y: number } | null = null;\n /** The control's own size, from its last layout. Null until it has been measured once. */\n private size: { width: number; height: number } | null = null;\n private cancelled = false;\n private longPressed = false;\n /** How many `(longPress)` listeners there are; the long-press clock only runs with one. */\n private longPressListeners = 0;\n private pressedAt = 0;\n private pressInTimer: ReturnType<typeof setTimeout> | null = null;\n private longPressTimer: ReturnType<typeof setTimeout> | null = null;\n private pressOutTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor() {\n super();\n // output() has to be a member's own initializer for the compiler to see it, so its listeners\n // are counted here, through its public subscribe.\n const subscribe = this.longPress.subscribe.bind(this.longPress);\n this.longPress.subscribe = (callback) => {\n this.longPressListeners++;\n const subscription = subscribe(callback);\n let open = true;\n return {\n unsubscribe: () => {\n if (open) this.longPressListeners--;\n open = false;\n subscription.unsubscribe();\n },\n };\n };\n }\n\n /** Called as a press starts and ends, for a subclass that shows it natively. `Text` does. */\n protected pressedChanged(_pressed: boolean): void {}\n\n /** Whether a touch starting on this node should be claimed. `Text` narrows it. */\n protected claims(): boolean {\n return !this.disabled();\n }\n\n /**\n * Whether the control's size should be tracked. Native only measures a view that asks, so\n * this must not be true for every `<text>`: a pressable text opts in, a label never does.\n */\n protected measures(): boolean {\n return true;\n }\n\n /**\n * Whether a touch this far from where it started is still on the control.\n *\n * Distance from the origin is the wrong question on anything large: a thumb tap on a full-width\n * button easily travels twenty points without ever leaving it, and cancelling there reads as\n * \"the button doesn't work\", intermittently and only for some people. What matters is whether\n * the finger is still within the control plus its hit slop, plus the slop RN allows.\n *\n * The touch began somewhere inside the control but we do not know where, so the bound is the\n * full extent rather than half of it. That errs towards keeping the press, which is the right\n * way to be wrong: a press that survives a drag the user meant as a scroll is a smaller sin\n * than a tap that does nothing.\n */\n private stillOnControl(dx: number, dy: number): boolean {\n if (!this.size) return Math.hypot(dx, dy) <= PRESS_CANCEL_DISTANCE;\n const slop = insets(this.hitSlop(), { top: 0, left: 0, right: 0, bottom: 0 });\n const keep = insets(this.pressRetentionOffset(), DEFAULT_PRESS_RETENTION);\n const horizontal = dx < 0 ? slop.left + keep.left : slop.right + keep.right;\n const vertical = dy < 0 ? slop.top + keep.top : slop.bottom + keep.bottom;\n return (\n Math.abs(dx) <= this.size.width + horizontal && Math.abs(dy) <= this.size.height + vertical\n );\n }\n\n /**\n * A lifecycle hook rather than `inject(DestroyRef).onDestroy`: Angular registers a hook once per\n * directive type, where the callback was a closure and a lookup for every instance - and every\n * `<text>` on screen is one.\n */\n ngOnDestroy(): void {\n this.clearTimers();\n this.stopResponding?.();\n this.stopLayout?.();\n this.stopHover?.();\n }\n\n private stopResponding: (() => void) | null = null;\n private stopLayout: (() => void) | null = null;\n private stopHover: (() => void) | null = null;\n\n override ngOnInit(): void {\n super.ngOnInit();\n this.respondIfNeeded();\n this.measureIfNeeded();\n this.hoverIfNeeded();\n }\n\n override ngOnChanges(): void {\n super.ngOnChanges();\n this.respondIfNeeded();\n this.measureIfNeeded();\n this.hoverIfNeeded();\n }\n\n /**\n * Join the responder negotiation, once this is something a touch can press.\n *\n * Behind `measures()` for the same reason as layout and hover: a `<text>` is the commonest node\n * on screen and almost never a control, and registering every one cost a handler object, six\n * closures and a responder entry apiece for a touch it would have refused anyway.\n */\n private respondIfNeeded(): void {\n if (this.stopResponding || !this.measures()) return;\n this.stopResponding = this.engine.setResponder(this.node, {\n // Claim the gesture on touch down unless disabled. Because this goes through the\n // negotiation, an ancestor can pre-empt us in the capture pass and a nested pressable\n // wins over us in the bubble pass, neither of which raw touch listeners could express.\n onStartShouldSetResponder: () => this.claims(),\n onResponderGrant: (event) => this.onGrant(event),\n onResponderMove: (event) => this.onMove(event),\n onResponderRelease: (event) => this.onRelease(event),\n onResponderTerminate: (event) => this.onTerminate(event),\n // Yield to an enclosing scroll view when it takes over the drag, unless told not to.\n onResponderTerminationRequest: () => this.cancelable(),\n });\n }\n\n /**\n * `onLayout` is opted into by the engine as soon as something listens for it, which is the only\n * way the native side reports a view's size at all, and the reason it is only asked for once\n * `measures()` says so - a `<text>` answers that from an input, and most of them say no.\n *\n * Called from the lifecycle rather than watched by an effect. An effect per element is an\n * allocation and a scheduler entry for every pressable and every piece of text on screen, to\n * notice a change these two hooks already see.\n */\n /**\n * Hover, on the same terms and behind the same question.\n *\n * Fabric will not dispatch a pointer event to a view whose props have not asked for one, and\n * the engine writes those props when something listens - so listening is the whole opt-in. The\n * gate is `measures()`, which is not what its name is about but is the right question underneath\n * it: is this an actual control, or a piece of text that merely inherits the machinery. A label\n * says no, and two props on every paragraph on screen is not a cost worth paying for a hover\n * state a label has no use for.\n *\n * Never true on a phone, which sends no pointer events at all. This is the one thing an iPad\n * with a trackpad has that a phone does not.\n */\n private hoverIfNeeded(): void {\n if (this.stopHover || !this.measures()) return;\n const enter = this.engine.setEventListener(this.node, 'topPointerEnter', () =>\n this.hovered.set(true),\n );\n const leave = this.engine.setEventListener(this.node, 'topPointerLeave', () =>\n this.hovered.set(false),\n );\n this.stopHover = () => {\n enter();\n leave();\n };\n }\n\n private measureIfNeeded(): void {\n if (this.stopLayout || !this.measures()) return;\n this.stopLayout = this.engine.setEventListener(this.node, 'topLayout', (event) => {\n const layout = (event as NativeSyntheticEvent<{ layout?: { width: number; height: number } }>)\n .nativeEvent?.layout;\n if (layout) this.size = { width: layout.width, height: layout.height };\n });\n }\n\n private onGrant(event: PressEvent): void {\n this.origin = touchPoint(event);\n this.cancelled = false;\n this.longPressed = false;\n this.clearTimers();\n if (this.androidRipple()) {\n const { x, y } = this.origin;\n this.engine.dispatchCommand(this.node, 'hotspotUpdate', [x, y]);\n this.engine.dispatchCommand(this.node, 'setPressed', [true]);\n }\n const delay = this.delayPressIn();\n if (delay > 0) this.pressInTimer = setTimeout(() => this.activate(event), delay);\n else this.activate(event);\n }\n\n /** `pressIn`, and the long-press clock starts from here. */\n private activate(event: PressEvent): void {\n this.pressInTimer = null;\n this.pressedAt = now();\n this.pressed.set(true);\n this.pressedChanged(true);\n this.pressIn.emit(event);\n if (!this.longPressListeners) return;\n this.longPressTimer = setTimeout(() => {\n this.longPressTimer = null;\n this.longPressed = true;\n this.longPress.emit(event);\n }, this.delayLongPress());\n }\n\n private onMove(event: PressEvent): void {\n if (this.cancelled || !this.origin) return;\n const point = touchPoint(event);\n if (this.stillOnControl(point.x - this.origin.x, point.y - this.origin.y)) return;\n // The finger has wandered: this is a drag, not a tap. Give up the press but stay the\n // responder, so a scroll view underneath still gets its gesture.\n this.cancelled = true;\n this.deactivate(event);\n }\n\n private onRelease(event: PressEvent): void {\n if (this.androidRipple()) this.engine.dispatchCommand(this.node, 'setPressed', [false]);\n if (this.cancelled) return;\n // Lifted before the press-in delay ran out: RN still reports a full press.\n if (this.pressInTimer) {\n clearTimeout(this.pressInTimer);\n this.activate(event);\n }\n const longPressed = this.longPressed;\n this.deactivate(event);\n if (!longPressed) this.press.emit(event);\n }\n\n private onTerminate(event: PressEvent): void {\n if (this.androidRipple()) this.engine.dispatchCommand(this.node, 'setPressed', [false]);\n if (this.cancelled) return;\n this.cancelled = true;\n this.deactivate(event);\n }\n\n /** `pressOut`, no sooner than `minPressDuration` after `pressIn` and after `delayPressOut`. */\n private deactivate(event: PressEvent): void {\n if (this.pressInTimer) {\n clearTimeout(this.pressInTimer);\n this.pressInTimer = null;\n return;\n }\n if (this.longPressTimer) {\n clearTimeout(this.longPressTimer);\n this.longPressTimer = null;\n }\n if (!this.pressed()) return;\n const held = now() - this.pressedAt;\n const delay = Math.max(this.delayPressOut(), this.minPressDuration() - held);\n const out = () => {\n this.pressOutTimer = null;\n this.pressed.set(false);\n this.pressedChanged(false);\n this.pressOut.emit(event);\n };\n if (delay > 0) this.pressOutTimer = setTimeout(out, delay);\n else out();\n }\n\n private clearTimers(): void {\n // Every touchable is destroyed through here, and nearly all of them were never pressed.\n if (!this.pressInTimer && !this.longPressTimer && !this.pressOutTimer) return;\n for (const timer of [this.pressInTimer, this.longPressTimer, this.pressOutTimer]) {\n if (timer) clearTimeout(timer);\n }\n this.pressInTimer = this.longPressTimer = this.pressOutTimer = null;\n }\n}\n\n/**\n * A touchable that is a control: `Pressable`, `TouchableOpacity` and `PressBehavior`.\n *\n * The three host bindings every control needs live here rather than on `TouchableBase`, which\n * `Text` extends: the state that follows `disabled`, and the Android ripple. Controls are few\n * enough on a screen to pay for a binding on every pass; texts are not.\n */\n@Directive({\n host: {\n // `disabled` is an input of ours, so it cannot reach `ngOnChanges` on the base; this is\n // the one binding that keeps the announced state in step with it.\n '[accessibilityState]': 'accessibilityStateProp()',\n '[nativeBackgroundAndroid]': 'rippleBackground()',\n '[nativeForegroundAndroid]': 'rippleForeground()',\n },\n})\nexport abstract class ControlBase extends TouchableBase {}\n\n/**\n * The press machine on its own, for a component that wants to be pressable rather than to\n * contain something that is.\n *\n * No selector: this is only ever a `hostDirectives` entry. A component listing it gets the whole\n * of `TouchableBase` on its own host node - the responder negotiation, the press rectangle, the\n * delays and the long-press timer - instead of wrapping a `<pressable>` and paying for a second\n * native view.\n *\n * It provides `TouchableBase`, so a primitive on the same node can `inject(TouchableBase)` and\n * read `pressed` without caring whether it landed on this or on a real `<pressable>`.\n */\n@Directive({\n providers: [{ provide: TouchableBase, useExisting: forwardRef(() => PressBehavior) }],\n})\nexport class PressBehavior extends ControlBase {\n protected override accessibleByDefault(): boolean {\n return true;\n }\n\n protected override focusableByDefault(): boolean {\n return true;\n }\n\n protected override disabledForAccessibility(): boolean {\n return this.disabled();\n }\n}\n\n/**\n * A view that responds to presses. RN's `Pressable`, with the same configuration: hit slop,\n * retention offset, press-in and press-out delays, long press, and an Android ripple.\n *\n * `pressed` is a public signal, so a template can style from it through a template reference:\n * `<pressable #p [style.opacity]=\"p.pressed() ? 0.5 : 1\">`.\n */\n@Directive({\n selector: 'pressable',\n exportAs: 'pressable',\n providers: [{ provide: TouchableBase, useExisting: forwardRef(() => Pressable) }],\n})\nexport class Pressable extends ControlBase {\n /** `Pressable.js`: a control is an accessibility element, and focusable, unless refused. */\n protected override accessibleByDefault(): boolean {\n return true;\n }\n\n protected override focusableByDefault(): boolean {\n return true;\n }\n\n protected override disabledForAccessibility(): boolean {\n return this.disabled();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"pressable.js","sourceRoot":"","sources":["../src/pressable.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Press handling, built on the engine's responder system as RN's `Pressability` is.\n *\n * `onPress` is not a native event: RN synthesises it in JS from the touch primitives, with a\n * press rectangle, delays and a long-press timer around them. This is that machine, on the same\n * responder negotiation, so a button and an enclosing scroll view agree on who owns a drag.\n */\nimport {\n Directive,\n booleanAttribute,\n forwardRef,\n input,\n numberAttribute,\n output,\n signal,\n} from '@angular/core';\nimport type { NativeSyntheticEvent } from '@ng-native/fabric';\nimport type { Insets, TouchEvent } from './events.ts';\nimport { ViewBase } from './view-base.ts';\n\n/** What a press handler receives: RN's `{nativeEvent}` shape, passed straight through. */\nexport type PressEvent = TouchEvent;\n\n/**\n * Android's ripple, drawn natively. `foreground` paints it over the content rather than behind.\n */\nexport interface AndroidRipple {\n readonly color?: string | number;\n readonly borderless?: boolean;\n readonly radius?: number;\n readonly foreground?: boolean;\n}\n\n/**\n * How far outside its own bounds a control keeps a press: RN's `DEFAULT_PRESS_RECT_OFFSETS`.\n * More room below, because a thumb rolls downwards as it lifts.\n */\nconst DEFAULT_PRESS_RETENTION: Required<Insets> = { top: 20, left: 20, right: 20, bottom: 30 };\n/** RN's `DEFAULT_LONG_PRESS_DELAY_MS`. */\nconst DEFAULT_LONG_PRESS_DELAY = 500;\n/** RN's `DEFAULT_MIN_PRESS_DURATION`: the pressed look stays at least this long on a quick tap. */\nconst DEFAULT_MIN_PRESS_DURATION = 130;\n\n/**\n * Used only until a control has been measured. RN measures the view and cancels when the touch\n * leaves its bounds plus the retention offset; before the first layout arrives there are no\n * bounds to compare against, so fall back to a small movement threshold rather than treating a\n * drag of any length as a tap.\n */\nconst PRESS_CANCEL_DISTANCE = 15;\n\nconst insets = (value: Insets | number | undefined, fallback: Required<Insets>) => {\n if (value === undefined) return fallback;\n if (typeof value === 'number') return { top: value, left: value, right: value, bottom: value };\n return {\n top: value.top ?? 0,\n left: value.left ?? 0,\n right: value.right ?? 0,\n bottom: value.bottom ?? 0,\n };\n};\n\n/** Page-space touch point, tolerating the several shapes a Fabric touch payload can take. */\nfunction touchPoint(event: NativeSyntheticEvent): { x: number; y: number } {\n const native = (event.nativeEvent ?? {}) as {\n pageX?: number;\n pageY?: number;\n touches?: { pageX?: number; pageY?: number }[];\n };\n const touch = native.touches?.[0];\n return {\n x: native.pageX ?? touch?.pageX ?? 0,\n y: native.pageY ?? touch?.pageY ?? 0,\n };\n}\n\n/** What `rippleDrawable` builds: Android's `RippleAndroid` drawable description. */\ninterface RippleDrawable {\n readonly type: 'RippleAndroid';\n readonly color: unknown;\n readonly borderless: boolean;\n readonly rippleRadius: number | undefined;\n}\n\nconst now = (): number => globalThis.performance?.now?.() ?? Date.now();\n\n/**\n * The press machine, and the base of every primitive that takes a touch.\n *\n * It declares no host bindings of its own, because `Text` extends it and a host binding runs on\n * every element that carries it, on every pass. The controls bind theirs through `ControlBase`.\n */\n@Directive()\nexport abstract class TouchableBase extends ViewBase {\n /** Ignore touches entirely. */\n readonly disabled = input(false, { transform: booleanAttribute });\n\n /**\n * How far outside the hit area a touch may wander before the press is cancelled. Native's\n * `hitSlop` grows the area a touch can start in; this grows the area it may move within.\n */\n readonly pressRetentionOffset = input<Insets | number>();\n /** Milliseconds a touch must be held before `(longPress)` fires. */\n readonly delayLongPress = input(DEFAULT_LONG_PRESS_DELAY, { transform: numberAttribute });\n /** Milliseconds between the touch landing and `(pressIn)`, so a scroll can start first. */\n readonly delayPressIn = input(0, { transform: numberAttribute });\n /** Milliseconds between the touch lifting and `(pressOut)`. */\n readonly delayPressOut = input(0, { transform: numberAttribute });\n /** The pressed state lasts at least this long, so a quick tap still shows it. */\n readonly minPressDuration = input(DEFAULT_MIN_PRESS_DURATION, { transform: numberAttribute });\n /** Whether a scrolling ancestor may take the gesture away mid-press. */\n readonly cancelable = input(true, { transform: booleanAttribute });\n /** Android: a native ripple on press. */\n readonly androidRipple = input<AndroidRipple>(undefined, { alias: 'android_ripple' });\n\n /** The touch lifted inside the press area. Not fired after a `(longPress)` that has a listener. */\n readonly press = output<PressEvent>();\n readonly pressIn = output<PressEvent>();\n readonly pressOut = output<PressEvent>();\n /**\n * The touch has been held for `delayLongPress`. With no listener there is no long press, as in\n * React Native, so a slow tap is still a `press`.\n */\n readonly longPress = output<PressEvent>();\n\n /** Whether a press is in progress, for the pressed look. */\n readonly pressed = signal(false);\n\n /**\n * Whether a pointer is over the control, which on this platform means an iPad with a trackpad\n * or a mouse. Always false on a phone, because a phone never sends a pointer event.\n *\n * Opted into by exactly the elements that opt into being measured, which is the same question\n * asked twice: is this a control, or is it a piece of text that merely inherits the machinery.\n * Registering on everything was the first attempt and put two props on every paragraph on\n * screen, which is the most numerous node in an app paying for a state a label cannot use.\n */\n readonly hovered = signal(false);\n\n /*\n * Methods rather than `computed()`s, because nearly every instance has no ripple and a computed\n * is an allocation per element whether or not it ever holds anything. The drawable is kept for as\n * long as the ripple it came from, which is the memo the computed was there to provide: a fresh\n * object on every pass would re-send the prop on every pass.\n */\n protected rippleBackground(): RippleDrawable | undefined {\n const ripple = this.androidRipple();\n return ripple && !ripple.foreground ? this.drawable(ripple) : undefined;\n }\n\n protected rippleForeground(): RippleDrawable | undefined {\n const ripple = this.androidRipple();\n return ripple?.foreground ? this.drawable(ripple) : undefined;\n }\n\n private drawn: { ripple: AndroidRipple; drawable: RippleDrawable } | null = null;\n\n private drawable(ripple: AndroidRipple): RippleDrawable {\n if (this.drawn?.ripple !== ripple)\n this.drawn = { ripple, drawable: this.rippleDrawable(ripple) };\n return this.drawn.drawable;\n }\n\n /**\n * The drawable description Android's `ReactDrawableHelper` reads.\n *\n * `color` goes through the engine the way every other colour prop does, and has to: the helper\n * switches on the value's runtime type and takes a number or a platform-colour map, and anything\n * else - a `'#ff0000'` written at the call site, say - falls through to `null` and the ripple\n * draws in the theme's own `colorControlHighlight` instead. Nothing is logged and nothing throws,\n * so the ripple appears and is simply the wrong colour. RN's own `TouchableNativeFeedback.Ripple`\n * calls `processColor` here for the same reason.\n */\n private rippleDrawable(ripple: AndroidRipple): RippleDrawable {\n return {\n type: 'RippleAndroid' as const,\n color: this.engine.color(ripple.color),\n borderless: ripple.borderless ?? false,\n rippleRadius: ripple.radius,\n };\n }\n\n /** Where the touch started, so a drag can be told apart from a tap. */\n private origin: { x: number; y: number } | null = null;\n /** The control's own size, from its last layout. Null until it has been measured once. */\n private size: { width: number; height: number } | null = null;\n private cancelled = false;\n private longPressed = false;\n /** How many `(longPress)` listeners there are; the long-press clock only runs with one. */\n private longPressListeners = 0;\n private pressedAt = 0;\n private pressInTimer: ReturnType<typeof setTimeout> | null = null;\n private longPressTimer: ReturnType<typeof setTimeout> | null = null;\n private pressOutTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor() {\n super();\n // output() has to be a member's own initializer for the compiler to see it, so its listeners\n // are counted here, through its public subscribe.\n const subscribe = this.longPress.subscribe.bind(this.longPress);\n this.longPress.subscribe = (callback) => {\n this.longPressListeners++;\n const subscription = subscribe(callback);\n let open = true;\n return {\n unsubscribe: () => {\n if (open) this.longPressListeners--;\n open = false;\n subscription.unsubscribe();\n },\n };\n };\n }\n\n /** Called as a press starts and ends, for a subclass that shows it natively. `Text` does. */\n protected pressedChanged(_pressed: boolean): void {}\n\n /** Whether a touch starting on this node should be claimed. `Text` narrows it. */\n protected claims(): boolean {\n return !this.disabled();\n }\n\n /**\n * Whether the control's size should be tracked. Native only measures a view that asks, so\n * this must not be true for every `<text>`: a pressable text opts in, a label never does.\n */\n protected measures(): boolean {\n return true;\n }\n\n /**\n * Whether a touch this far from where it started is still on the control.\n *\n * Distance from the origin is the wrong question on anything large: a thumb tap on a full-width\n * button easily travels twenty points without ever leaving it, and cancelling there reads as\n * \"the button doesn't work\", intermittently and only for some people. What matters is whether\n * the finger is still within the control plus its hit slop, plus the slop RN allows.\n *\n * The touch began somewhere inside the control but we do not know where, so the bound is the\n * full extent rather than half of it. That errs towards keeping the press, which is the right\n * way to be wrong: a press that survives a drag the user meant as a scroll is a smaller sin\n * than a tap that does nothing.\n */\n private stillOnControl(dx: number, dy: number): boolean {\n if (!this.size) return Math.hypot(dx, dy) <= PRESS_CANCEL_DISTANCE;\n const slop = insets(this.hitSlop(), { top: 0, left: 0, right: 0, bottom: 0 });\n const keep = insets(this.pressRetentionOffset(), DEFAULT_PRESS_RETENTION);\n const horizontal = dx < 0 ? slop.left + keep.left : slop.right + keep.right;\n const vertical = dy < 0 ? slop.top + keep.top : slop.bottom + keep.bottom;\n return (\n Math.abs(dx) <= this.size.width + horizontal && Math.abs(dy) <= this.size.height + vertical\n );\n }\n\n /**\n * A lifecycle hook rather than `inject(DestroyRef).onDestroy`: Angular registers a hook once per\n * directive type, where the callback was a closure and a lookup for every instance - and every\n * `<text>` on screen is one.\n */\n ngOnDestroy(): void {\n this.clearTimers();\n this.stopResponding?.();\n this.stopLayout?.();\n this.stopHover?.();\n }\n\n private stopResponding: (() => void) | null = null;\n private stopLayout: (() => void) | null = null;\n private stopHover: (() => void) | null = null;\n\n override ngOnInit(): void {\n super.ngOnInit();\n this.respondIfNeeded();\n this.measureIfNeeded();\n this.hoverIfNeeded();\n }\n\n override ngOnChanges(): void {\n super.ngOnChanges();\n this.respondIfNeeded();\n this.measureIfNeeded();\n this.hoverIfNeeded();\n }\n\n /**\n * Join the responder negotiation, once this is something a touch can press.\n *\n * Behind `measures()` for the same reason as layout and hover: a `<text>` is the commonest node\n * on screen and almost never a control, and registering every one cost a handler object, six\n * closures and a responder entry apiece for a touch it would have refused anyway.\n */\n private respondIfNeeded(): void {\n if (this.stopResponding || !this.measures()) return;\n this.stopResponding = this.engine.setResponder(this.node, {\n // Claim the gesture on touch down unless disabled. Because this goes through the\n // negotiation, an ancestor can pre-empt us in the capture pass and a nested pressable\n // wins over us in the bubble pass, neither of which raw touch listeners could express.\n onStartShouldSetResponder: () => this.claims(),\n onResponderGrant: (event) => this.onGrant(event),\n onResponderMove: (event) => this.onMove(event),\n onResponderRelease: (event) => this.onRelease(event),\n onResponderTerminate: (event) => this.onTerminate(event),\n // Yield to an enclosing scroll view when it takes over the drag, unless told not to.\n onResponderTerminationRequest: () => this.cancelable(),\n });\n }\n\n /**\n * `onLayout` is opted into by the engine as soon as something listens for it, which is the only\n * way the native side reports a view's size at all, and the reason it is only asked for once\n * `measures()` says so - a `<text>` answers that from an input, and most of them say no.\n *\n * Called from the lifecycle rather than watched by an effect. An effect per element is an\n * allocation and a scheduler entry for every pressable and every piece of text on screen, to\n * notice a change these two hooks already see.\n */\n /**\n * Hover, on the same terms and behind the same question.\n *\n * Fabric will not dispatch a pointer event to a view whose props have not asked for one, and\n * the engine writes those props when something listens - so listening is the whole opt-in. The\n * gate is `measures()`, which is not what its name is about but is the right question underneath\n * it: is this an actual control, or a piece of text that merely inherits the machinery. A label\n * says no, and two props on every paragraph on screen is not a cost worth paying for a hover\n * state a label has no use for.\n *\n * Never true on a phone, which sends no pointer events at all. This is the one thing an iPad\n * with a trackpad has that a phone does not.\n */\n private hoverIfNeeded(): void {\n if (this.stopHover || !this.measures()) return;\n const enter = this.engine.setEventListener(this.node, 'topPointerEnter', () =>\n this.hovered.set(true),\n );\n const leave = this.engine.setEventListener(this.node, 'topPointerLeave', () =>\n this.hovered.set(false),\n );\n this.stopHover = () => {\n enter();\n leave();\n };\n }\n\n private measureIfNeeded(): void {\n if (this.stopLayout || !this.measures()) return;\n this.stopLayout = this.engine.setEventListener(this.node, 'topLayout', (event) => {\n const layout = (event as NativeSyntheticEvent<{ layout?: { width: number; height: number } }>)\n .nativeEvent?.layout;\n if (layout) this.size = { width: layout.width, height: layout.height };\n });\n }\n\n private onGrant(event: PressEvent): void {\n this.origin = touchPoint(event);\n this.cancelled = false;\n this.longPressed = false;\n this.clearTimers();\n if (this.androidRipple()) {\n const { x, y } = this.origin;\n this.engine.dispatchCommand(this.node, 'hotspotUpdate', [x, y]);\n this.engine.dispatchCommand(this.node, 'setPressed', [true]);\n }\n const delay = this.delayPressIn();\n if (delay > 0) this.pressInTimer = setTimeout(() => this.activate(event), delay);\n else this.activate(event);\n }\n\n /** `pressIn`, and the long-press clock starts from here. */\n private activate(event: PressEvent): void {\n this.pressInTimer = null;\n this.pressedAt = now();\n this.pressed.set(true);\n this.pressedChanged(true);\n this.pressIn.emit(event);\n if (!this.longPressListeners) return;\n this.longPressTimer = setTimeout(() => {\n this.longPressTimer = null;\n this.longPressed = true;\n this.longPress.emit(event);\n }, this.delayLongPress());\n }\n\n private onMove(event: PressEvent): void {\n if (this.cancelled || !this.origin) return;\n const point = touchPoint(event);\n if (this.stillOnControl(point.x - this.origin.x, point.y - this.origin.y)) return;\n // The finger has wandered: this is a drag, not a tap. Give up the press but stay the\n // responder, so a scroll view underneath still gets its gesture.\n this.cancelled = true;\n this.deactivate(event);\n }\n\n private onRelease(event: PressEvent): void {\n if (this.androidRipple()) this.engine.dispatchCommand(this.node, 'setPressed', [false]);\n if (this.cancelled) return;\n // Lifted before the press-in delay ran out: RN still reports a full press.\n if (this.pressInTimer) {\n clearTimeout(this.pressInTimer);\n this.activate(event);\n }\n const longPressed = this.longPressed;\n this.deactivate(event);\n if (!longPressed) this.press.emit(event);\n }\n\n private onTerminate(event: PressEvent): void {\n if (this.androidRipple()) this.engine.dispatchCommand(this.node, 'setPressed', [false]);\n if (this.cancelled) return;\n this.cancelled = true;\n this.deactivate(event);\n }\n\n /** `pressOut`, no sooner than `minPressDuration` after `pressIn` and after `delayPressOut`. */\n private deactivate(event: PressEvent): void {\n if (this.pressInTimer) {\n clearTimeout(this.pressInTimer);\n this.pressInTimer = null;\n return;\n }\n if (this.longPressTimer) {\n clearTimeout(this.longPressTimer);\n this.longPressTimer = null;\n }\n if (!this.pressed()) return;\n const held = now() - this.pressedAt;\n const delay = Math.max(this.delayPressOut(), this.minPressDuration() - held);\n const out = () => {\n this.pressOutTimer = null;\n this.pressed.set(false);\n this.pressedChanged(false);\n this.pressOut.emit(event);\n };\n if (delay > 0) this.pressOutTimer = setTimeout(out, delay);\n else out();\n }\n\n private clearTimers(): void {\n // Every touchable is destroyed through here, and nearly all of them were never pressed.\n if (!this.pressInTimer && !this.longPressTimer && !this.pressOutTimer) return;\n for (const timer of [this.pressInTimer, this.longPressTimer, this.pressOutTimer]) {\n if (timer) clearTimeout(timer);\n }\n this.pressInTimer = this.longPressTimer = this.pressOutTimer = null;\n }\n}\n\n/**\n * A touchable that is a control: `Pressable`, `TouchableOpacity` and `PressBehavior`.\n *\n * The host bindings every control needs live here rather than on `TouchableBase`, which `Text`\n * extends: the state that follows `disabled`, and the Android ripple. Controls are few enough on\n * a screen to pay for a binding on every pass; texts are not.\n */\n@Directive({\n host: {\n // `disabled` is an input of ours, so it cannot reach `ngOnChanges` on the base; this is\n // the one binding that keeps the announced state in step with it.\n '[accessibilityState]': 'accessibilityStateProp()',\n // Nor is it left on the node for `:disabled` to read, so this is what a stylesheet matches.\n '[attr.data-disabled]': \"disabled() ? '' : null\",\n '[nativeBackgroundAndroid]': 'rippleBackground()',\n '[nativeForegroundAndroid]': 'rippleForeground()',\n },\n})\nexport abstract class ControlBase extends TouchableBase {}\n\n/**\n * The press machine on its own, for a component that wants to be pressable rather than to\n * contain something that is.\n *\n * No selector: this is only ever a `hostDirectives` entry. A component listing it gets the whole\n * of `TouchableBase` on its own host node - the responder negotiation, the press rectangle, the\n * delays and the long-press timer - instead of wrapping a `<pressable>` and paying for a second\n * native view.\n *\n * It provides `TouchableBase`, so a primitive on the same node can `inject(TouchableBase)` and\n * read `pressed` without caring whether it landed on this or on a real `<pressable>`.\n */\n@Directive({\n providers: [{ provide: TouchableBase, useExisting: forwardRef(() => PressBehavior) }],\n})\nexport class PressBehavior extends ControlBase {\n protected override accessibleByDefault(): boolean {\n return true;\n }\n\n protected override focusableByDefault(): boolean {\n return true;\n }\n\n protected override disabledForAccessibility(): boolean {\n return this.disabled();\n }\n}\n\n/**\n * A view that responds to presses. RN's `Pressable`, with the same configuration: hit slop,\n * retention offset, press-in and press-out delays, long press, and an Android ripple.\n *\n * `pressed` is a public signal, so a template can style from it through a template reference:\n * `<pressable #p [style.opacity]=\"p.pressed() ? 0.5 : 1\">`.\n */\n@Directive({\n selector: 'pressable',\n exportAs: 'pressable',\n providers: [{ provide: TouchableBase, useExisting: forwardRef(() => Pressable) }],\n})\nexport class Pressable extends ControlBase {\n /** `Pressable.js`: a control is an accessibility element, and focusable, unless refused. */\n protected override accessibleByDefault(): boolean {\n return true;\n }\n\n protected override focusableByDefault(): boolean {\n return true;\n }\n\n protected override disabledForAccessibility(): boolean {\n return this.disabled();\n }\n}\n"]}
|
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
*
|
|
14
14
|
* **A `<safe-area-view>` needs one above it**, which is less obvious than it sounds. The native
|
|
15
15
|
* view walks its superviews for a provider and falls back to reading its own insets - but only
|
|
16
|
-
* once, as it enters the window, before it has been laid out, and nothing
|
|
17
|
-
* provider it therefore insets by zero and looks like it is working
|
|
16
|
+
* once, as it enters the window, before it has been laid out, and nothing notifies it when they
|
|
17
|
+
* change. With no provider it therefore insets by zero and looks like it is working, until a later
|
|
18
|
+
* update to that view happens to re-read them and the content jumps.
|
|
18
19
|
*
|
|
19
20
|
* That is also why a presented screen needs its own: it is outside the stack's view tree, which
|
|
20
21
|
* is the same reason it has no header. Give a modal a provider of its own with
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safe-area-provider.js","sourceRoot":"","sources":["../src/safe-area-provider.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"safe-area-provider.js","sourceRoot":"","sources":["../src/safe-area-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EACL,SAAS,EACT,UAAU,EACV,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,MAAM,EACN,KAAK,GACN,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,QAAQ,EAA2B,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAiB,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;;AAE5D,4FAA4F;AAC5F,SAAS,WAAW,CAAC,MAAc;IACjC,OAAO;QACL,uBAAuB,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE;QAC/C,yBAAyB,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,EAAE;QACnD,0BAA0B,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;QACrD,wBAAwB,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE;KAClD,CAAC;AACJ,CAAC;AAWD,MAAM,OAAO,gBAAgB;IAC3B;;;OAGG;IACM,YAAY,GAAG,KAAK,CAAC,IAAI,oFAAI,SAAS,EAAE,gBAAgB,GAAG,CAAC;IAErE;QACE,0BAA0B,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,aAAyB,CAAC;QAC1D,SAAS,CAAC,IAAI,CAAC,CAAC;QAEhB,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CACnC,IAAI,EACJ,cAAc,EACd,CAAC,KAAqC,EAAE,EAAE;YACxC,MAAM,MAAM,GAAG,KAAK,EAAE,WAAW,CAAC;YAClC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;gBAAE,OAAO;YAC5C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;YACzC,mFAAmF;YACnF,8DAA8D;YAC9D,MAAM,EAAE,YAAY,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QACnD,CAAC,CACF,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;uGA3BU,gBAAgB;2FAAhB,gBAAgB,uOAFjB,gBAAgB;;2FAEf,gBAAgB;kBAJ5B,SAAS;mBAAC;oBACT,QAAQ,EAAE,oBAAoB;oBAC9B,QAAQ,EAAE,gBAAgB;iBAC3B","sourcesContent":["/**\n * The view that measures the safe area and reports it, for the layouts that need the numbers.\n *\n * ```html\n * <safe-area-provider>\n * <native-stack-outlet />\n * </safe-area-provider>\n * ```\n *\n * One, at the root, wrapping everything. What it measures is its own frame and the insets around\n * it, which is why it has to be the thing filling the window rather than a view somewhere inside\n * it. It fills by default and paints nothing.\n *\n * **A `<safe-area-view>` needs one above it**, which is less obvious than it sounds. The native\n * view walks its superviews for a provider and falls back to reading its own insets - but only\n * once, as it enters the window, before it has been laid out, and nothing notifies it when they\n * change. With no provider it therefore insets by zero and looks like it is working, until a later\n * update to that view happens to re-read them and the content jumps.\n *\n * That is also why a presented screen needs its own: it is outside the stack's view tree, which\n * is the same reason it has no header. Give a modal a provider of its own with\n * `[reportInsets]=\"false\"`, so its geometry stays out of the app-wide `SafeArea` while it is up.\n */\nimport {\n Component,\n DestroyRef,\n ElementRef,\n Renderer2,\n booleanAttribute,\n inject,\n input,\n} from '@angular/core';\nimport { SafeArea, type Frame, type Insets } from '@ng-native/device';\nimport { Engine, claimHost, type HostNode } from '@ng-native/fabric';\nimport { registerSafeAreaComponents } from './safe-area.ts';\n\n/** The insets, in the form the cascade carries: one custom property per edge, in points. */\nfunction insetTokens(insets: Insets): Record<string, { length: number }> {\n return {\n '--safe-area-inset-top': { length: insets.top },\n '--safe-area-inset-right': { length: insets.right },\n '--safe-area-inset-bottom': { length: insets.bottom },\n '--safe-area-inset-left': { length: insets.left },\n };\n}\n\ninterface InsetsChange {\n readonly insets: Insets;\n readonly frame: Frame;\n}\n\n@Component({\n selector: 'safe-area-provider',\n template: '<ng-content />',\n})\nexport class SafeAreaProvider {\n /**\n * Whether what this measures becomes `SafeArea.insets`. The app has one safe area; a second\n * provider inside a modal is there so native descendants can find one, not to redefine it.\n */\n readonly reportInsets = input(true, { transform: booleanAttribute });\n\n constructor() {\n registerSafeAreaComponents();\n const host = inject(ElementRef).nativeElement as HostNode;\n claimHost(host);\n\n const area = inject(SafeArea);\n const engine = inject(Engine, { optional: true });\n const stop = inject(Renderer2).listen(\n host,\n 'insetsChange',\n (event: { nativeEvent?: InsetsChange }) => {\n const change = event?.nativeEvent;\n if (!change || !this.reportInsets()) return;\n area.report(change.insets, change.frame);\n // Also published to the stylesheet, where a padding that clears the home indicator\n // belongs. `env()` on the web; a seeded custom property here.\n engine?.updateTokens(insetTokens(change.insets));\n },\n );\n inject(DestroyRef).onDestroy(stop);\n }\n}\n"]}
|
package/dist/switch.js
CHANGED
|
@@ -83,7 +83,7 @@ export class Switch extends ViewBase {
|
|
|
83
83
|
this.engine.dispatchCommand(this.node, command, [desired]);
|
|
84
84
|
}
|
|
85
85
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: Switch, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
86
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.2.0", type: Switch, isStandalone: true, selector: "switch", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, thumbColor: { classPropertyName: "thumbColor", publicName: "thumbColor", isSignal: true, isRequired: false, transformFunction: null }, trackColor: { classPropertyName: "trackColor", publicName: "trackColor", isSignal: true, isRequired: false, transformFunction: null }, iosBackgroundColor: { classPropertyName: "iosBackgroundColor", publicName: "ios_backgroundColor", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange" }, host: { listeners: { "change": "onNativeChange($event)" }, properties: { "accessibilityState": "accessibilityStateProp()", "value": "checked()", "disabled": "disabled()", "enabled": "enabled()", "thumbTintColor": "thumbColor()", "tintColor": "trackColor()?.false", "trackColorForTrue": "trackColor()?.true", "trackColorForFalse": "trackColor()?.false", "trackTintColor": "checked() ? trackColor()?.true : trackColor()?.false", "style.backgroundColor": "iosBackgroundColor()", "style.borderRadius": "iosBackgroundColor() ? 16 : undefined" } }, usesInheritance: true, usesOnChanges: true, ngImport: i0 });
|
|
86
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.2.0", type: Switch, isStandalone: true, selector: "switch", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, thumbColor: { classPropertyName: "thumbColor", publicName: "thumbColor", isSignal: true, isRequired: false, transformFunction: null }, trackColor: { classPropertyName: "trackColor", publicName: "trackColor", isSignal: true, isRequired: false, transformFunction: null }, iosBackgroundColor: { classPropertyName: "iosBackgroundColor", publicName: "ios_backgroundColor", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange" }, host: { listeners: { "change": "onNativeChange($event)" }, properties: { "accessibilityState": "accessibilityStateProp()", "value": "checked()", "disabled": "disabled()", "attr.data-disabled": "disabled() ? '' : null", "enabled": "enabled()", "thumbTintColor": "thumbColor()", "tintColor": "trackColor()?.false", "trackColorForTrue": "trackColor()?.true", "trackColorForFalse": "trackColor()?.false", "trackTintColor": "checked() ? trackColor()?.true : trackColor()?.false", "style.backgroundColor": "iosBackgroundColor()", "style.borderRadius": "iosBackgroundColor() ? 16 : undefined" } }, usesInheritance: true, usesOnChanges: true, ngImport: i0 });
|
|
87
87
|
}
|
|
88
88
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: Switch, decorators: [{
|
|
89
89
|
type: Directive,
|
|
@@ -95,6 +95,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImpor
|
|
|
95
95
|
'[accessibilityState]': 'accessibilityStateProp()',
|
|
96
96
|
'[value]': 'checked()',
|
|
97
97
|
'[disabled]': 'disabled()',
|
|
98
|
+
'[attr.data-disabled]': "disabled() ? '' : null",
|
|
98
99
|
'[enabled]': 'enabled()',
|
|
99
100
|
'[thumbTintColor]': 'thumbColor()',
|
|
100
101
|
'[tintColor]': 'trackColor()?.false',
|
package/dist/switch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch.js","sourceRoot":"","sources":["../src/switch.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,QAAQ,EAER,eAAe,EACf,QAAQ,EACR,MAAM,EACN,MAAM,EACN,KAAK,EACL,KAAK,GACN,MAAM,eAAe,CAAC;AACvB,OAAO,EAA6B,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;;AAE1C;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"switch.js","sourceRoot":"","sources":["../src/switch.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Directive,\n Injector,\n type SimpleChanges,\n afterNextRender,\n computed,\n effect,\n inject,\n input,\n model,\n} from '@angular/core';\nimport { type NativeSyntheticEvent, nativePlatform } from '@ng-native/fabric';\nimport { ControlledModel } from './controlled-model.ts';\nimport { optionalBoolean } from './transforms.ts';\nimport { ViewBase } from './view-base.ts';\n\n/**\n * A toggle, wired for signal forms as a `FormCheckboxControl` (`checked`, not `value`). Commits\n * as `Switch` on iOS and `AndroidSwitch` on Android.\n *\n * The two platforms spell the same props differently, so both spellings are sent and each\n * native side reads its own; a prop it does not know is ignored.\n *\n * Controlled as React Native's `Switch` is: bind `checked` and the app's value is what the switch\n * shows. The user flips it, the app keeps the old value, and a prop diff has nothing to send,\n * because the prop never changed; native is the only side that moved. So once the pass the flip\n * started has rendered, the switch compares the model with what native reported and, if they\n * differ, sends the command RN's wrapper sends - `setValue` on iOS, `setNativeValue` on Android.\n * See `ControlledModel` for how the model comes to say what the app says.\n */\n@Directive({\n selector: 'switch',\n host: {\n // `disabled` is an input of ours, so it cannot reach `ngOnChanges` on the base; this is\n // the one binding that keeps the announced state in step with it.\n '[accessibilityState]': 'accessibilityStateProp()',\n '[value]': 'checked()',\n '[disabled]': 'disabled()',\n '[attr.data-disabled]': \"disabled() ? '' : null\",\n '[enabled]': 'enabled()',\n '[thumbTintColor]': 'thumbColor()',\n '[tintColor]': 'trackColor()?.false',\n '[trackColorForTrue]': 'trackColor()?.true',\n '[trackColorForFalse]': 'trackColor()?.false',\n '[trackTintColor]': 'checked() ? trackColor()?.true : trackColor()?.false',\n '[style.backgroundColor]': 'iosBackgroundColor()',\n '[style.borderRadius]': 'iosBackgroundColor() ? 16 : undefined',\n '(change)': 'onNativeChange($event)',\n },\n})\nexport class Switch extends ViewBase {\n readonly checked = model<boolean>(false);\n /** Ignore touches and grey out. */\n readonly disabled = input(undefined, { transform: optionalBoolean });\n\n /** `Switch.js`: `accessibilityRole={props.accessibilityRole ?? 'switch'}`. */\n protected override roleByDefault(): 'switch' {\n return 'switch';\n }\n\n protected override disabledForAccessibility(): boolean | undefined {\n return this.disabled();\n }\n\n protected override checkedForAccessibility(): boolean {\n return this.checked();\n }\n /** The colour of the knob. */\n readonly thumbColor = input<string>();\n /** The track colour for each state. */\n readonly trackColor = input<{ readonly false?: string; readonly true?: string }>();\n /** iOS: the colour behind the track when off, seen where the track is transparent. */\n readonly iosBackgroundColor = input<string>(undefined, { alias: 'ios_backgroundColor' });\n\n protected readonly enabled = computed(() => {\n const disabled = this.disabled();\n return disabled === undefined ? undefined : !disabled;\n });\n\n private readonly injector = inject(Injector);\n private readonly control = new ControlledModel(this.checked, 'checked');\n /** What native reported last, until the pass it started has rendered and been compared. */\n private nativeValue: boolean | null = null;\n\n constructor() {\n super();\n effect(() => {\n // Android spells the value `on` and iOS the on-track colour `onTintColor`. Angular refuses\n // both as host bindings because they read as event handlers, so they go to the node.\n this.engine.setProp(this.node, 'on', this.checked());\n this.engine.setProp(this.node, 'onTintColor', this.trackColor()?.true);\n });\n }\n\n override ngOnChanges(changes: SimpleChanges): void {\n super.ngOnChanges(changes);\n this.control.noteChanges(changes);\n }\n\n protected onNativeChange(event: NativeSyntheticEvent<{ value?: boolean }>): void {\n this.nativeValue = event.nativeEvent?.value ?? false;\n this.control.propose(this.nativeValue);\n afterNextRender({ write: () => this.reconcile() }, { injector: this.injector });\n }\n\n /**\n * After the app's bindings have settled, not before: a flip the app accepts reaches the model\n * during change detection, and comparing any earlier would send native back the value it is\n * about to be given. A value set from code later needs none of this, as the prop changes.\n */\n private reconcile(): void {\n const native = this.nativeValue;\n this.nativeValue = null;\n const desired = this.checked();\n if (native === null || native === desired) return;\n const command = nativePlatform() === 'android' ? 'setNativeValue' : 'setValue';\n this.engine.dispatchCommand(this.node, command, [desired]);\n }\n}\n"]}
|
package/dist/text.d.ts
CHANGED
|
@@ -22,6 +22,12 @@ export declare class Text extends TouchableBase {
|
|
|
22
22
|
* `Platform.OS` decides, exactly as React Native's own wrapper does.
|
|
23
23
|
*/
|
|
24
24
|
protected accessibleByDefault(): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* `Text.js` announces `disabled` on every text, pressable or not, nested or not. Written from
|
|
27
|
+
* `ngOnChanges` like the rest of the state, since `disabled` is an input of this directive: no
|
|
28
|
+
* host binding, which `ControlBase` needs and a text cannot afford.
|
|
29
|
+
*/
|
|
30
|
+
protected disabledForAccessibility(): boolean;
|
|
25
31
|
/** Truncate after this many lines, with `ellipsizeMode` deciding where the ellipsis goes. */
|
|
26
32
|
readonly numberOfLines: import("@angular/core").InputSignalWithTransform<number | undefined, unknown>;
|
|
27
33
|
/**
|
package/dist/text.js
CHANGED
|
@@ -25,6 +25,14 @@ export class Text extends TouchableBase {
|
|
|
25
25
|
accessibleByDefault() {
|
|
26
26
|
return nativePlatform() === 'android' ? this.pressable() : true;
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* `Text.js` announces `disabled` on every text, pressable or not, nested or not. Written from
|
|
30
|
+
* `ngOnChanges` like the rest of the state, since `disabled` is an input of this directive: no
|
|
31
|
+
* host binding, which `ControlBase` needs and a text cannot afford.
|
|
32
|
+
*/
|
|
33
|
+
disabledForAccessibility() {
|
|
34
|
+
return this.disabled();
|
|
35
|
+
}
|
|
28
36
|
/** Truncate after this many lines, with `ellipsizeMode` deciding where the ellipsis goes. */
|
|
29
37
|
numberOfLines = input(undefined, { ...(ngDevMode ? { debugName: "numberOfLines" } : /* istanbul ignore next */ {}), transform: optionalNumber });
|
|
30
38
|
/**
|
|
@@ -91,6 +99,9 @@ export class Text extends TouchableBase {
|
|
|
91
99
|
write('dataDetectorType', this.dataDetectorType());
|
|
92
100
|
write('android_hyphenationFrequency', this.hyphenationFrequency());
|
|
93
101
|
write('isPressable', this.pressable() || undefined);
|
|
102
|
+
// `disabled` is consumed as an input, so this is what `[data-disabled]` and `disabled:` match,
|
|
103
|
+
// as on a control. Written here rather than bound from the host; see `pressedChanged`.
|
|
104
|
+
write('data-disabled', this.disabled() ? '' : undefined);
|
|
94
105
|
}
|
|
95
106
|
claims() {
|
|
96
107
|
return this.pressable() && !this.disabled();
|
package/dist/text.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","sourceRoot":"","sources":["../src/text.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../src/text.ts"],"names":[],"mappings":"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","sourcesContent":["import { Directive, booleanAttribute, input } from '@angular/core';\nimport { nativePlatform } from '@ng-native/fabric';\nimport { TouchableBase } from './pressable.ts';\nimport { optionalBoolean, optionalNumber } from './transforms.ts';\n\nexport type EllipsizeMode = 'head' | 'middle' | 'tail' | 'clip';\nexport type DynamicTypeRamp =\n | 'caption2'\n | 'caption1'\n | 'footnote'\n | 'subheadline'\n | 'callout'\n | 'body'\n | 'headline'\n | 'title3'\n | 'title2'\n | 'title1'\n | 'largeTitle';\n\n/**\n * A run of text. Commits as `Paragraph`, or as a span (`VirtualText`) when nested in another\n * `<text>`, which the engine decides from the tree so a nested run inherits its parent's font\n * and sits on its baseline.\n *\n * Text inherits `color`, `fontSize` and the other text properties from CSS as it does on the\n * web; from an inline `[style]` on an ancestor view it does not, exactly as in RN.\n *\n * Presses: RN makes a text pressable when a press handler is present. Angular cannot see\n * whether `(press)` is bound, so set `pressable` to opt in; the handlers, delays and long press\n * are then the same as `<pressable>`'s. iOS highlights a pressed run unless\n * `suppressHighlighting` is set.\n */\n@Directive({\n selector: 'text',\n exportAs: 'text',\n})\nexport class Text extends TouchableBase {\n /**\n * `Text.js` splits by platform: on iOS every text is an accessibility element unless refused,\n * on Android only one that can be pressed. Nothing native can infer which, so the host's\n * `Platform.OS` decides, exactly as React Native's own wrapper does.\n */\n protected override accessibleByDefault(): boolean {\n return nativePlatform() === 'android' ? this.pressable() : true;\n }\n\n /**\n * `Text.js` announces `disabled` on every text, pressable or not, nested or not. Written from\n * `ngOnChanges` like the rest of the state, since `disabled` is an input of this directive: no\n * host binding, which `ControlBase` needs and a text cannot afford.\n */\n protected override disabledForAccessibility(): boolean {\n return this.disabled();\n }\n\n /** Truncate after this many lines, with `ellipsizeMode` deciding where the ellipsis goes. */\n readonly numberOfLines = input<number>(undefined, { transform: optionalNumber });\n /**\n * Where truncated text is cut. `clip` is iOS only. Defaults to `tail`, as React Native's `Text`\n * does in JavaScript: native's own default is to clip, with no ellipsis. The default is the\n * engine's, below `text-overflow` in a stylesheet, which in turn is below this input.\n */\n readonly ellipsizeMode = input<EllipsizeMode>();\n /** Let the user select and copy the text. */\n readonly selectable = input<boolean>(undefined, { transform: optionalBoolean });\n /** The highlight colour of a selection. */\n readonly selectionColor = input<string>();\n /** Scale with the system Text Size setting. Defaults to true. */\n readonly allowFontScaling = input<boolean>(undefined, { transform: optionalBoolean });\n /** The most `allowFontScaling` may scale by; 0 means no limit. */\n readonly maxFontSizeMultiplier = input<number>(undefined, { transform: optionalNumber });\n /** iOS: the Dynamic Type style this text follows. */\n readonly dynamicTypeRamp = input<DynamicTypeRamp>();\n /** iOS: shrink the font to fit `numberOfLines`. */\n readonly adjustsFontSizeToFit = input<boolean>(undefined, { transform: optionalBoolean });\n /** iOS: the smallest scale `adjustsFontSizeToFit` may shrink to, from 0.01 to 1. */\n readonly minimumFontScale = input<number>(undefined, { transform: optionalNumber });\n /** iOS: the line-breaking strategy. */\n readonly lineBreakStrategyIOS = input<'none' | 'standard' | 'hangul-word' | 'push-out'>();\n /** Android: the line-breaking strategy. */\n readonly textBreakStrategy = input<'simple' | 'highQuality' | 'balanced'>();\n /** Android: turn phone numbers, links and addresses into tappable text. */\n readonly dataDetectorType = input<'phoneNumber' | 'link' | 'email' | 'none' | 'all'>();\n /** Android: how often to hyphenate. */\n readonly hyphenationFrequency = input<'normal' | 'none' | 'full'>(undefined, {\n alias: 'android_hyphenationFrequency',\n });\n /** Respond to presses. See the class note. */\n readonly pressable = input(false, { transform: booleanAttribute });\n /** iOS: do not grey the text while it is pressed. */\n readonly suppressHighlighting = input(false, { transform: booleanAttribute });\n\n /**\n * Written when the press starts and ends rather than bound from the host: a host binding would\n * run for every text on screen on every pass, to follow a press that almost none of them get.\n */\n protected override pressedChanged(pressed: boolean): void {\n const highlight = pressed && !this.suppressHighlighting();\n this.engine.setProp(this.node, 'isHighlighted', highlight ? true : undefined);\n }\n\n /** The pass-through props, written when one of them changes. See `ViewBase.ngOnChanges`. */\n override ngOnChanges(): void {\n super.ngOnChanges();\n const write = (key: string, value: unknown) => this.engine.setProp(this.node, key, value);\n write('numberOfLines', this.numberOfLines());\n write('ellipsizeMode', this.ellipsizeMode());\n write('selectable', this.selectable());\n write('selectionColor', this.selectionColor());\n write('allowFontScaling', this.allowFontScaling());\n write('maxFontSizeMultiplier', this.maxFontSizeMultiplier());\n write('dynamicTypeRamp', this.dynamicTypeRamp());\n write('adjustsFontSizeToFit', this.adjustsFontSizeToFit());\n write('minimumFontScale', this.minimumFontScale());\n write('lineBreakStrategyIOS', this.lineBreakStrategyIOS());\n write('textBreakStrategy', this.textBreakStrategy());\n write('dataDetectorType', this.dataDetectorType());\n write('android_hyphenationFrequency', this.hyphenationFrequency());\n write('isPressable', this.pressable() || undefined);\n // `disabled` is consumed as an input, so this is what `[data-disabled]` and `disabled:` match,\n // as on a control. Written here rather than bound from the host; see `pressedChanged`.\n write('data-disabled', this.disabled() ? '' : undefined);\n }\n\n protected override claims(): boolean {\n return this.pressable() && !this.disabled();\n }\n\n protected override measures(): boolean {\n return this.pressable();\n }\n}\n"]}
|
package/dist/view-base.d.ts
CHANGED
|
@@ -254,6 +254,12 @@ export declare abstract class ViewBase {
|
|
|
254
254
|
*/
|
|
255
255
|
ngOnChanges(_changes?: SimpleChanges): void;
|
|
256
256
|
private writeAccessibility;
|
|
257
|
+
/**
|
|
258
|
+
* The aria states Tailwind has variants for, put back on the node as the attributes they came
|
|
259
|
+
* in as. The inputs consume them, so `[aria-disabled="true"]` and every `aria-*:` utility had
|
|
260
|
+
* nothing to match. Hyphenated, so the engine keeps them for selectors and never sends them.
|
|
261
|
+
*/
|
|
262
|
+
private publishAriaState;
|
|
257
263
|
/** The half of accessibility that is about what assistive technology may see, and in which language. */
|
|
258
264
|
private writeVisibility;
|
|
259
265
|
/**
|
package/dist/view-base.js
CHANGED
|
@@ -325,6 +325,21 @@ export class ViewBase {
|
|
|
325
325
|
write('accessibilityValue', this.mergedAccessibilityValue());
|
|
326
326
|
write('accessibilityActions', this.accessibilityActions());
|
|
327
327
|
this.writeVisibility();
|
|
328
|
+
this.publishAriaState(write);
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* The aria states Tailwind has variants for, put back on the node as the attributes they came
|
|
332
|
+
* in as. The inputs consume them, so `[aria-disabled="true"]` and every `aria-*:` utility had
|
|
333
|
+
* nothing to match. Hyphenated, so the engine keeps them for selectors and never sends them.
|
|
334
|
+
*/
|
|
335
|
+
publishAriaState(write) {
|
|
336
|
+
const attribute = (value) => (value === undefined ? undefined : String(value));
|
|
337
|
+
write('aria-busy', attribute(this.ariaBusy()));
|
|
338
|
+
write('aria-checked', attribute(this.ariaChecked()));
|
|
339
|
+
write('aria-disabled', attribute(this.ariaDisabled()));
|
|
340
|
+
write('aria-expanded', attribute(this.ariaExpanded()));
|
|
341
|
+
write('aria-hidden', attribute(this.ariaHidden()));
|
|
342
|
+
write('aria-selected', attribute(this.ariaSelected()));
|
|
328
343
|
}
|
|
329
344
|
/** The half of accessibility that is about what assistive technology may see, and in which language. */
|
|
330
345
|
writeVisibility() {
|
package/dist/view-base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view-base.js","sourceRoot":"","sources":["../src/view-base.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The props every native view accepts, as typed inputs forwarded to the host node.\n *\n * Each input is mirrored by a host binding of the same name, which is what carries the value to\n * the renderer: once a directive declares an input, Angular routes the binding to the directive\n * rather than the element. An unset input stays `undefined` and never reaches native, so a view\n * that mentions none of these sends none of them.\n *\n * Web-style `aria-*` names are accepted as aliases and land on the `accessibility*` props React\n * Native's own `View.js` maps them to. `id` maps to `nativeID` and `tabIndex` to `focusable` the\n * same way.\n *\n * Events are element events, typed in `events.ts`: `(layout)`, `(touchStart)`,\n * `(accessibilityAction)` and so on. They are deliberately not outputs; see that file.\n */\nimport { Directive, ElementRef, type SimpleChanges, inject, input } from '@angular/core';\nimport { HostEngine, claimHost, declareNativeProps, type HostNode } from '@ng-native/fabric';\nimport type { Insets } from './events.ts';\nimport { optionalBoolean, optionalNumber } from './transforms.ts';\nimport { WRITTEN_PROPS } from './written-props.ts';\n\n/** The roles assistive technologies understand. `Role` is the web spelling of the same set. */\nexport type AccessibilityRole =\n | 'none'\n | 'button'\n | 'togglebutton'\n | 'link'\n | 'search'\n | 'image'\n | 'keyboardkey'\n | 'text'\n | 'adjustable'\n | 'imagebutton'\n | 'header'\n | 'summary'\n | 'alert'\n | 'checkbox'\n | 'combobox'\n | 'menu'\n | 'menubar'\n | 'menuitem'\n | 'progressbar'\n | 'radio'\n | 'radiogroup'\n | 'scrollbar'\n | 'spinbutton'\n | 'switch'\n | 'tab'\n | 'tabbar'\n | 'tablist'\n | 'timer'\n | 'list'\n | 'toolbar'\n | 'grid'\n | 'pager'\n | 'scrollview'\n | 'horizontalscrollview'\n | 'viewgroup'\n | 'webview'\n | 'drawerlayout'\n | 'slidingdrawer'\n | 'iconmenu';\n\nexport interface AccessibilityState {\n readonly disabled?: boolean;\n readonly selected?: boolean;\n readonly checked?: boolean | 'mixed';\n readonly busy?: boolean;\n readonly expanded?: boolean;\n}\n\nexport interface AccessibilityValue {\n readonly min?: number;\n readonly max?: number;\n readonly now?: number;\n readonly text?: string;\n}\n\nexport interface AccessibilityAction {\n readonly name: string;\n readonly label?: string;\n}\n\n/** Android's `nativeBackgroundAndroid` and `nativeForegroundAndroid`. */\nexport type AndroidDrawable =\n | {\n readonly type: 'RippleAndroid';\n readonly color?: string | number;\n readonly borderless?: boolean;\n readonly rippleRadius?: number;\n }\n | { readonly type: 'ThemeAttrAndroid'; readonly attribute: string };\n\nexport type PointerEvents = 'box-none' | 'none' | 'box-only' | 'auto';\nexport type ImportantForAccessibility = 'auto' | 'yes' | 'no' | 'no-hide-descendants';\nexport type AccessibilityLiveRegion = 'none' | 'polite' | 'assertive';\n\n/**\n * Angular writes a static attribute to the element as well as feeding it to the input of the\n * same name, so `<switch thumbColor=\"#fff\">` leaves a stray `thumbColor` prop on the node next to\n * the `thumbTintColor` the input produces. The inputs of the directive are what consumed them,\n * so those names come off the node; a host binding puts back any that native does read.\n *\n * Walking the *node's* props rather than the directive's inputs is not a detail. This runs for\n * every element on screen, a primitive declares some forty-five inputs, and at this point the node\n * usually has no props at all - bindings have not run yet, so only static attributes are there.\n * The other way round it was forty-five `delete`s per element on an object that had none of them,\n * which is both wasted work and the way to push an object into dictionary mode.\n */\n/** Shallow equality, so a re-merged state that says the same thing keeps its identity. */\nfunction sameState(a: AccessibilityState, b: AccessibilityState): boolean {\n const keys = Object.keys(a) as (keyof AccessibilityState)[];\n return keys.length === Object.keys(b).length && keys.every((key) => a[key] === b[key]);\n}\n\n/** The host primitives whose props have been declared to the engine. */\nconst declared = new WeakSet<object>();\n\n/**\n * Tell the engine the props this primitive's native view takes, once per component class: its\n * inputs by their public names, and `WRITTEN_PROPS`. What its check for a misspelt prop reads.\n */\nfunction declareProps(ctor: unknown, node: HostNode): void {\n if (declared.has(ctor as object)) return;\n declared.add(ctor as object);\n const def =\n (ctor as { ɵcmp?: { inputs?: object }; ɵdir?: { inputs?: object } }).ɵcmp ??\n (ctor as { ɵdir?: { inputs?: object } }).ɵdir;\n const name = (node as { name?: string }).name;\n if (!name || !def?.inputs) return;\n declareNativeProps(name, [...Object.keys(def.inputs), ...WRITTEN_PROPS]);\n}\n\nfunction stripConsumedAttributes(ctor: unknown, node: HostNode): void {\n // A directive with no selector is only ever a `hostDirectives` entry, which exposes the inputs\n // it lists and no others, so an attribute of the same name as the rest was not consumed.\n type Def = { inputs?: Record<string, unknown>; selectors?: readonly unknown[] };\n const { ɵcmp, ɵdir } = ctor as { ɵcmp?: Def; ɵdir?: Def };\n const def = ɵcmp ?? (ɵdir?.selectors?.length ? ɵdir : undefined);\n const inputs = def?.inputs;\n if (!inputs) return;\n // A host that has not put a bag on the node yet has no attributes to take off it. Read\n // unconditionally, this threw `Cannot convert undefined or null to object` on the first\n // component a browser host ever mounted, before anything rendered - which is a hard crash\n // standing between this package and a second platform, for a loop with nothing to do.\n const props = node.props as Record<string, unknown> | undefined;\n if (!props) return;\n for (const name of Object.keys(props)) {\n if (name in inputs) delete props[name];\n }\n}\n\n/**\n * What a directive on the same node says this view *is*, for a screen reader.\n *\n * A host primitive knows it is a view; only the thing composed onto it knows it is a button, a\n * checkbox or an accordion trigger. Without this seam that knowledge has nowhere to go: the role\n * and the state are written here, from this class's own inputs, and a later `ngOnChanges` would\n * overwrite anything a directive had set behind its back.\n *\n * Registered on the element with `contributeAccessibility`, and several primitives may contribute\n * to one element - a trigger that is also a button.\n */\nexport interface AccessibilityContribution {\n /** The role, if this directive implies one. An explicit `role` on the element still wins. */\n readonly role?: AccessibilityRole;\n /**\n * State to merge in, read on every write so it may be a signal read.\n *\n * Spelled in full because `state` is what a primitive calls the thing it publishes for a\n * stylesheet - `data-state=\"checked\"` - and the two are not the same thing.\n */\n readonly accessibilityState?: () => AccessibilityState | undefined;\n}\n\n/** Where an element's contributions are kept: on the node, and only on a node that has some. */\nconst CONTRIBUTIONS = Symbol('angular-native.accessibilityContributions');\ntype Contributed = HostNode & { [CONTRIBUTIONS]?: AccessibilityContribution[] };\nconst NO_CONTRIBUTIONS: readonly AccessibilityContribution[] = [];\n\n/**\n * Tell the primitive on this element what it is, for a screen reader: a role, and state to merge\n * into what it announces. Call it from a directive's field initialiser or constructor, on the\n * element the primitive is on:\n *\n * private readonly contribution = contributeAccessibility({ role: 'button' });\n * private readonly contribution = contributeAccessibility(this);\n *\n * Kept on the node rather than provided through DI, because asking the injector costs every\n * element on screen a lookup to learn that nothing contributes - about a tenth of creating a list.\n * Reading a property that is not there costs nothing.\n */\nexport function contributeAccessibility<T extends AccessibilityContribution>(contribution: T): T {\n const node = inject(ElementRef).nativeElement as Contributed;\n (node[CONTRIBUTIONS] ??= []).push(contribution);\n return contribution;\n}\n\n@Directive()\nexport abstract class ViewBase {\n /** The retained node this directive sits on. */\n protected readonly node = inject(ElementRef).nativeElement as HostNode;\n\n /**\n * The engine, because the props these inputs carry are written straight onto the node. Read\n * off the node where the host put it there, which is one property read against an injector\n * lookup that walks every ancestor element, for every element on screen.\n */\n protected readonly engine: HostEngine = this.node.host ?? inject(HostEngine);\n\n /**\n * See `contributeAccessibility`. Empty for every element nothing is composed onto. Read, never\n * cached, from `ngOnInit` onwards: by then every directive on the node has been constructed and\n * registered what it has to say.\n */\n private get contributions(): readonly AccessibilityContribution[] {\n return (this.node as Contributed)[CONTRIBUTIONS] ?? NO_CONTRIBUTIONS;\n }\n\n constructor() {\n claimHost(this.node);\n stripConsumedAttributes(this.constructor, this.node);\n declareProps(this.constructor, this.node);\n this.engine.settle(this);\n }\n\n /** Whether `ngOnInit` has run, which is what writes the props every element starts with. */\n private initialised = false;\n\n /**\n * Write what the inputs say, for an element whose view has not been checked by the time the\n * host commits it. Nothing for one that has.\n *\n * The props are written from `ngOnChanges` and `ngOnInit`, which Angular runs in the parent\n * view's update pass. A component that detaches itself before its first check never gets one,\n * and on the web that pattern still works, because a listener and an attribute are there from\n * creation. So the host calls this before the commit that first mounts the element, by when its\n * static inputs are set: the press handling, the role and the `testID` are there, and the view\n * behaves as written once something calls `detectChanges()`.\n */\n settleProps(): void {\n if (this.initialised) return;\n this.ngOnChanges({});\n this.ngOnInit();\n }\n\n // --- accessibility ---------------------------------------------------------------------\n\n /** Whether the view is an accessibility element. Defaults to false for a plain view. */\n readonly accessible = input<boolean>(undefined, { transform: optionalBoolean });\n /** What a screen reader announces for the view. */\n readonly accessibilityLabel = input<string>();\n /** `aria-label`: web spelling of `accessibilityLabel`. */\n readonly ariaLabel = input<string>(undefined, { alias: 'aria-label' });\n /** Android: `nativeID`s of the views that label this one. */\n readonly accessibilityLabelledBy = input<string | readonly string[]>();\n /** `aria-labelledby`: web spelling of `accessibilityLabelledBy`. */\n readonly ariaLabelledBy = input<string | readonly string[]>(undefined, {\n alias: 'aria-labelledby',\n });\n /** What happens when the user acts on the view, when the label alone does not say. */\n readonly accessibilityHint = input<string>();\n /** The kind of control this is, for assistive technologies. */\n readonly accessibilityRole = input<AccessibilityRole>();\n /** `role`: the web spelling of `accessibilityRole`. */\n readonly role = input<AccessibilityRole>();\n /** Disabled, selected, checked, busy and expanded, as one object. */\n readonly accessibilityState = input<AccessibilityState>();\n /** `aria-busy`. */\n readonly ariaBusy = input<boolean>(undefined, { alias: 'aria-busy', transform: optionalBoolean });\n /** `aria-checked`. */\n readonly ariaChecked = input<boolean | 'mixed'>(undefined, { alias: 'aria-checked' });\n /** `aria-disabled`. */\n readonly ariaDisabled = input<boolean>(undefined, {\n alias: 'aria-disabled',\n transform: optionalBoolean,\n });\n /** `aria-expanded`. */\n readonly ariaExpanded = input<boolean>(undefined, {\n alias: 'aria-expanded',\n transform: optionalBoolean,\n });\n /** `aria-selected`. */\n readonly ariaSelected = input<boolean>(undefined, {\n alias: 'aria-selected',\n transform: optionalBoolean,\n });\n /** The current value of an adjustable control, for a screen reader. */\n readonly accessibilityValue = input<AccessibilityValue>();\n /** `aria-valuemin`. */\n readonly ariaValueMin = input<number>(undefined, {\n alias: 'aria-valuemin',\n transform: optionalNumber,\n });\n /** `aria-valuemax`. */\n readonly ariaValueMax = input<number>(undefined, {\n alias: 'aria-valuemax',\n transform: optionalNumber,\n });\n /** `aria-valuenow`. */\n readonly ariaValueNow = input<number>(undefined, {\n alias: 'aria-valuenow',\n transform: optionalNumber,\n });\n /** `aria-valuetext`. */\n readonly ariaValueText = input<string>(undefined, { alias: 'aria-valuetext' });\n /** Custom actions a screen reader can invoke; each arrives as `(accessibilityAction)`. */\n readonly accessibilityActions = input<readonly AccessibilityAction[]>();\n /** Android: announce changes to this view's content without focus moving to it. */\n readonly accessibilityLiveRegion = input<AccessibilityLiveRegion>();\n /** `aria-live`. */\n readonly ariaLive = input<AccessibilityLiveRegion>(undefined, { alias: 'aria-live' });\n /** iOS: hide this view and its children from assistive technologies. */\n readonly accessibilityElementsHidden = input<boolean>(undefined, { transform: optionalBoolean });\n /** `aria-hidden`: `accessibilityElementsHidden` on iOS, `no-hide-descendants` on Android. */\n readonly ariaHidden = input<boolean>(undefined, {\n alias: 'aria-hidden',\n transform: optionalBoolean,\n });\n /** Android: whether this view is exposed to accessibility, and whether its children are. */\n readonly importantForAccessibility = input<ImportantForAccessibility>();\n /** iOS: VoiceOver ignores every sibling while this view is shown, as a modal expects. */\n readonly accessibilityViewIsModal = input<boolean>(undefined, { transform: optionalBoolean });\n /** `aria-modal`. */\n readonly ariaModal = input<boolean>(undefined, {\n alias: 'aria-modal',\n transform: optionalBoolean,\n });\n /** iOS: keep the view's colours when the Invert Colors setting is on; images want this. */\n readonly accessibilityIgnoresInvertColors = input<boolean>(undefined, {\n transform: optionalBoolean,\n });\n /** iOS: the language VoiceOver reads the label in, as a BCP 47 tag. */\n readonly accessibilityLanguage = input<string>();\n /** iOS: the title shown by the Large Content Viewer on a long press with large text on. */\n readonly accessibilityLargeContentTitle = input<string>();\n /** iOS: opt this view into the Large Content Viewer. */\n readonly accessibilityShowsLargeContentViewer = input<boolean>(undefined, {\n transform: optionalBoolean,\n });\n /** iOS: tell VoiceOver the view responds to a tap even without a role that implies it. */\n readonly accessibilityRespondsToUserInteraction = input<boolean>(undefined, {\n transform: optionalBoolean,\n });\n\n // --- identity and hit testing ----------------------------------------------------------\n\n /** A handle native code can find the view by; also what `:id` selectors match. */\n readonly nativeID = input<string>();\n /** `id`: the web spelling of `nativeID`. */\n readonly id = input<string>();\n /** A handle for end-to-end test tooling. */\n readonly testID = input<string>();\n /** Extend the touchable area beyond the view's bounds, without moving anything visible. */\n readonly hitSlop = input<Insets | number>();\n /** Whether this view, its children, or neither can be the target of a touch. */\n readonly pointerEvents = input<PointerEvents>();\n /** Set to false to keep a layout-only view alive; Fabric otherwise removes it from the tree. */\n readonly collapsable = input<boolean>(undefined, { transform: optionalBoolean });\n /** Set to false to keep this view's layout-only children from being flattened. */\n readonly collapsableChildren = input<boolean>(undefined, { transform: optionalBoolean });\n /** Detach children that are outside the visible bounds. A scroll view optimisation. */\n readonly removeClippedSubviews = input<boolean>(undefined, { transform: optionalBoolean });\n /** Composite the view offscreen so a translucent view with children blends correctly. */\n readonly needsOffscreenAlphaCompositing = input<boolean>(undefined, {\n transform: optionalBoolean,\n });\n /** Android: whether the view takes keyboard or TV focus. RN's `tabIndex` is this. */\n readonly focusable = input<boolean>(undefined, { transform: optionalBoolean });\n /** iOS: render the view to a bitmap once and reuse it; for a static view that animates. */\n readonly shouldRasterizeIOS = input<boolean>(undefined, { transform: optionalBoolean });\n /** Android: cache the view in a hardware texture; the same trade as `shouldRasterizeIOS`. */\n readonly renderToHardwareTextureAndroid = input<boolean>(undefined, {\n transform: optionalBoolean,\n });\n /** Android: a ripple or theme drawable painted behind the view's content. */\n readonly nativeBackgroundAndroid = input<AndroidDrawable>();\n /** Android: a ripple or theme drawable painted over the view's content. */\n readonly nativeForegroundAndroid = input<AndroidDrawable>();\n\n // --- merged views of the aliases ------------------------------------------------------\n\n /**\n * What React Native's own JavaScript wrapper would have defaulted, per component.\n *\n * Driving the native views directly skips those wrappers, and what is lost is invisible: the\n * app looks identical and is unusable with a screen reader, because nothing on it is an\n * accessibility element. Each hook is overridden by the component whose wrapper sets it, and\n * cites the file it came from.\n */\n\n /** True for anything that behaves like a control. `Pressable.js`: `accessible !== false`. */\n protected accessibleByDefault(): boolean {\n return false;\n }\n\n /** Whether the platform's focus order should include this. `Pressable.js` again. */\n protected focusableByDefault(): boolean {\n return false;\n }\n\n /** A role the component itself implies. `Switch.js`: `accessibilityRole ?? 'switch'`. */\n protected roleByDefault(): AccessibilityRole | undefined {\n return undefined;\n }\n\n /**\n * The component's own `disabled`, for the state a screen reader announces.\n *\n * React Native merges this whenever the prop was passed, even as false. An input here always\n * has a value, so there is no telling \"passed false\" from \"not passed\"; only true is merged,\n * and a control that is not disabled says nothing rather than saying so on every node.\n */\n protected disabledForAccessibility(): boolean | undefined {\n return undefined;\n }\n\n /**\n * The component's own `checked`, for a control whose checked state is not an accessibility\n * input at all - `Switch`'s `checked` is a `model()`, not one of this class's inputs, so it\n * cannot reach `ngOnChanges` here any more than `disabled` can.\n */\n protected checkedForAccessibility(): boolean | 'mixed' | undefined {\n return undefined;\n }\n\n /**\n * Write what the inputs say onto the node.\n *\n * This is what thirty host bindings used to do, and it is here rather than there for a reason\n * that was measured: a host binding costs every element that carries it, on every pass, whether\n * or not the app ever set the prop, and mounting four hundred rows spent a third of its time on\n * the accessibility surface alone. Angular calls this once with everything that changed instead.\n *\n * It works with signal inputs, which is easy to assume it does not: `ngOnChanges` fires for\n * them as it does for any other input, because `ngOnChangesSetInput` records a `SimpleChange`\n * before writing the signal. `signal-onchanges.test.ts` is there to keep that fact honest.\n *\n * What remains is the allocation - a signal input builds its node whether or not anything binds\n * to it, and there are forty-six here. Moving prop groups into directives selected by the props\n * they carry (`[accessibilityLabel], [aria-label], ...`) is how that goes away: an element that\n * binds none of them would allocate nothing. Measured on a 400-row mount it is worth about 40ms,\n * at the price of an import per group.\n */\n ngOnChanges(_changes?: SimpleChanges): void {\n this.writeAccessibility();\n this.writeIdentity();\n }\n\n private writeAccessibility(): void {\n const write = this.writer();\n write(\n 'accessible',\n this.accessibleByDefault() ? (this.accessible() ?? true) : this.accessible(),\n );\n write(\n 'accessibilityLabel',\n this.accessibilityLabel() ?? this.ariaLabel() ?? this.labelByDefault(),\n );\n write('accessibilityLabelledBy', this.accessibilityLabelledBy() ?? this.ariaLabelledBy());\n write('accessibilityHint', this.accessibilityHint());\n write(\n 'accessibilityRole',\n this.accessibilityRole() ?? this.role() ?? this.roleByDefault() ?? this.contributedRole(),\n );\n write('accessibilityState', this.mergedAccessibilityState());\n write('accessibilityValue', this.mergedAccessibilityValue());\n write('accessibilityActions', this.accessibilityActions());\n this.writeVisibility();\n }\n\n /** The half of accessibility that is about what assistive technology may see, and in which language. */\n private writeVisibility(): void {\n const write = (key: string, value: unknown) => this.engine.setProp(this.node, key, value);\n write('accessibilityLiveRegion', this.accessibilityLiveRegion() ?? this.ariaLive());\n write('accessibilityElementsHidden', this.accessibilityElementsHidden() ?? this.ariaHidden());\n write(\n 'importantForAccessibility',\n this.importantForAccessibility() ?? (this.ariaHidden() ? 'no-hide-descendants' : undefined),\n );\n write('accessibilityViewIsModal', this.accessibilityViewIsModal() ?? this.ariaModal());\n write('accessibilityIgnoresInvertColors', this.accessibilityIgnoresInvertColors());\n write('accessibilityLanguage', this.accessibilityLanguage());\n write('accessibilityLargeContentTitle', this.accessibilityLargeContentTitle());\n write('accessibilityShowsLargeContentViewer', this.accessibilityShowsLargeContentViewer());\n write('accessibilityRespondsToUserInteraction', this.accessibilityRespondsToUserInteraction());\n }\n\n /**\n * Writes a prop, and says nothing when it has nothing to say.\n *\n * The `undefined` guard is the whole of it, and it fixes a silent failure that had already been\n * hit twice. These two methods rewrite roughly forty props from this class's own inputs on every\n * `ngOnChanges`, so anything that reached the node by another route was overwritten the first\n * time any input changed. Two routes get here without going through an input of this class:\n *\n * - A host binding on the composing component. `ui-alert` sets `[accessible]` that way and\n * `ui-separator` sets `[accessibilityLabel]`; both are documented as working, and both were\n * one input change away from stopping.\n * - An element property binding. A component whose `hostDirectives` entry lists `disabled` but\n * not `nativeID` leaves `[nativeID]` to be applied as a plain property, and then a bound\n * `[disabled]` beside it clobbered the id on the next change. `ui-checkbox` carries a\n * per-component workaround for that, listing the identity inputs through explicitly, and\n * `ui-select-item` and `ui-dropdown-menu-item` do not - which is the shape of a bug that gets\n * copied rather than fixed.\n *\n * An input that goes back to `undefined` clears the prop only when this is what set it, so a\n * binding such as `[pointerEvents]=\"busy() ? 'none' : undefined\"` still switches off, and a\n * prop that arrived by one of those other routes is still never touched. Clearing a *class*\n * clears the style it brought, because that goes through the cascade rather than through here.\n */\n private writer(): (key: string, value: unknown) => void {\n return (key, value) => {\n if (value === undefined) {\n // Cleared only if this wrote it: `[pointerEvents]=\"busy() ? 'none' : undefined\"` has to\n // give the view its touches back, and a prop another route set is still left alone.\n if (this.written?.delete(key)) this.engine.setProp(this.node, key, null);\n return;\n }\n (this.written ??= new Set()).add(key);\n this.engine.setProp(this.node, key, value);\n };\n }\n\n /** The props `writer` has set from an input, so it can clear one when its input is unset. */\n private written: Set<string> | null = null;\n\n private writeIdentity(): void {\n const write = this.writer();\n write('nativeID', this.nativeID() ?? this.id());\n write('testID', this.testID());\n write('hitSlop', this.hitSlop());\n write('pointerEvents', this.pointerEvents());\n write('collapsable', this.collapsable());\n write('collapsableChildren', this.collapsableChildren());\n write('removeClippedSubviews', this.removeClippedSubviews());\n write('needsOffscreenAlphaCompositing', this.needsOffscreenAlphaCompositing());\n write('focusable', this.focusableByDefault() ? (this.focusable() ?? true) : this.focusable());\n write('shouldRasterizeIOS', this.shouldRasterizeIOS());\n write('renderToHardwareTextureAndroid', this.renderToHardwareTextureAndroid());\n write('nativeBackgroundAndroid', this.nativeBackgroundAndroid());\n write('nativeForegroundAndroid', this.nativeForegroundAndroid());\n }\n\n /**\n * The defaults a React Native wrapper would have applied, written once when the element is\n * created. `ngOnChanges` writes them again whenever an input changes, so an app that later\n * clears a prop falls back to the default rather than to nothing.\n */\n /**\n * The defaults a React Native wrapper would have applied, for an element nothing was bound on.\n *\n * In `ngOnInit` rather than the constructor because a hook like `accessibleByDefault` is\n * answered from the subclass's own inputs - `Text` asks whether it is pressable - and those\n * fields do not exist yet while the base constructor runs. Each is guarded on its input being\n * unset, because `ngOnChanges` has already run by now and its answer, which merges the default\n * in, is the better one.\n */\n ngOnInit(): void {\n this.initialised = true;\n // A directive with nothing bound to it never sees `ngOnChanges`, so an element that carries a\n // primitive and no bindings would never have its role or state written at all. Cheap to ask,\n // and the answer is no for every element in an app that uses none.\n if (this.contributions.length > 0) this.writeAccessibility();\n if (this.accessible() === undefined && this.accessibleByDefault()) {\n this.engine.setProp(this.node, 'accessible', true);\n }\n if (this.focusable() === undefined && this.focusableByDefault()) {\n this.engine.setProp(this.node, 'focusable', true);\n }\n if (this.accessibilityRole() === undefined && this.role() === undefined) {\n const role = this.roleByDefault();\n if (role) this.engine.setProp(this.node, 'accessibilityRole', role);\n }\n if (this.accessibilityLabel() === undefined && this.ariaLabel() === undefined) {\n const label = this.labelByDefault();\n if (label !== undefined) this.engine.setProp(this.node, 'accessibilityLabel', label);\n }\n }\n\n /** The first role any directive on this node claims. Two claiming different ones is a bug. */\n private contributedRole(): AccessibilityRole | undefined {\n for (const contribution of this.contributions) {\n if (contribution.role) return contribution.role;\n }\n return undefined;\n }\n\n /** A label the component itself can supply, as `Image` does from `alt`. */\n protected labelByDefault(): string | undefined {\n return undefined;\n }\n\n /**\n * The merged state, for a component whose own inputs feed it - `disabled` on a pressable or a\n * switch, which is a signal of theirs and so cannot reach `ngOnChanges` here.\n *\n * Those components bind this from their host. It returns the *same object* when nothing has\n * changed, which is what keeps a host binding from marking the node dirty on every pass.\n */\n protected accessibilityStateProp(): AccessibilityState | undefined {\n return this.mergedAccessibilityState();\n }\n\n private lastAccessibilityState: AccessibilityState | undefined;\n\n /** Whether anything could put state on this node. For nearly every node on screen, no. */\n private hasState(): boolean {\n return (\n this.accessibilityState() !== undefined ||\n this.ariaBusy() !== undefined ||\n this.ariaChecked() !== undefined ||\n this.ariaDisabled() !== undefined ||\n this.ariaExpanded() !== undefined ||\n this.ariaSelected() !== undefined ||\n !!this.disabledForAccessibility() ||\n this.checkedForAccessibility() !== undefined ||\n this.contributions.length > 0\n );\n }\n\n private mergedAccessibilityState(): AccessibilityState | undefined {\n // Answered without allocating in the common case: this runs from a host binding on every\n // control, on every pass, and most of them have no state to announce.\n if (!this.hasState()) return (this.lastAccessibilityState = undefined);\n const explicit = this.accessibilityState();\n const merged: Record<string, unknown> = { ...explicit };\n const set = (key: keyof AccessibilityState, value: unknown) => {\n if (value !== undefined) merged[key] = value;\n };\n set('disabled', this.disabledForAccessibility() || undefined);\n set('checked', this.checkedForAccessibility());\n set('busy', this.ariaBusy());\n set('checked', this.ariaChecked());\n set('disabled', this.ariaDisabled());\n set('expanded', this.ariaExpanded());\n set('selected', this.ariaSelected());\n for (const contribution of this.contributions) {\n const state = contribution.accessibilityState?.();\n for (const key of Object.keys(state ?? {})) {\n set(key as keyof AccessibilityState, (state as Record<string, unknown>)[key]);\n }\n }\n const state = Object.keys(merged).length ? (merged as AccessibilityState) : explicit;\n const last = this.lastAccessibilityState;\n if (last && state && sameState(last, state)) return last;\n return (this.lastAccessibilityState = state);\n }\n\n private mergedAccessibilityValue(): AccessibilityValue | undefined {\n const explicit = this.accessibilityValue();\n const merged: Record<string, unknown> = { ...explicit };\n const set = (key: keyof AccessibilityValue, value: unknown) => {\n if (value !== undefined) merged[key] = value;\n };\n set('min', this.ariaValueMin());\n set('max', this.ariaValueMax());\n set('now', this.ariaValueNow());\n set('text', this.ariaValueText());\n return Object.keys(merged).length ? (merged as AccessibilityValue) : explicit;\n }\n}\n\n/**\n * `ViewBase` on its own, for a component whose host is a plain view.\n *\n * No selector: this is only ever a `hostDirectives` entry, and it is the counterpart to\n * `PressBehavior` for the parts of a control that do not take a touch. A radio group is the case\n * that asked for it - it announces itself as a group and holds a value, but pressing it means\n * nothing, and without a `ViewBase` on the node there is nothing to write that role.\n */\n@Directive({})\nexport class ViewBehavior extends ViewBase {}\n"]}
|
|
1
|
+
{"version":3,"file":"view-base.js","sourceRoot":"","sources":["../src/view-base.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The props every native view accepts, as typed inputs forwarded to the host node.\n *\n * Each input is mirrored by a host binding of the same name, which is what carries the value to\n * the renderer: once a directive declares an input, Angular routes the binding to the directive\n * rather than the element. An unset input stays `undefined` and never reaches native, so a view\n * that mentions none of these sends none of them.\n *\n * Web-style `aria-*` names are accepted as aliases and land on the `accessibility*` props React\n * Native's own `View.js` maps them to. `id` maps to `nativeID` and `tabIndex` to `focusable` the\n * same way.\n *\n * Events are element events, typed in `events.ts`: `(layout)`, `(touchStart)`,\n * `(accessibilityAction)` and so on. They are deliberately not outputs; see that file.\n */\nimport { Directive, ElementRef, type SimpleChanges, inject, input } from '@angular/core';\nimport { HostEngine, claimHost, declareNativeProps, type HostNode } from '@ng-native/fabric';\nimport type { Insets } from './events.ts';\nimport { optionalBoolean, optionalNumber } from './transforms.ts';\nimport { WRITTEN_PROPS } from './written-props.ts';\n\n/** The roles assistive technologies understand. `Role` is the web spelling of the same set. */\nexport type AccessibilityRole =\n | 'none'\n | 'button'\n | 'togglebutton'\n | 'link'\n | 'search'\n | 'image'\n | 'keyboardkey'\n | 'text'\n | 'adjustable'\n | 'imagebutton'\n | 'header'\n | 'summary'\n | 'alert'\n | 'checkbox'\n | 'combobox'\n | 'menu'\n | 'menubar'\n | 'menuitem'\n | 'progressbar'\n | 'radio'\n | 'radiogroup'\n | 'scrollbar'\n | 'spinbutton'\n | 'switch'\n | 'tab'\n | 'tabbar'\n | 'tablist'\n | 'timer'\n | 'list'\n | 'toolbar'\n | 'grid'\n | 'pager'\n | 'scrollview'\n | 'horizontalscrollview'\n | 'viewgroup'\n | 'webview'\n | 'drawerlayout'\n | 'slidingdrawer'\n | 'iconmenu';\n\nexport interface AccessibilityState {\n readonly disabled?: boolean;\n readonly selected?: boolean;\n readonly checked?: boolean | 'mixed';\n readonly busy?: boolean;\n readonly expanded?: boolean;\n}\n\nexport interface AccessibilityValue {\n readonly min?: number;\n readonly max?: number;\n readonly now?: number;\n readonly text?: string;\n}\n\nexport interface AccessibilityAction {\n readonly name: string;\n readonly label?: string;\n}\n\n/** Android's `nativeBackgroundAndroid` and `nativeForegroundAndroid`. */\nexport type AndroidDrawable =\n | {\n readonly type: 'RippleAndroid';\n readonly color?: string | number;\n readonly borderless?: boolean;\n readonly rippleRadius?: number;\n }\n | { readonly type: 'ThemeAttrAndroid'; readonly attribute: string };\n\nexport type PointerEvents = 'box-none' | 'none' | 'box-only' | 'auto';\nexport type ImportantForAccessibility = 'auto' | 'yes' | 'no' | 'no-hide-descendants';\nexport type AccessibilityLiveRegion = 'none' | 'polite' | 'assertive';\n\n/**\n * Angular writes a static attribute to the element as well as feeding it to the input of the\n * same name, so `<switch thumbColor=\"#fff\">` leaves a stray `thumbColor` prop on the node next to\n * the `thumbTintColor` the input produces. The inputs of the directive are what consumed them,\n * so those names come off the node; a host binding puts back any that native does read.\n *\n * Walking the *node's* props rather than the directive's inputs is not a detail. This runs for\n * every element on screen, a primitive declares some forty-five inputs, and at this point the node\n * usually has no props at all - bindings have not run yet, so only static attributes are there.\n * The other way round it was forty-five `delete`s per element on an object that had none of them,\n * which is both wasted work and the way to push an object into dictionary mode.\n */\n/** Shallow equality, so a re-merged state that says the same thing keeps its identity. */\nfunction sameState(a: AccessibilityState, b: AccessibilityState): boolean {\n const keys = Object.keys(a) as (keyof AccessibilityState)[];\n return keys.length === Object.keys(b).length && keys.every((key) => a[key] === b[key]);\n}\n\n/** The host primitives whose props have been declared to the engine. */\nconst declared = new WeakSet<object>();\n\n/**\n * Tell the engine the props this primitive's native view takes, once per component class: its\n * inputs by their public names, and `WRITTEN_PROPS`. What its check for a misspelt prop reads.\n */\nfunction declareProps(ctor: unknown, node: HostNode): void {\n if (declared.has(ctor as object)) return;\n declared.add(ctor as object);\n const def =\n (ctor as { ɵcmp?: { inputs?: object }; ɵdir?: { inputs?: object } }).ɵcmp ??\n (ctor as { ɵdir?: { inputs?: object } }).ɵdir;\n const name = (node as { name?: string }).name;\n if (!name || !def?.inputs) return;\n declareNativeProps(name, [...Object.keys(def.inputs), ...WRITTEN_PROPS]);\n}\n\nfunction stripConsumedAttributes(ctor: unknown, node: HostNode): void {\n // A directive with no selector is only ever a `hostDirectives` entry, which exposes the inputs\n // it lists and no others, so an attribute of the same name as the rest was not consumed.\n type Def = { inputs?: Record<string, unknown>; selectors?: readonly unknown[] };\n const { ɵcmp, ɵdir } = ctor as { ɵcmp?: Def; ɵdir?: Def };\n const def = ɵcmp ?? (ɵdir?.selectors?.length ? ɵdir : undefined);\n const inputs = def?.inputs;\n if (!inputs) return;\n // A host that has not put a bag on the node yet has no attributes to take off it. Read\n // unconditionally, this threw `Cannot convert undefined or null to object` on the first\n // component a browser host ever mounted, before anything rendered - which is a hard crash\n // standing between this package and a second platform, for a loop with nothing to do.\n const props = node.props as Record<string, unknown> | undefined;\n if (!props) return;\n for (const name of Object.keys(props)) {\n if (name in inputs) delete props[name];\n }\n}\n\n/**\n * What a directive on the same node says this view *is*, for a screen reader.\n *\n * A host primitive knows it is a view; only the thing composed onto it knows it is a button, a\n * checkbox or an accordion trigger. Without this seam that knowledge has nowhere to go: the role\n * and the state are written here, from this class's own inputs, and a later `ngOnChanges` would\n * overwrite anything a directive had set behind its back.\n *\n * Registered on the element with `contributeAccessibility`, and several primitives may contribute\n * to one element - a trigger that is also a button.\n */\nexport interface AccessibilityContribution {\n /** The role, if this directive implies one. An explicit `role` on the element still wins. */\n readonly role?: AccessibilityRole;\n /**\n * State to merge in, read on every write so it may be a signal read.\n *\n * Spelled in full because `state` is what a primitive calls the thing it publishes for a\n * stylesheet - `data-state=\"checked\"` - and the two are not the same thing.\n */\n readonly accessibilityState?: () => AccessibilityState | undefined;\n}\n\n/** Where an element's contributions are kept: on the node, and only on a node that has some. */\nconst CONTRIBUTIONS = Symbol('angular-native.accessibilityContributions');\ntype Contributed = HostNode & { [CONTRIBUTIONS]?: AccessibilityContribution[] };\nconst NO_CONTRIBUTIONS: readonly AccessibilityContribution[] = [];\n\n/**\n * Tell the primitive on this element what it is, for a screen reader: a role, and state to merge\n * into what it announces. Call it from a directive's field initialiser or constructor, on the\n * element the primitive is on:\n *\n * private readonly contribution = contributeAccessibility({ role: 'button' });\n * private readonly contribution = contributeAccessibility(this);\n *\n * Kept on the node rather than provided through DI, because asking the injector costs every\n * element on screen a lookup to learn that nothing contributes - about a tenth of creating a list.\n * Reading a property that is not there costs nothing.\n */\nexport function contributeAccessibility<T extends AccessibilityContribution>(contribution: T): T {\n const node = inject(ElementRef).nativeElement as Contributed;\n (node[CONTRIBUTIONS] ??= []).push(contribution);\n return contribution;\n}\n\n@Directive()\nexport abstract class ViewBase {\n /** The retained node this directive sits on. */\n protected readonly node = inject(ElementRef).nativeElement as HostNode;\n\n /**\n * The engine, because the props these inputs carry are written straight onto the node. Read\n * off the node where the host put it there, which is one property read against an injector\n * lookup that walks every ancestor element, for every element on screen.\n */\n protected readonly engine: HostEngine = this.node.host ?? inject(HostEngine);\n\n /**\n * See `contributeAccessibility`. Empty for every element nothing is composed onto. Read, never\n * cached, from `ngOnInit` onwards: by then every directive on the node has been constructed and\n * registered what it has to say.\n */\n private get contributions(): readonly AccessibilityContribution[] {\n return (this.node as Contributed)[CONTRIBUTIONS] ?? NO_CONTRIBUTIONS;\n }\n\n constructor() {\n claimHost(this.node);\n stripConsumedAttributes(this.constructor, this.node);\n declareProps(this.constructor, this.node);\n this.engine.settle(this);\n }\n\n /** Whether `ngOnInit` has run, which is what writes the props every element starts with. */\n private initialised = false;\n\n /**\n * Write what the inputs say, for an element whose view has not been checked by the time the\n * host commits it. Nothing for one that has.\n *\n * The props are written from `ngOnChanges` and `ngOnInit`, which Angular runs in the parent\n * view's update pass. A component that detaches itself before its first check never gets one,\n * and on the web that pattern still works, because a listener and an attribute are there from\n * creation. So the host calls this before the commit that first mounts the element, by when its\n * static inputs are set: the press handling, the role and the `testID` are there, and the view\n * behaves as written once something calls `detectChanges()`.\n */\n settleProps(): void {\n if (this.initialised) return;\n this.ngOnChanges({});\n this.ngOnInit();\n }\n\n // --- accessibility ---------------------------------------------------------------------\n\n /** Whether the view is an accessibility element. Defaults to false for a plain view. */\n readonly accessible = input<boolean>(undefined, { transform: optionalBoolean });\n /** What a screen reader announces for the view. */\n readonly accessibilityLabel = input<string>();\n /** `aria-label`: web spelling of `accessibilityLabel`. */\n readonly ariaLabel = input<string>(undefined, { alias: 'aria-label' });\n /** Android: `nativeID`s of the views that label this one. */\n readonly accessibilityLabelledBy = input<string | readonly string[]>();\n /** `aria-labelledby`: web spelling of `accessibilityLabelledBy`. */\n readonly ariaLabelledBy = input<string | readonly string[]>(undefined, {\n alias: 'aria-labelledby',\n });\n /** What happens when the user acts on the view, when the label alone does not say. */\n readonly accessibilityHint = input<string>();\n /** The kind of control this is, for assistive technologies. */\n readonly accessibilityRole = input<AccessibilityRole>();\n /** `role`: the web spelling of `accessibilityRole`. */\n readonly role = input<AccessibilityRole>();\n /** Disabled, selected, checked, busy and expanded, as one object. */\n readonly accessibilityState = input<AccessibilityState>();\n /** `aria-busy`. */\n readonly ariaBusy = input<boolean>(undefined, { alias: 'aria-busy', transform: optionalBoolean });\n /** `aria-checked`. */\n readonly ariaChecked = input<boolean | 'mixed'>(undefined, { alias: 'aria-checked' });\n /** `aria-disabled`. */\n readonly ariaDisabled = input<boolean>(undefined, {\n alias: 'aria-disabled',\n transform: optionalBoolean,\n });\n /** `aria-expanded`. */\n readonly ariaExpanded = input<boolean>(undefined, {\n alias: 'aria-expanded',\n transform: optionalBoolean,\n });\n /** `aria-selected`. */\n readonly ariaSelected = input<boolean>(undefined, {\n alias: 'aria-selected',\n transform: optionalBoolean,\n });\n /** The current value of an adjustable control, for a screen reader. */\n readonly accessibilityValue = input<AccessibilityValue>();\n /** `aria-valuemin`. */\n readonly ariaValueMin = input<number>(undefined, {\n alias: 'aria-valuemin',\n transform: optionalNumber,\n });\n /** `aria-valuemax`. */\n readonly ariaValueMax = input<number>(undefined, {\n alias: 'aria-valuemax',\n transform: optionalNumber,\n });\n /** `aria-valuenow`. */\n readonly ariaValueNow = input<number>(undefined, {\n alias: 'aria-valuenow',\n transform: optionalNumber,\n });\n /** `aria-valuetext`. */\n readonly ariaValueText = input<string>(undefined, { alias: 'aria-valuetext' });\n /** Custom actions a screen reader can invoke; each arrives as `(accessibilityAction)`. */\n readonly accessibilityActions = input<readonly AccessibilityAction[]>();\n /** Android: announce changes to this view's content without focus moving to it. */\n readonly accessibilityLiveRegion = input<AccessibilityLiveRegion>();\n /** `aria-live`. */\n readonly ariaLive = input<AccessibilityLiveRegion>(undefined, { alias: 'aria-live' });\n /** iOS: hide this view and its children from assistive technologies. */\n readonly accessibilityElementsHidden = input<boolean>(undefined, { transform: optionalBoolean });\n /** `aria-hidden`: `accessibilityElementsHidden` on iOS, `no-hide-descendants` on Android. */\n readonly ariaHidden = input<boolean>(undefined, {\n alias: 'aria-hidden',\n transform: optionalBoolean,\n });\n /** Android: whether this view is exposed to accessibility, and whether its children are. */\n readonly importantForAccessibility = input<ImportantForAccessibility>();\n /** iOS: VoiceOver ignores every sibling while this view is shown, as a modal expects. */\n readonly accessibilityViewIsModal = input<boolean>(undefined, { transform: optionalBoolean });\n /** `aria-modal`. */\n readonly ariaModal = input<boolean>(undefined, {\n alias: 'aria-modal',\n transform: optionalBoolean,\n });\n /** iOS: keep the view's colours when the Invert Colors setting is on; images want this. */\n readonly accessibilityIgnoresInvertColors = input<boolean>(undefined, {\n transform: optionalBoolean,\n });\n /** iOS: the language VoiceOver reads the label in, as a BCP 47 tag. */\n readonly accessibilityLanguage = input<string>();\n /** iOS: the title shown by the Large Content Viewer on a long press with large text on. */\n readonly accessibilityLargeContentTitle = input<string>();\n /** iOS: opt this view into the Large Content Viewer. */\n readonly accessibilityShowsLargeContentViewer = input<boolean>(undefined, {\n transform: optionalBoolean,\n });\n /** iOS: tell VoiceOver the view responds to a tap even without a role that implies it. */\n readonly accessibilityRespondsToUserInteraction = input<boolean>(undefined, {\n transform: optionalBoolean,\n });\n\n // --- identity and hit testing ----------------------------------------------------------\n\n /** A handle native code can find the view by; also what `:id` selectors match. */\n readonly nativeID = input<string>();\n /** `id`: the web spelling of `nativeID`. */\n readonly id = input<string>();\n /** A handle for end-to-end test tooling. */\n readonly testID = input<string>();\n /** Extend the touchable area beyond the view's bounds, without moving anything visible. */\n readonly hitSlop = input<Insets | number>();\n /** Whether this view, its children, or neither can be the target of a touch. */\n readonly pointerEvents = input<PointerEvents>();\n /** Set to false to keep a layout-only view alive; Fabric otherwise removes it from the tree. */\n readonly collapsable = input<boolean>(undefined, { transform: optionalBoolean });\n /** Set to false to keep this view's layout-only children from being flattened. */\n readonly collapsableChildren = input<boolean>(undefined, { transform: optionalBoolean });\n /** Detach children that are outside the visible bounds. A scroll view optimisation. */\n readonly removeClippedSubviews = input<boolean>(undefined, { transform: optionalBoolean });\n /** Composite the view offscreen so a translucent view with children blends correctly. */\n readonly needsOffscreenAlphaCompositing = input<boolean>(undefined, {\n transform: optionalBoolean,\n });\n /** Android: whether the view takes keyboard or TV focus. RN's `tabIndex` is this. */\n readonly focusable = input<boolean>(undefined, { transform: optionalBoolean });\n /** iOS: render the view to a bitmap once and reuse it; for a static view that animates. */\n readonly shouldRasterizeIOS = input<boolean>(undefined, { transform: optionalBoolean });\n /** Android: cache the view in a hardware texture; the same trade as `shouldRasterizeIOS`. */\n readonly renderToHardwareTextureAndroid = input<boolean>(undefined, {\n transform: optionalBoolean,\n });\n /** Android: a ripple or theme drawable painted behind the view's content. */\n readonly nativeBackgroundAndroid = input<AndroidDrawable>();\n /** Android: a ripple or theme drawable painted over the view's content. */\n readonly nativeForegroundAndroid = input<AndroidDrawable>();\n\n // --- merged views of the aliases ------------------------------------------------------\n\n /**\n * What React Native's own JavaScript wrapper would have defaulted, per component.\n *\n * Driving the native views directly skips those wrappers, and what is lost is invisible: the\n * app looks identical and is unusable with a screen reader, because nothing on it is an\n * accessibility element. Each hook is overridden by the component whose wrapper sets it, and\n * cites the file it came from.\n */\n\n /** True for anything that behaves like a control. `Pressable.js`: `accessible !== false`. */\n protected accessibleByDefault(): boolean {\n return false;\n }\n\n /** Whether the platform's focus order should include this. `Pressable.js` again. */\n protected focusableByDefault(): boolean {\n return false;\n }\n\n /** A role the component itself implies. `Switch.js`: `accessibilityRole ?? 'switch'`. */\n protected roleByDefault(): AccessibilityRole | undefined {\n return undefined;\n }\n\n /**\n * The component's own `disabled`, for the state a screen reader announces.\n *\n * React Native merges this whenever the prop was passed, even as false. An input here always\n * has a value, so there is no telling \"passed false\" from \"not passed\"; only true is merged,\n * and a control that is not disabled says nothing rather than saying so on every node.\n */\n protected disabledForAccessibility(): boolean | undefined {\n return undefined;\n }\n\n /**\n * The component's own `checked`, for a control whose checked state is not an accessibility\n * input at all - `Switch`'s `checked` is a `model()`, not one of this class's inputs, so it\n * cannot reach `ngOnChanges` here any more than `disabled` can.\n */\n protected checkedForAccessibility(): boolean | 'mixed' | undefined {\n return undefined;\n }\n\n /**\n * Write what the inputs say onto the node.\n *\n * This is what thirty host bindings used to do, and it is here rather than there for a reason\n * that was measured: a host binding costs every element that carries it, on every pass, whether\n * or not the app ever set the prop, and mounting four hundred rows spent a third of its time on\n * the accessibility surface alone. Angular calls this once with everything that changed instead.\n *\n * It works with signal inputs, which is easy to assume it does not: `ngOnChanges` fires for\n * them as it does for any other input, because `ngOnChangesSetInput` records a `SimpleChange`\n * before writing the signal. `signal-onchanges.test.ts` is there to keep that fact honest.\n *\n * What remains is the allocation - a signal input builds its node whether or not anything binds\n * to it, and there are forty-six here. Moving prop groups into directives selected by the props\n * they carry (`[accessibilityLabel], [aria-label], ...`) is how that goes away: an element that\n * binds none of them would allocate nothing. Measured on a 400-row mount it is worth about 40ms,\n * at the price of an import per group.\n */\n ngOnChanges(_changes?: SimpleChanges): void {\n this.writeAccessibility();\n this.writeIdentity();\n }\n\n private writeAccessibility(): void {\n const write = this.writer();\n write(\n 'accessible',\n this.accessibleByDefault() ? (this.accessible() ?? true) : this.accessible(),\n );\n write(\n 'accessibilityLabel',\n this.accessibilityLabel() ?? this.ariaLabel() ?? this.labelByDefault(),\n );\n write('accessibilityLabelledBy', this.accessibilityLabelledBy() ?? this.ariaLabelledBy());\n write('accessibilityHint', this.accessibilityHint());\n write(\n 'accessibilityRole',\n this.accessibilityRole() ?? this.role() ?? this.roleByDefault() ?? this.contributedRole(),\n );\n write('accessibilityState', this.mergedAccessibilityState());\n write('accessibilityValue', this.mergedAccessibilityValue());\n write('accessibilityActions', this.accessibilityActions());\n this.writeVisibility();\n this.publishAriaState(write);\n }\n\n /**\n * The aria states Tailwind has variants for, put back on the node as the attributes they came\n * in as. The inputs consume them, so `[aria-disabled=\"true\"]` and every `aria-*:` utility had\n * nothing to match. Hyphenated, so the engine keeps them for selectors and never sends them.\n */\n private publishAriaState(write: (key: string, value: unknown) => void): void {\n const attribute = (value: unknown) => (value === undefined ? undefined : String(value));\n write('aria-busy', attribute(this.ariaBusy()));\n write('aria-checked', attribute(this.ariaChecked()));\n write('aria-disabled', attribute(this.ariaDisabled()));\n write('aria-expanded', attribute(this.ariaExpanded()));\n write('aria-hidden', attribute(this.ariaHidden()));\n write('aria-selected', attribute(this.ariaSelected()));\n }\n\n /** The half of accessibility that is about what assistive technology may see, and in which language. */\n private writeVisibility(): void {\n const write = (key: string, value: unknown) => this.engine.setProp(this.node, key, value);\n write('accessibilityLiveRegion', this.accessibilityLiveRegion() ?? this.ariaLive());\n write('accessibilityElementsHidden', this.accessibilityElementsHidden() ?? this.ariaHidden());\n write(\n 'importantForAccessibility',\n this.importantForAccessibility() ?? (this.ariaHidden() ? 'no-hide-descendants' : undefined),\n );\n write('accessibilityViewIsModal', this.accessibilityViewIsModal() ?? this.ariaModal());\n write('accessibilityIgnoresInvertColors', this.accessibilityIgnoresInvertColors());\n write('accessibilityLanguage', this.accessibilityLanguage());\n write('accessibilityLargeContentTitle', this.accessibilityLargeContentTitle());\n write('accessibilityShowsLargeContentViewer', this.accessibilityShowsLargeContentViewer());\n write('accessibilityRespondsToUserInteraction', this.accessibilityRespondsToUserInteraction());\n }\n\n /**\n * Writes a prop, and says nothing when it has nothing to say.\n *\n * The `undefined` guard is the whole of it, and it fixes a silent failure that had already been\n * hit twice. These two methods rewrite roughly forty props from this class's own inputs on every\n * `ngOnChanges`, so anything that reached the node by another route was overwritten the first\n * time any input changed. Two routes get here without going through an input of this class:\n *\n * - A host binding on the composing component. `ui-alert` sets `[accessible]` that way and\n * `ui-separator` sets `[accessibilityLabel]`; both are documented as working, and both were\n * one input change away from stopping.\n * - An element property binding. A component whose `hostDirectives` entry lists `disabled` but\n * not `nativeID` leaves `[nativeID]` to be applied as a plain property, and then a bound\n * `[disabled]` beside it clobbered the id on the next change. `ui-checkbox` carries a\n * per-component workaround for that, listing the identity inputs through explicitly, and\n * `ui-select-item` and `ui-dropdown-menu-item` do not - which is the shape of a bug that gets\n * copied rather than fixed.\n *\n * An input that goes back to `undefined` clears the prop only when this is what set it, so a\n * binding such as `[pointerEvents]=\"busy() ? 'none' : undefined\"` still switches off, and a\n * prop that arrived by one of those other routes is still never touched. Clearing a *class*\n * clears the style it brought, because that goes through the cascade rather than through here.\n */\n private writer(): (key: string, value: unknown) => void {\n return (key, value) => {\n if (value === undefined) {\n // Cleared only if this wrote it: `[pointerEvents]=\"busy() ? 'none' : undefined\"` has to\n // give the view its touches back, and a prop another route set is still left alone.\n if (this.written?.delete(key)) this.engine.setProp(this.node, key, null);\n return;\n }\n (this.written ??= new Set()).add(key);\n this.engine.setProp(this.node, key, value);\n };\n }\n\n /** The props `writer` has set from an input, so it can clear one when its input is unset. */\n private written: Set<string> | null = null;\n\n private writeIdentity(): void {\n const write = this.writer();\n write('nativeID', this.nativeID() ?? this.id());\n write('testID', this.testID());\n write('hitSlop', this.hitSlop());\n write('pointerEvents', this.pointerEvents());\n write('collapsable', this.collapsable());\n write('collapsableChildren', this.collapsableChildren());\n write('removeClippedSubviews', this.removeClippedSubviews());\n write('needsOffscreenAlphaCompositing', this.needsOffscreenAlphaCompositing());\n write('focusable', this.focusableByDefault() ? (this.focusable() ?? true) : this.focusable());\n write('shouldRasterizeIOS', this.shouldRasterizeIOS());\n write('renderToHardwareTextureAndroid', this.renderToHardwareTextureAndroid());\n write('nativeBackgroundAndroid', this.nativeBackgroundAndroid());\n write('nativeForegroundAndroid', this.nativeForegroundAndroid());\n }\n\n /**\n * The defaults a React Native wrapper would have applied, written once when the element is\n * created. `ngOnChanges` writes them again whenever an input changes, so an app that later\n * clears a prop falls back to the default rather than to nothing.\n */\n /**\n * The defaults a React Native wrapper would have applied, for an element nothing was bound on.\n *\n * In `ngOnInit` rather than the constructor because a hook like `accessibleByDefault` is\n * answered from the subclass's own inputs - `Text` asks whether it is pressable - and those\n * fields do not exist yet while the base constructor runs. Each is guarded on its input being\n * unset, because `ngOnChanges` has already run by now and its answer, which merges the default\n * in, is the better one.\n */\n ngOnInit(): void {\n this.initialised = true;\n // A directive with nothing bound to it never sees `ngOnChanges`, so an element that carries a\n // primitive and no bindings would never have its role or state written at all. Cheap to ask,\n // and the answer is no for every element in an app that uses none.\n if (this.contributions.length > 0) this.writeAccessibility();\n if (this.accessible() === undefined && this.accessibleByDefault()) {\n this.engine.setProp(this.node, 'accessible', true);\n }\n if (this.focusable() === undefined && this.focusableByDefault()) {\n this.engine.setProp(this.node, 'focusable', true);\n }\n if (this.accessibilityRole() === undefined && this.role() === undefined) {\n const role = this.roleByDefault();\n if (role) this.engine.setProp(this.node, 'accessibilityRole', role);\n }\n if (this.accessibilityLabel() === undefined && this.ariaLabel() === undefined) {\n const label = this.labelByDefault();\n if (label !== undefined) this.engine.setProp(this.node, 'accessibilityLabel', label);\n }\n }\n\n /** The first role any directive on this node claims. Two claiming different ones is a bug. */\n private contributedRole(): AccessibilityRole | undefined {\n for (const contribution of this.contributions) {\n if (contribution.role) return contribution.role;\n }\n return undefined;\n }\n\n /** A label the component itself can supply, as `Image` does from `alt`. */\n protected labelByDefault(): string | undefined {\n return undefined;\n }\n\n /**\n * The merged state, for a component whose own inputs feed it - `disabled` on a pressable or a\n * switch, which is a signal of theirs and so cannot reach `ngOnChanges` here.\n *\n * Those components bind this from their host. It returns the *same object* when nothing has\n * changed, which is what keeps a host binding from marking the node dirty on every pass.\n */\n protected accessibilityStateProp(): AccessibilityState | undefined {\n return this.mergedAccessibilityState();\n }\n\n private lastAccessibilityState: AccessibilityState | undefined;\n\n /** Whether anything could put state on this node. For nearly every node on screen, no. */\n private hasState(): boolean {\n return (\n this.accessibilityState() !== undefined ||\n this.ariaBusy() !== undefined ||\n this.ariaChecked() !== undefined ||\n this.ariaDisabled() !== undefined ||\n this.ariaExpanded() !== undefined ||\n this.ariaSelected() !== undefined ||\n !!this.disabledForAccessibility() ||\n this.checkedForAccessibility() !== undefined ||\n this.contributions.length > 0\n );\n }\n\n private mergedAccessibilityState(): AccessibilityState | undefined {\n // Answered without allocating in the common case: this runs from a host binding on every\n // control, on every pass, and most of them have no state to announce.\n if (!this.hasState()) return (this.lastAccessibilityState = undefined);\n const explicit = this.accessibilityState();\n const merged: Record<string, unknown> = { ...explicit };\n const set = (key: keyof AccessibilityState, value: unknown) => {\n if (value !== undefined) merged[key] = value;\n };\n set('disabled', this.disabledForAccessibility() || undefined);\n set('checked', this.checkedForAccessibility());\n set('busy', this.ariaBusy());\n set('checked', this.ariaChecked());\n set('disabled', this.ariaDisabled());\n set('expanded', this.ariaExpanded());\n set('selected', this.ariaSelected());\n for (const contribution of this.contributions) {\n const state = contribution.accessibilityState?.();\n for (const key of Object.keys(state ?? {})) {\n set(key as keyof AccessibilityState, (state as Record<string, unknown>)[key]);\n }\n }\n const state = Object.keys(merged).length ? (merged as AccessibilityState) : explicit;\n const last = this.lastAccessibilityState;\n if (last && state && sameState(last, state)) return last;\n return (this.lastAccessibilityState = state);\n }\n\n private mergedAccessibilityValue(): AccessibilityValue | undefined {\n const explicit = this.accessibilityValue();\n const merged: Record<string, unknown> = { ...explicit };\n const set = (key: keyof AccessibilityValue, value: unknown) => {\n if (value !== undefined) merged[key] = value;\n };\n set('min', this.ariaValueMin());\n set('max', this.ariaValueMax());\n set('now', this.ariaValueNow());\n set('text', this.ariaValueText());\n return Object.keys(merged).length ? (merged as AccessibilityValue) : explicit;\n }\n}\n\n/**\n * `ViewBase` on its own, for a component whose host is a plain view.\n *\n * No selector: this is only ever a `hostDirectives` entry, and it is the counterpart to\n * `PressBehavior` for the parts of a control that do not take a touch. A radio group is the case\n * that asked for it - it announces itself as a group and holds a value, but pressing it means\n * nothing, and without a `ViewBase` on the node there is nothing to write that role.\n */\n@Directive({})\nexport class ViewBehavior extends ViewBase {}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ng-native/components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Angular Native's core components: view, text, image, pressable, scroll-view, virtual-list, text-input and the rest of React Native's set.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"access": "public"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@ng-native/
|
|
43
|
-
"@ng-native/
|
|
42
|
+
"@ng-native/device": "0.2.0",
|
|
43
|
+
"@ng-native/fabric": "0.2.0"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"@angular/core": "^22.0.0",
|