@ng-native/components 0.0.1 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +78 -1
  3. package/dist/activity-indicator.d.ts +41 -0
  4. package/dist/activity-indicator.js +66 -0
  5. package/dist/activity-indicator.js.map +1 -0
  6. package/dist/animated-style.d.ts +31 -0
  7. package/dist/animated-style.js +102 -0
  8. package/dist/animated-style.js.map +1 -0
  9. package/dist/animated.d.ts +125 -0
  10. package/dist/animated.js +538 -0
  11. package/dist/animated.js.map +1 -0
  12. package/dist/animation.d.ts +40 -0
  13. package/dist/animation.js +20 -0
  14. package/dist/animation.js.map +1 -0
  15. package/dist/animations-web.d.ts +8 -0
  16. package/dist/animations-web.js +31 -0
  17. package/dist/animations-web.js.map +1 -0
  18. package/dist/animations.d.ts +7 -0
  19. package/dist/animations.js +58 -0
  20. package/dist/animations.js.map +1 -0
  21. package/dist/controlled-model.d.ts +33 -0
  22. package/dist/controlled-model.js +47 -0
  23. package/dist/controlled-model.js.map +1 -0
  24. package/dist/easing.d.ts +21 -0
  25. package/dist/easing.js +50 -0
  26. package/dist/easing.js.map +1 -0
  27. package/dist/events.d.ts +169 -0
  28. package/dist/events.js +2 -0
  29. package/dist/events.js.map +1 -0
  30. package/dist/gesture-backend.d.ts +26 -0
  31. package/dist/gesture-backend.js +14 -0
  32. package/dist/gesture-backend.js.map +1 -0
  33. package/dist/gesture-dispatch.d.ts +67 -0
  34. package/dist/gesture-dispatch.js +106 -0
  35. package/dist/gesture-dispatch.js.map +1 -0
  36. package/dist/gestures.d.ts +23 -0
  37. package/dist/gestures.js +164 -0
  38. package/dist/gestures.js.map +1 -0
  39. package/dist/height-index.d.ts +31 -0
  40. package/dist/height-index.js +80 -0
  41. package/dist/height-index.js.map +1 -0
  42. package/dist/image-background.d.ts +32 -0
  43. package/dist/image-background.js +80 -0
  44. package/dist/image-background.js.map +1 -0
  45. package/dist/image.d.ts +79 -0
  46. package/dist/image.js +155 -0
  47. package/dist/image.js.map +1 -0
  48. package/dist/index.d.ts +38 -0
  49. package/dist/index.js +39 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/input-accessory-view.d.ts +16 -0
  52. package/dist/input-accessory-view.js +29 -0
  53. package/dist/input-accessory-view.js.map +1 -0
  54. package/dist/keyboard-avoiding-view.d.ts +79 -0
  55. package/dist/keyboard-avoiding-view.js +172 -0
  56. package/dist/keyboard-avoiding-view.js.map +1 -0
  57. package/dist/keyboard-dock.d.ts +126 -0
  58. package/dist/keyboard-dock.js +327 -0
  59. package/dist/keyboard-dock.js.map +1 -0
  60. package/dist/keyboard-taps.d.ts +12 -0
  61. package/dist/keyboard-taps.js +51 -0
  62. package/dist/keyboard-taps.js.map +1 -0
  63. package/dist/modal.d.ts +56 -0
  64. package/dist/modal.js +102 -0
  65. package/dist/modal.js.map +1 -0
  66. package/dist/native-gesture.d.ts +21 -0
  67. package/dist/native-gesture.js +56 -0
  68. package/dist/native-gesture.js.map +1 -0
  69. package/dist/native-ref.d.ts +7 -0
  70. package/dist/native-ref.js +13 -0
  71. package/dist/native-ref.js.map +1 -0
  72. package/dist/pressable.d.ts +220 -0
  73. package/dist/pressable.js +484 -0
  74. package/dist/pressable.js.map +1 -0
  75. package/dist/reanimated.d.ts +19 -0
  76. package/dist/reanimated.js +111 -0
  77. package/dist/reanimated.js.map +1 -0
  78. package/dist/refresh-control.d.ts +50 -0
  79. package/dist/refresh-control.js +103 -0
  80. package/dist/refresh-control.js.map +1 -0
  81. package/dist/safe-area-provider.d.ts +11 -0
  82. package/dist/safe-area-provider.js +70 -0
  83. package/dist/safe-area-provider.js.map +1 -0
  84. package/dist/safe-area-view.d.ts +22 -0
  85. package/dist/safe-area-view.js +77 -0
  86. package/dist/safe-area-view.js.map +1 -0
  87. package/dist/safe-area.d.ts +12 -0
  88. package/dist/safe-area.js +27 -0
  89. package/dist/safe-area.js.map +1 -0
  90. package/dist/scroll-view-props.d.ts +89 -0
  91. package/dist/scroll-view-props.js +153 -0
  92. package/dist/scroll-view-props.js.map +1 -0
  93. package/dist/scroll-view.d.ts +95 -0
  94. package/dist/scroll-view.js +181 -0
  95. package/dist/scroll-view.js.map +1 -0
  96. package/dist/section-list.d.ts +146 -0
  97. package/dist/section-list.js +300 -0
  98. package/dist/section-list.js.map +1 -0
  99. package/dist/sticky-headers.d.ts +41 -0
  100. package/dist/sticky-headers.js +118 -0
  101. package/dist/sticky-headers.js.map +1 -0
  102. package/dist/swipe-refresh-layout.d.ts +51 -0
  103. package/dist/swipe-refresh-layout.js +162 -0
  104. package/dist/swipe-refresh-layout.js.map +1 -0
  105. package/dist/switch.d.ts +54 -0
  106. package/dist/switch.js +110 -0
  107. package/dist/switch.js.map +1 -0
  108. package/dist/template-slot.d.ts +18 -0
  109. package/dist/template-slot.js +30 -0
  110. package/dist/template-slot.js.map +1 -0
  111. package/dist/text-input.d.ts +168 -0
  112. package/dist/text-input.js +312 -0
  113. package/dist/text-input.js.map +1 -0
  114. package/dist/text.d.ts +70 -0
  115. package/dist/text.js +111 -0
  116. package/dist/text.js.map +1 -0
  117. package/dist/touchable-opacity.d.ts +36 -0
  118. package/dist/touchable-opacity.js +76 -0
  119. package/dist/touchable-opacity.js.map +1 -0
  120. package/dist/transforms.d.ts +2 -0
  121. package/dist/transforms.js +17 -0
  122. package/dist/transforms.js.map +1 -0
  123. package/dist/view-base.d.ts +332 -0
  124. package/dist/view-base.js +534 -0
  125. package/dist/view-base.js.map +1 -0
  126. package/dist/view.d.ts +12 -0
  127. package/dist/view.js +18 -0
  128. package/dist/view.js.map +1 -0
  129. package/dist/virtual-list.d.ts +530 -0
  130. package/dist/virtual-list.js +1150 -0
  131. package/dist/virtual-list.js.map +1 -0
  132. package/dist/worklet-scroll.d.ts +13 -0
  133. package/dist/worklet-scroll.js +49 -0
  134. package/dist/worklet-scroll.js.map +1 -0
  135. package/dist/worklet-style.d.ts +13 -0
  136. package/dist/worklet-style.js +47 -0
  137. package/dist/worklet-style.js.map +1 -0
  138. package/dist/worklets.d.ts +89 -0
  139. package/dist/worklets.js +42 -0
  140. package/dist/worklets.js.map +1 -0
  141. package/dist/written-props.d.ts +6 -0
  142. package/dist/written-props.js +180 -0
  143. package/dist/written-props.js.map +1 -0
  144. package/package.json +88 -3
package/dist/text.d.ts ADDED
@@ -0,0 +1,70 @@
1
+ import { TouchableBase } from './pressable.ts';
2
+ import * as i0 from "@angular/core";
3
+ export type EllipsizeMode = 'head' | 'middle' | 'tail' | 'clip';
4
+ export type DynamicTypeRamp = 'caption2' | 'caption1' | 'footnote' | 'subheadline' | 'callout' | 'body' | 'headline' | 'title3' | 'title2' | 'title1' | 'largeTitle';
5
+ /**
6
+ * A run of text. Commits as `Paragraph`, or as a span (`VirtualText`) when nested in another
7
+ * `<text>`, which the engine decides from the tree so a nested run inherits its parent's font
8
+ * and sits on its baseline.
9
+ *
10
+ * Text inherits `color`, `fontSize` and the other text properties from CSS as it does on the
11
+ * web; from an inline `[style]` on an ancestor view it does not, exactly as in RN.
12
+ *
13
+ * Presses: RN makes a text pressable when a press handler is present. Angular cannot see
14
+ * whether `(press)` is bound, so set `pressable` to opt in; the handlers, delays and long press
15
+ * are then the same as `<pressable>`'s. iOS highlights a pressed run unless
16
+ * `suppressHighlighting` is set.
17
+ */
18
+ export declare class Text extends TouchableBase {
19
+ /**
20
+ * `Text.js` splits by platform: on iOS every text is an accessibility element unless refused,
21
+ * on Android only one that can be pressed. Nothing native can infer which, so the host's
22
+ * `Platform.OS` decides, exactly as React Native's own wrapper does.
23
+ */
24
+ protected accessibleByDefault(): boolean;
25
+ /** Truncate after this many lines, with `ellipsizeMode` deciding where the ellipsis goes. */
26
+ readonly numberOfLines: import("@angular/core").InputSignalWithTransform<number | undefined, unknown>;
27
+ /**
28
+ * Where truncated text is cut. `clip` is iOS only. Defaults to `tail`, as React Native's `Text`
29
+ * does in JavaScript: native's own default is to clip, with no ellipsis. The default is the
30
+ * engine's, below `text-overflow` in a stylesheet, which in turn is below this input.
31
+ */
32
+ readonly ellipsizeMode: import("@angular/core").InputSignal<EllipsizeMode | undefined>;
33
+ /** Let the user select and copy the text. */
34
+ readonly selectable: import("@angular/core").InputSignalWithTransform<boolean | undefined, unknown>;
35
+ /** The highlight colour of a selection. */
36
+ readonly selectionColor: import("@angular/core").InputSignal<string | undefined>;
37
+ /** Scale with the system Text Size setting. Defaults to true. */
38
+ readonly allowFontScaling: import("@angular/core").InputSignalWithTransform<boolean | undefined, unknown>;
39
+ /** The most `allowFontScaling` may scale by; 0 means no limit. */
40
+ readonly maxFontSizeMultiplier: import("@angular/core").InputSignalWithTransform<number | undefined, unknown>;
41
+ /** iOS: the Dynamic Type style this text follows. */
42
+ readonly dynamicTypeRamp: import("@angular/core").InputSignal<DynamicTypeRamp | undefined>;
43
+ /** iOS: shrink the font to fit `numberOfLines`. */
44
+ readonly adjustsFontSizeToFit: import("@angular/core").InputSignalWithTransform<boolean | undefined, unknown>;
45
+ /** iOS: the smallest scale `adjustsFontSizeToFit` may shrink to, from 0.01 to 1. */
46
+ readonly minimumFontScale: import("@angular/core").InputSignalWithTransform<number | undefined, unknown>;
47
+ /** iOS: the line-breaking strategy. */
48
+ readonly lineBreakStrategyIOS: import("@angular/core").InputSignal<"none" | "standard" | "hangul-word" | "push-out" | undefined>;
49
+ /** Android: the line-breaking strategy. */
50
+ readonly textBreakStrategy: import("@angular/core").InputSignal<"simple" | "highQuality" | "balanced" | undefined>;
51
+ /** Android: turn phone numbers, links and addresses into tappable text. */
52
+ readonly dataDetectorType: import("@angular/core").InputSignal<"none" | "link" | "phoneNumber" | "email" | "all" | undefined>;
53
+ /** Android: how often to hyphenate. */
54
+ readonly hyphenationFrequency: import("@angular/core").InputSignal<"none" | "normal" | "full" | undefined>;
55
+ /** Respond to presses. See the class note. */
56
+ readonly pressable: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
57
+ /** iOS: do not grey the text while it is pressed. */
58
+ readonly suppressHighlighting: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
59
+ /**
60
+ * Written when the press starts and ends rather than bound from the host: a host binding would
61
+ * run for every text on screen on every pass, to follow a press that almost none of them get.
62
+ */
63
+ protected pressedChanged(pressed: boolean): void;
64
+ /** The pass-through props, written when one of them changes. See `ViewBase.ngOnChanges`. */
65
+ ngOnChanges(): void;
66
+ protected claims(): boolean;
67
+ protected measures(): boolean;
68
+ static ɵfac: i0.ɵɵFactoryDeclaration<Text, never>;
69
+ static ɵdir: i0.ɵɵDirectiveDeclaration<Text, "text", ["text"], { "numberOfLines": { "alias": "numberOfLines"; "required": false; "isSignal": true; }; "ellipsizeMode": { "alias": "ellipsizeMode"; "required": false; "isSignal": true; }; "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "selectionColor": { "alias": "selectionColor"; "required": false; "isSignal": true; }; "allowFontScaling": { "alias": "allowFontScaling"; "required": false; "isSignal": true; }; "maxFontSizeMultiplier": { "alias": "maxFontSizeMultiplier"; "required": false; "isSignal": true; }; "dynamicTypeRamp": { "alias": "dynamicTypeRamp"; "required": false; "isSignal": true; }; "adjustsFontSizeToFit": { "alias": "adjustsFontSizeToFit"; "required": false; "isSignal": true; }; "minimumFontScale": { "alias": "minimumFontScale"; "required": false; "isSignal": true; }; "lineBreakStrategyIOS": { "alias": "lineBreakStrategyIOS"; "required": false; "isSignal": true; }; "textBreakStrategy": { "alias": "textBreakStrategy"; "required": false; "isSignal": true; }; "dataDetectorType": { "alias": "dataDetectorType"; "required": false; "isSignal": true; }; "hyphenationFrequency": { "alias": "android_hyphenationFrequency"; "required": false; "isSignal": true; }; "pressable": { "alias": "pressable"; "required": false; "isSignal": true; }; "suppressHighlighting": { "alias": "suppressHighlighting"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
70
+ }
package/dist/text.js ADDED
@@ -0,0 +1,111 @@
1
+ import { Directive, booleanAttribute, input } from '@angular/core';
2
+ import { nativePlatform } from '@ng-native/fabric';
3
+ import { TouchableBase } from "./pressable.js";
4
+ import { optionalBoolean, optionalNumber } from "./transforms.js";
5
+ import * as i0 from "@angular/core";
6
+ /**
7
+ * A run of text. Commits as `Paragraph`, or as a span (`VirtualText`) when nested in another
8
+ * `<text>`, which the engine decides from the tree so a nested run inherits its parent's font
9
+ * and sits on its baseline.
10
+ *
11
+ * Text inherits `color`, `fontSize` and the other text properties from CSS as it does on the
12
+ * web; from an inline `[style]` on an ancestor view it does not, exactly as in RN.
13
+ *
14
+ * Presses: RN makes a text pressable when a press handler is present. Angular cannot see
15
+ * whether `(press)` is bound, so set `pressable` to opt in; the handlers, delays and long press
16
+ * are then the same as `<pressable>`'s. iOS highlights a pressed run unless
17
+ * `suppressHighlighting` is set.
18
+ */
19
+ export class Text extends TouchableBase {
20
+ /**
21
+ * `Text.js` splits by platform: on iOS every text is an accessibility element unless refused,
22
+ * on Android only one that can be pressed. Nothing native can infer which, so the host's
23
+ * `Platform.OS` decides, exactly as React Native's own wrapper does.
24
+ */
25
+ accessibleByDefault() {
26
+ return nativePlatform() === 'android' ? this.pressable() : true;
27
+ }
28
+ /** Truncate after this many lines, with `ellipsizeMode` deciding where the ellipsis goes. */
29
+ numberOfLines = input(undefined, { ...(ngDevMode ? { debugName: "numberOfLines" } : /* istanbul ignore next */ {}), transform: optionalNumber });
30
+ /**
31
+ * Where truncated text is cut. `clip` is iOS only. Defaults to `tail`, as React Native's `Text`
32
+ * does in JavaScript: native's own default is to clip, with no ellipsis. The default is the
33
+ * engine's, below `text-overflow` in a stylesheet, which in turn is below this input.
34
+ */
35
+ ellipsizeMode = input(/* @ts-ignore */
36
+ ...(ngDevMode ? [undefined, { debugName: "ellipsizeMode" }] : /* istanbul ignore next */ []));
37
+ /** Let the user select and copy the text. */
38
+ selectable = input(undefined, { ...(ngDevMode ? { debugName: "selectable" } : /* istanbul ignore next */ {}), transform: optionalBoolean });
39
+ /** The highlight colour of a selection. */
40
+ selectionColor = input(/* @ts-ignore */
41
+ ...(ngDevMode ? [undefined, { debugName: "selectionColor" }] : /* istanbul ignore next */ []));
42
+ /** Scale with the system Text Size setting. Defaults to true. */
43
+ allowFontScaling = input(undefined, { ...(ngDevMode ? { debugName: "allowFontScaling" } : /* istanbul ignore next */ {}), transform: optionalBoolean });
44
+ /** The most `allowFontScaling` may scale by; 0 means no limit. */
45
+ maxFontSizeMultiplier = input(undefined, { ...(ngDevMode ? { debugName: "maxFontSizeMultiplier" } : /* istanbul ignore next */ {}), transform: optionalNumber });
46
+ /** iOS: the Dynamic Type style this text follows. */
47
+ dynamicTypeRamp = input(/* @ts-ignore */
48
+ ...(ngDevMode ? [undefined, { debugName: "dynamicTypeRamp" }] : /* istanbul ignore next */ []));
49
+ /** iOS: shrink the font to fit `numberOfLines`. */
50
+ adjustsFontSizeToFit = input(undefined, { ...(ngDevMode ? { debugName: "adjustsFontSizeToFit" } : /* istanbul ignore next */ {}), transform: optionalBoolean });
51
+ /** iOS: the smallest scale `adjustsFontSizeToFit` may shrink to, from 0.01 to 1. */
52
+ minimumFontScale = input(undefined, { ...(ngDevMode ? { debugName: "minimumFontScale" } : /* istanbul ignore next */ {}), transform: optionalNumber });
53
+ /** iOS: the line-breaking strategy. */
54
+ lineBreakStrategyIOS = input(/* @ts-ignore */
55
+ ...(ngDevMode ? [undefined, { debugName: "lineBreakStrategyIOS" }] : /* istanbul ignore next */ []));
56
+ /** Android: the line-breaking strategy. */
57
+ textBreakStrategy = input(/* @ts-ignore */
58
+ ...(ngDevMode ? [undefined, { debugName: "textBreakStrategy" }] : /* istanbul ignore next */ []));
59
+ /** Android: turn phone numbers, links and addresses into tappable text. */
60
+ dataDetectorType = input(/* @ts-ignore */
61
+ ...(ngDevMode ? [undefined, { debugName: "dataDetectorType" }] : /* istanbul ignore next */ []));
62
+ /** Android: how often to hyphenate. */
63
+ hyphenationFrequency = input(undefined, { ...(ngDevMode ? { debugName: "hyphenationFrequency" } : /* istanbul ignore next */ {}), alias: 'android_hyphenationFrequency' });
64
+ /** Respond to presses. See the class note. */
65
+ pressable = input(false, { ...(ngDevMode ? { debugName: "pressable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
66
+ /** iOS: do not grey the text while it is pressed. */
67
+ suppressHighlighting = input(false, { ...(ngDevMode ? { debugName: "suppressHighlighting" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
68
+ /**
69
+ * Written when the press starts and ends rather than bound from the host: a host binding would
70
+ * run for every text on screen on every pass, to follow a press that almost none of them get.
71
+ */
72
+ pressedChanged(pressed) {
73
+ const highlight = pressed && !this.suppressHighlighting();
74
+ this.engine.setProp(this.node, 'isHighlighted', highlight ? true : undefined);
75
+ }
76
+ /** The pass-through props, written when one of them changes. See `ViewBase.ngOnChanges`. */
77
+ ngOnChanges() {
78
+ super.ngOnChanges();
79
+ const write = (key, value) => this.engine.setProp(this.node, key, value);
80
+ write('numberOfLines', this.numberOfLines());
81
+ write('ellipsizeMode', this.ellipsizeMode());
82
+ write('selectable', this.selectable());
83
+ write('selectionColor', this.selectionColor());
84
+ write('allowFontScaling', this.allowFontScaling());
85
+ write('maxFontSizeMultiplier', this.maxFontSizeMultiplier());
86
+ write('dynamicTypeRamp', this.dynamicTypeRamp());
87
+ write('adjustsFontSizeToFit', this.adjustsFontSizeToFit());
88
+ write('minimumFontScale', this.minimumFontScale());
89
+ write('lineBreakStrategyIOS', this.lineBreakStrategyIOS());
90
+ write('textBreakStrategy', this.textBreakStrategy());
91
+ write('dataDetectorType', this.dataDetectorType());
92
+ write('android_hyphenationFrequency', this.hyphenationFrequency());
93
+ write('isPressable', this.pressable() || undefined);
94
+ }
95
+ claims() {
96
+ return this.pressable() && !this.disabled();
97
+ }
98
+ measures() {
99
+ return this.pressable();
100
+ }
101
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: Text, deps: null, target: i0.ɵɵFactoryTarget.Directive });
102
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.2.0", type: Text, isStandalone: true, selector: "text", inputs: { numberOfLines: { classPropertyName: "numberOfLines", publicName: "numberOfLines", isSignal: true, isRequired: false, transformFunction: null }, ellipsizeMode: { classPropertyName: "ellipsizeMode", publicName: "ellipsizeMode", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, selectionColor: { classPropertyName: "selectionColor", publicName: "selectionColor", isSignal: true, isRequired: false, transformFunction: null }, allowFontScaling: { classPropertyName: "allowFontScaling", publicName: "allowFontScaling", isSignal: true, isRequired: false, transformFunction: null }, maxFontSizeMultiplier: { classPropertyName: "maxFontSizeMultiplier", publicName: "maxFontSizeMultiplier", isSignal: true, isRequired: false, transformFunction: null }, dynamicTypeRamp: { classPropertyName: "dynamicTypeRamp", publicName: "dynamicTypeRamp", isSignal: true, isRequired: false, transformFunction: null }, adjustsFontSizeToFit: { classPropertyName: "adjustsFontSizeToFit", publicName: "adjustsFontSizeToFit", isSignal: true, isRequired: false, transformFunction: null }, minimumFontScale: { classPropertyName: "minimumFontScale", publicName: "minimumFontScale", isSignal: true, isRequired: false, transformFunction: null }, lineBreakStrategyIOS: { classPropertyName: "lineBreakStrategyIOS", publicName: "lineBreakStrategyIOS", isSignal: true, isRequired: false, transformFunction: null }, textBreakStrategy: { classPropertyName: "textBreakStrategy", publicName: "textBreakStrategy", isSignal: true, isRequired: false, transformFunction: null }, dataDetectorType: { classPropertyName: "dataDetectorType", publicName: "dataDetectorType", isSignal: true, isRequired: false, transformFunction: null }, hyphenationFrequency: { classPropertyName: "hyphenationFrequency", publicName: "android_hyphenationFrequency", isSignal: true, isRequired: false, transformFunction: null }, pressable: { classPropertyName: "pressable", publicName: "pressable", isSignal: true, isRequired: false, transformFunction: null }, suppressHighlighting: { classPropertyName: "suppressHighlighting", publicName: "suppressHighlighting", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["text"], usesInheritance: true, usesOnChanges: true, ngImport: i0 });
103
+ }
104
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: Text, decorators: [{
105
+ type: Directive,
106
+ args: [{
107
+ selector: 'text',
108
+ exportAs: 'text',
109
+ }]
110
+ }], propDecorators: { numberOfLines: [{ type: i0.Input, args: [{ isSignal: true, alias: "numberOfLines", required: false }] }], ellipsizeMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "ellipsizeMode", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], selectionColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionColor", required: false }] }], allowFontScaling: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowFontScaling", required: false }] }], maxFontSizeMultiplier: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFontSizeMultiplier", required: false }] }], dynamicTypeRamp: [{ type: i0.Input, args: [{ isSignal: true, alias: "dynamicTypeRamp", required: false }] }], adjustsFontSizeToFit: [{ type: i0.Input, args: [{ isSignal: true, alias: "adjustsFontSizeToFit", required: false }] }], minimumFontScale: [{ type: i0.Input, args: [{ isSignal: true, alias: "minimumFontScale", required: false }] }], lineBreakStrategyIOS: [{ type: i0.Input, args: [{ isSignal: true, alias: "lineBreakStrategyIOS", required: false }] }], textBreakStrategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "textBreakStrategy", required: false }] }], dataDetectorType: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataDetectorType", required: false }] }], hyphenationFrequency: [{ type: i0.Input, args: [{ isSignal: true, alias: "android_hyphenationFrequency", required: false }] }], pressable: [{ type: i0.Input, args: [{ isSignal: true, alias: "pressable", required: false }] }], suppressHighlighting: [{ type: i0.Input, args: [{ isSignal: true, alias: "suppressHighlighting", required: false }] }] } });
111
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
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 /** 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 }\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"]}
@@ -0,0 +1,36 @@
1
+ import { ControlBase } from './pressable.ts';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * A pressable that dims while pressed, as RN's `TouchableOpacity` does.
5
+ *
6
+ * The fade is a CSS transition rather than a JavaScript tween: the component sets the target
7
+ * opacity and the engine eases to it. React Native's own timings are asymmetric - 150ms in,
8
+ * 250ms out - which is a thing CSS expresses exactly, because the duration in force is the one on
9
+ * the state being entered. That is what the two rules below are.
10
+ *
11
+ * The opacity is a binding rather than a rule because `activeOpacity` is an input, and it returns
12
+ * to `undefined` when the fade finishes so a caller's own `[style]` opacity is in charge again at
13
+ * rest. `transitionend` is the engine's own event, the same one Angular's `animate.leave` waits
14
+ * for.
15
+ */
16
+ export declare class TouchableOpacity extends ControlBase {
17
+ /** `TouchableOpacity.js`: `accessible={this.props.accessible !== false}`, and focusable too. */
18
+ protected accessibleByDefault(): boolean;
19
+ protected focusableByDefault(): boolean;
20
+ protected disabledForAccessibility(): boolean;
21
+ /** The opacity while pressed. */
22
+ readonly activeOpacity: import("@angular/core").InputSignalWithTransform<number, unknown>;
23
+ /** Undefined at rest, so the caller's own `[style]` opacity shows through. */
24
+ protected readonly opacity: import("@angular/core").WritableSignal<number | undefined>;
25
+ /** What to ease back to: whatever the caller had before the press. */
26
+ private resting;
27
+ constructor();
28
+ /**
29
+ * The fade is over. Letting go of the value hands the opacity back to whatever the caller's own
30
+ * style says, which is the same number we just eased to - so nothing moves, and a caller who
31
+ * changes it later is not fighting a binding of ours.
32
+ */
33
+ protected settle(): void;
34
+ static ɵfac: i0.ɵɵFactoryDeclaration<TouchableOpacity, never>;
35
+ static ɵcmp: i0.ɵɵComponentDeclaration<TouchableOpacity, "touchable-opacity", ["touchableOpacity"], { "activeOpacity": { "alias": "activeOpacity"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
36
+ }
@@ -0,0 +1,76 @@
1
+ import { Component, DestroyRef, effect, inject, input, numberAttribute, signal, untracked, } from '@angular/core';
2
+ import { ControlBase } from "./pressable.js";
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * A pressable that dims while pressed, as RN's `TouchableOpacity` does.
6
+ *
7
+ * The fade is a CSS transition rather than a JavaScript tween: the component sets the target
8
+ * opacity and the engine eases to it. React Native's own timings are asymmetric - 150ms in,
9
+ * 250ms out - which is a thing CSS expresses exactly, because the duration in force is the one on
10
+ * the state being entered. That is what the two rules below are.
11
+ *
12
+ * The opacity is a binding rather than a rule because `activeOpacity` is an input, and it returns
13
+ * to `undefined` when the fade finishes so a caller's own `[style]` opacity is in charge again at
14
+ * rest. `transitionend` is the engine's own event, the same one Angular's `animate.leave` waits
15
+ * for.
16
+ */
17
+ export class TouchableOpacity extends ControlBase {
18
+ /** `TouchableOpacity.js`: `accessible={this.props.accessible !== false}`, and focusable too. */
19
+ accessibleByDefault() {
20
+ return true;
21
+ }
22
+ focusableByDefault() {
23
+ return true;
24
+ }
25
+ disabledForAccessibility() {
26
+ return this.disabled();
27
+ }
28
+ /** The opacity while pressed. */
29
+ activeOpacity = input(0.2, { ...(ngDevMode ? { debugName: "activeOpacity" } : /* istanbul ignore next */ {}), transform: numberAttribute });
30
+ /** Undefined at rest, so the caller's own `[style]` opacity shows through. */
31
+ opacity = signal(undefined, /* @ts-ignore */
32
+ ...(ngDevMode ? [{ debugName: "opacity" }] : /* istanbul ignore next */ []));
33
+ /** What to ease back to: whatever the caller had before the press. */
34
+ resting = 1;
35
+ constructor() {
36
+ super();
37
+ // Reacts to `pressed` alone. Reading `opacity` here would re-run the effect on the value it
38
+ // just wrote, and a press that arrives mid-fade would restart from the wrong end.
39
+ effect(() => {
40
+ const pressed = this.pressed();
41
+ untracked(() => {
42
+ if (pressed) {
43
+ // Remembered on the way in, so the fade out returns to it rather than to 1.
44
+ const style = this.node.props['style'];
45
+ this.resting = this.opacity() ?? style?.opacity ?? 1;
46
+ this.opacity.set(this.activeOpacity());
47
+ }
48
+ else if (this.opacity() !== undefined) {
49
+ this.opacity.set(this.resting);
50
+ }
51
+ });
52
+ });
53
+ // A component destroyed mid-fade leaves a transition the engine would go on advancing.
54
+ inject(DestroyRef).onDestroy(() => this.opacity.set(undefined));
55
+ }
56
+ /**
57
+ * The fade is over. Letting go of the value hands the opacity back to whatever the caller's own
58
+ * style says, which is the same number we just eased to - so nothing moves, and a caller who
59
+ * changes it later is not fighting a binding of ours.
60
+ */
61
+ settle() {
62
+ if (!this.pressed())
63
+ this.opacity.set(undefined);
64
+ }
65
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: TouchableOpacity, deps: [], target: i0.ɵɵFactoryTarget.Component });
66
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.2.0", type: TouchableOpacity, isStandalone: true, selector: "touchable-opacity", inputs: { activeOpacity: { classPropertyName: "activeOpacity", publicName: "activeOpacity", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "transitionend": "settle()" }, properties: { "style.opacity": "opacity()", "class.pressed": "pressed()" } }, exportAs: ["touchableOpacity"], usesInheritance: true, ngImport: i0, template: `<ng-content />`, isInline: true, styles: ["\n /*\n * The resting opacity is stated rather than left out, because a transition needs a value to\n * ease *from*: a property appearing for the first time is recorded and left alone, which is\n * CSS's own rule and would make every fade in a snap. Inline style still wins over this, so a\n * caller's own opacity is untouched.\n */\n :host {\n opacity: 1;\n transition: opacity 250ms ease-in-out;\n }\n :host(.pressed) {\n transition: opacity 150ms ease-in-out;\n }\n "] });
67
+ }
68
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.0", ngImport: i0, type: TouchableOpacity, decorators: [{
69
+ type: Component,
70
+ args: [{ selector: 'touchable-opacity', template: `<ng-content />`, exportAs: 'touchableOpacity', host: {
71
+ '[style.opacity]': 'opacity()',
72
+ '[class.pressed]': 'pressed()',
73
+ '(transitionend)': 'settle()',
74
+ }, styles: ["\n /*\n * The resting opacity is stated rather than left out, because a transition needs a value to\n * ease *from*: a property appearing for the first time is recorded and left alone, which is\n * CSS's own rule and would make every fade in a snap. Inline style still wins over this, so a\n * caller's own opacity is untouched.\n */\n :host {\n opacity: 1;\n transition: opacity 250ms ease-in-out;\n }\n :host(.pressed) {\n transition: opacity 150ms ease-in-out;\n }\n "] }]
75
+ }], ctorParameters: () => [], propDecorators: { activeOpacity: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeOpacity", required: false }] }] } });
76
+ //# sourceMappingURL=touchable-opacity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"touchable-opacity.js","sourceRoot":"","sources":["../src/touchable-opacity.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,UAAU,EACV,MAAM,EACN,MAAM,EACN,KAAK,EACL,eAAe,EACf,MAAM,EACN,SAAS,GACV,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;;AAE7C;;;;;;;;;;;;GAYG;AA0BH,MAAM,OAAO,gBAAiB,SAAQ,WAAW;IAC/C,gGAAgG;IAC7E,mBAAmB;QACpC,OAAO,IAAI,CAAC;IACd,CAAC;IAEkB,kBAAkB;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAEkB,wBAAwB;QACzC,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IAED,iCAAiC;IACxB,aAAa,GAAG,KAAK,CAAC,GAAG,qFAAI,SAAS,EAAE,eAAe,GAAG,CAAC;IAEpE,8EAA8E;IAC3D,OAAO,GAAG,MAAM,CAAqB,SAAS;gFAAC,CAAC;IAEnE,sEAAsE;IAC9D,OAAO,GAAG,CAAC,CAAC;IAEpB;QACE,KAAK,EAAE,CAAC;QACR,4FAA4F;QAC5F,kFAAkF;QAClF,MAAM,CAAC,GAAG,EAAE;YACV,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YAC/B,SAAS,CAAC,GAAG,EAAE;gBACb,IAAI,OAAO,EAAE,CAAC;oBACZ,4EAA4E;oBAC5E,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAqC,CAAC;oBAC3E,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,EAAE,OAAO,IAAI,CAAC,CAAC;oBACrD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;gBACzC,CAAC;qBAAM,IAAI,IAAI,CAAC,OAAO,EAAE,KAAK,SAAS,EAAE,CAAC;oBACxC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBACjC,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,uFAAuF;QACvF,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;IAClE,CAAC;IAED;;;;OAIG;IACO,MAAM;QACd,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACnD,CAAC;uGAnDU,gBAAgB;2FAAhB,gBAAgB,kaAvBjB,gBAAgB;;2FAuBf,gBAAgB;kBAzB5B,SAAS;+BACE,mBAAmB,YACnB,gBAAgB,YAChB,kBAAkB,QAgBtB;wBACJ,iBAAiB,EAAE,WAAW;wBAC9B,iBAAiB,EAAE,WAAW;wBAC9B,iBAAiB,EAAE,UAAU;qBAC9B","sourcesContent":["import {\n Component,\n DestroyRef,\n effect,\n inject,\n input,\n numberAttribute,\n signal,\n untracked,\n} from '@angular/core';\nimport { ControlBase } from './pressable.ts';\n\n/**\n * A pressable that dims while pressed, as RN's `TouchableOpacity` does.\n *\n * The fade is a CSS transition rather than a JavaScript tween: the component sets the target\n * opacity and the engine eases to it. React Native's own timings are asymmetric - 150ms in,\n * 250ms out - which is a thing CSS expresses exactly, because the duration in force is the one on\n * the state being entered. That is what the two rules below are.\n *\n * The opacity is a binding rather than a rule because `activeOpacity` is an input, and it returns\n * to `undefined` when the fade finishes so a caller's own `[style]` opacity is in charge again at\n * rest. `transitionend` is the engine's own event, the same one Angular's `animate.leave` waits\n * for.\n */\n@Component({\n selector: 'touchable-opacity',\n template: `<ng-content />`,\n exportAs: 'touchableOpacity',\n styles: `\n /*\n * The resting opacity is stated rather than left out, because a transition needs a value to\n * ease *from*: a property appearing for the first time is recorded and left alone, which is\n * CSS's own rule and would make every fade in a snap. Inline style still wins over this, so a\n * caller's own opacity is untouched.\n */\n :host {\n opacity: 1;\n transition: opacity 250ms ease-in-out;\n }\n :host(.pressed) {\n transition: opacity 150ms ease-in-out;\n }\n `,\n host: {\n '[style.opacity]': 'opacity()',\n '[class.pressed]': 'pressed()',\n '(transitionend)': 'settle()',\n },\n})\nexport class TouchableOpacity extends ControlBase {\n /** `TouchableOpacity.js`: `accessible={this.props.accessible !== false}`, and focusable too. */\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 /** The opacity while pressed. */\n readonly activeOpacity = input(0.2, { transform: numberAttribute });\n\n /** Undefined at rest, so the caller's own `[style]` opacity shows through. */\n protected readonly opacity = signal<number | undefined>(undefined);\n\n /** What to ease back to: whatever the caller had before the press. */\n private resting = 1;\n\n constructor() {\n super();\n // Reacts to `pressed` alone. Reading `opacity` here would re-run the effect on the value it\n // just wrote, and a press that arrives mid-fade would restart from the wrong end.\n effect(() => {\n const pressed = this.pressed();\n untracked(() => {\n if (pressed) {\n // Remembered on the way in, so the fade out returns to it rather than to 1.\n const style = this.node.props['style'] as { opacity?: number } | undefined;\n this.resting = this.opacity() ?? style?.opacity ?? 1;\n this.opacity.set(this.activeOpacity());\n } else if (this.opacity() !== undefined) {\n this.opacity.set(this.resting);\n }\n });\n });\n // A component destroyed mid-fade leaves a transition the engine would go on advancing.\n inject(DestroyRef).onDestroy(() => this.opacity.set(undefined));\n }\n\n /**\n * The fade is over. Letting go of the value hands the opacity back to whatever the caller's own\n * style says, which is the same number we just eased to - so nothing moves, and a caller who\n * changes it later is not fighting a binding of ours.\n */\n protected settle(): void {\n if (!this.pressed()) this.opacity.set(undefined);\n }\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function optionalBoolean(value: unknown): boolean | undefined;
2
+ export declare function optionalNumber(value: unknown): number | undefined;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Input transforms for props that native reads as "set" or "not set".
3
+ *
4
+ * Angular's own `booleanAttribute` turns an absent input into `false`, which is right for a DOM
5
+ * attribute and wrong for a native prop: `accessible` unset means "the platform decides", and
6
+ * sending `false` for every boolean a view never mentioned would put a dozen props on every
7
+ * node. These keep `undefined` as undefined and otherwise behave as Angular's do, so `<view
8
+ * collapsable="false">` and `<view [collapsable]="false">` both mean false.
9
+ */
10
+ import { booleanAttribute, numberAttribute } from '@angular/core';
11
+ export function optionalBoolean(value) {
12
+ return value === undefined ? undefined : booleanAttribute(value);
13
+ }
14
+ export function optionalNumber(value) {
15
+ return value === undefined ? undefined : numberAttribute(value);
16
+ }
17
+ //# sourceMappingURL=transforms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transforms.js","sourceRoot":"","sources":["../src/transforms.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAElE,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;AAClE,CAAC","sourcesContent":["/**\n * Input transforms for props that native reads as \"set\" or \"not set\".\n *\n * Angular's own `booleanAttribute` turns an absent input into `false`, which is right for a DOM\n * attribute and wrong for a native prop: `accessible` unset means \"the platform decides\", and\n * sending `false` for every boolean a view never mentioned would put a dozen props on every\n * node. These keep `undefined` as undefined and otherwise behave as Angular's do, so `<view\n * collapsable=\"false\">` and `<view [collapsable]=\"false\">` both mean false.\n */\nimport { booleanAttribute, numberAttribute } from '@angular/core';\n\nexport function optionalBoolean(value: unknown): boolean | undefined {\n return value === undefined ? undefined : booleanAttribute(value);\n}\n\nexport function optionalNumber(value: unknown): number | undefined {\n return value === undefined ? undefined : numberAttribute(value);\n}\n"]}