@octane-xplat/ui 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/README.md +46 -0
  2. package/dist/native/octane-client-build.json +1 -1
  3. package/dist/native/ui.js +52 -40
  4. package/dist/native/ui10.js +20 -11
  5. package/dist/native/ui11.js +42 -109
  6. package/dist/native/ui12.js +17 -84
  7. package/dist/native/ui13.js +11 -41
  8. package/dist/native/ui14.js +118 -76
  9. package/dist/native/ui15.js +43 -92
  10. package/dist/native/ui16.js +106 -45
  11. package/dist/native/ui17.js +29 -42
  12. package/dist/native/ui18.js +34 -53
  13. package/dist/native/ui19.js +246 -32
  14. package/dist/native/ui20.js +27 -16
  15. package/dist/native/ui21.js +376 -86
  16. package/dist/native/ui22.js +26 -114
  17. package/dist/native/ui23.js +49 -97
  18. package/dist/native/ui24.js +78 -53
  19. package/dist/native/ui25.js +138 -16
  20. package/dist/native/ui26.js +8 -23
  21. package/dist/native/ui27.js +60 -34
  22. package/dist/native/ui28.js +36 -142
  23. package/dist/native/ui29.js +101 -21
  24. package/dist/native/ui30.js +14 -31
  25. package/dist/native/ui31.js +55 -36
  26. package/dist/native/ui32.js +49 -61
  27. package/dist/native/ui33.js +36 -28
  28. package/dist/native/ui34.js +51 -8
  29. package/dist/native/ui35.js +98 -20
  30. package/dist/native/ui36.js +9 -33
  31. package/dist/native/ui37.js +42 -15
  32. package/dist/native/ui38.js +186 -57
  33. package/dist/native/ui39.js +96 -24
  34. package/dist/native/ui4.js +22 -20
  35. package/dist/native/ui40.js +57 -13
  36. package/dist/native/ui41.js +15 -100
  37. package/dist/native/ui42.js +6 -146
  38. package/dist/native/ui43.js +37 -21
  39. package/dist/native/ui44.js +265 -6
  40. package/dist/native/ui45.js +28 -0
  41. package/dist/native/ui46.js +35 -0
  42. package/dist/native/ui47.js +41 -0
  43. package/dist/native/ui48.js +72 -0
  44. package/dist/native/ui49.js +66 -0
  45. package/dist/native/ui5.js +37 -77
  46. package/dist/native/ui50.js +27 -0
  47. package/dist/native/ui51.js +13 -0
  48. package/dist/native/ui52.js +92 -0
  49. package/dist/native/ui53.js +34 -0
  50. package/dist/native/ui54.js +17 -0
  51. package/dist/native/ui55.js +156 -0
  52. package/dist/native/ui56.js +33 -0
  53. package/dist/native/ui57.js +14 -0
  54. package/dist/native/ui58.js +22 -0
  55. package/dist/native/ui59.js +8 -0
  56. package/dist/native/ui6.js +52 -9
  57. package/dist/native/ui60.js +108 -0
  58. package/dist/native/ui61.js +76 -0
  59. package/dist/native/ui7.js +42 -26
  60. package/dist/native/ui8.js +22 -12
  61. package/dist/native/ui9.js +18 -9
  62. package/dist/web/octane-client-build.json +1 -1
  63. package/dist/web/ui.js +51 -40
  64. package/dist/web/ui10.js +33 -186
  65. package/dist/web/ui11.js +28 -409
  66. package/dist/web/ui12.js +21 -68
  67. package/dist/web/ui13.js +201 -97
  68. package/dist/web/ui14.js +85 -95
  69. package/dist/web/ui15.js +368 -25
  70. package/dist/web/ui16.js +13 -101
  71. package/dist/web/ui17.js +246 -42
  72. package/dist/web/ui18.js +237 -28
  73. package/dist/web/ui19.js +36 -10
  74. package/dist/web/ui20.js +73 -102
  75. package/dist/web/ui21.js +102 -73
  76. package/dist/web/ui22.js +95 -55
  77. package/dist/web/ui23.js +94 -55
  78. package/dist/web/ui24.js +31 -15
  79. package/dist/web/ui25.js +105 -19
  80. package/dist/web/ui26.js +29 -23
  81. package/dist/web/ui27.js +12 -123
  82. package/dist/web/ui28.js +9 -110
  83. package/dist/web/ui29.js +52 -102
  84. package/dist/web/ui3.js +29 -18
  85. package/dist/web/ui30.js +32 -41
  86. package/dist/web/ui31.js +120 -39
  87. package/dist/web/ui32.js +41 -74
  88. package/dist/web/ui33.js +148 -32
  89. package/dist/web/ui34.js +54 -51
  90. package/dist/web/ui35.js +55 -7
  91. package/dist/web/ui36.js +18 -41
  92. package/dist/web/ui37.js +6 -46
  93. package/dist/web/ui38.js +37 -16
  94. package/dist/web/ui39.js +135 -81
  95. package/dist/web/ui4.js +46 -152
  96. package/dist/web/ui40.js +39 -37
  97. package/dist/web/ui41.js +41 -16
  98. package/dist/web/ui42.js +74 -7
  99. package/dist/web/ui43.js +40 -20
  100. package/dist/web/ui44.js +60 -6
  101. package/dist/web/ui45.js +9 -0
  102. package/dist/web/ui46.js +45 -0
  103. package/dist/web/ui47.js +13 -0
  104. package/dist/web/ui48.js +63 -0
  105. package/dist/web/ui49.js +47 -0
  106. package/dist/web/ui5.js +131 -27
  107. package/dist/web/ui50.js +17 -0
  108. package/dist/web/ui51.js +149 -0
  109. package/dist/web/ui52.js +42 -0
  110. package/dist/web/ui53.js +17 -0
  111. package/dist/web/ui54.js +9 -0
  112. package/dist/web/ui55.js +22 -0
  113. package/dist/web/ui56.js +8 -0
  114. package/dist/web/ui57.js +44 -0
  115. package/dist/web/ui58.js +46 -0
  116. package/dist/web/ui6.js +81 -45
  117. package/dist/web/ui7.js +43 -21
  118. package/dist/web/ui8.js +27 -21
  119. package/dist/web/ui9.js +29 -18
  120. package/package.json +13 -4
  121. package/src/theme/tokens.css +369 -138
  122. package/types/index.d.ts +102 -58
  123. package/types/props.d.ts +233 -13
@@ -1,10 +1,53 @@
1
- import { isAndroid, isIOS } from "@nativescript/core";
2
- //#region src/platformProps.native.ts
3
- /** Apply the matching native escape-hatch bag after the primitive's props. */
4
- function applyNativeProps(el, props) {
5
- if (!el) return;
6
- const bag = isIOS ? props.ios : isAndroid ? props.android : void 0;
7
- if (bag) Object.assign(el, bag);
1
+ import { RootLayout, getRootLayout } from "@nativescript/core";
2
+ //#region src/root-layout.native.ts
3
+ var registry = [];
4
+ /** Called by the Screen leaf's <rootlayout> onLoaded/onUnloaded. */
5
+ function registerRootLayout(rl) {
6
+ if (rl && !registry.includes(rl)) registry.push(rl);
7
+ }
8
+ function unregisterRootLayout(rl) {
9
+ const i = rl ? registry.indexOf(rl) : -1;
10
+ if (i >= 0) registry.splice(i, 1);
11
+ }
12
+ /** The most recently mounted rootlayout — the top of the push stack. For
13
+ * imperative services (toast, sheet) there is no invoking component to
14
+ * walk from; last-mounted is the pushed page when one exists. Caveat: tabs
15
+ * keep visited panes mounted — last is the newest, not the visible tab. */
16
+ function topRootLayout() {
17
+ return registry[registry.length - 1] ?? getRootLayout();
18
+ }
19
+ /** Resolve the RootLayout enclosing `view` by walking the native parent
20
+ * chain — the screen shell is a RootLayout (Screen.native), so the first
21
+ * RootLayout ancestor IS the current page's overlay host. Falls back to
22
+ * the top registry entry when the component renders outside any Screen. */
23
+ function rootLayoutFor(view) {
24
+ for (let v = view?.parent; v; v = v.parent) if (v instanceof RootLayout) return v;
25
+ return topRootLayout();
26
+ }
27
+ /** Search every registered rootlayout for a view by id — overlays/sheets/
28
+ * toasts land on different rootlayouts depending on which screen's shell
29
+ * mounted last. */
30
+ function findInRootLayouts(id) {
31
+ const walk = (view) => {
32
+ if (!view) return null;
33
+ if (view.id === id) return view;
34
+ let hit = null;
35
+ view.eachChildView?.((c) => {
36
+ const found = walk(c);
37
+ if (found) {
38
+ hit = found;
39
+ return false;
40
+ }
41
+ return true;
42
+ });
43
+ return hit;
44
+ };
45
+ for (let i = registry.length - 1; i >= 0; i--) {
46
+ const hit = walk(registry[i]);
47
+ if (hit) return hit;
48
+ }
49
+ const rl = getRootLayout();
50
+ return rl ? walk(rl) : null;
8
51
  }
9
52
  //#endregion
10
- export { applyNativeProps };
53
+ export { findInRootLayouts, registerRootLayout, rootLayoutFor, topRootLayout, unregisterRootLayout };
@@ -1,27 +1,105 @@
1
1
  import { cx } from "./ui2.js";
2
- import { applyNativeProps } from "./ui34.js";
3
- import { defineUniversalComponent, universalPlan, universalValue } from "@nativescript-community/octane";
4
- //#region src/ActivityIndicator.native.tsrx
2
+ import { applyThemeClasses } from "./ui31.js";
3
+ import { rootLayoutFor } from "./ui34.js";
4
+ import { createNativeScriptRoot, defineUniversalComponent, hookSlots, universalPlan, universalValue, useEffect, useRef } from "@nativescript-community/octane";
5
+ import { GridLayout, isAndroid, isIOS } from "@nativescript/core";
6
+ //#region src/Overlay.native.tsrx
7
+ var _hs$ = /* @__PURE__ */ hookSlots(4);
8
+ var _h$0 = /* @__PURE__ */ Symbol(_hs$);
9
+ var _h$1 = /* @__PURE__ */ Symbol(_hs$ + 1);
10
+ var _h$2 = /* @__PURE__ */ Symbol(_hs$ + 2);
11
+ var _h$3 = /* @__PURE__ */ Symbol(_hs$ + 3);
5
12
  var __octaneUniversalPlan0 = universalPlan("nativescript", {
13
+ "kind": "range",
14
+ "children": [{
15
+ "kind": "slot",
16
+ "slot": 0
17
+ }]
18
+ });
19
+ var __octaneUniversalPlan1 = universalPlan("nativescript", {
6
20
  "kind": "host",
7
- "type": "activityindicator",
8
- "bindings": [
9
- ["id", 0],
10
- ["className", 1],
11
- ["style", 2],
12
- ["busy", 3],
13
- ["ref", 4]
14
- ]
21
+ "type": "stacklayout",
22
+ "bindings": [["ref", 0], ["style", 1]]
15
23
  });
16
- var ActivityIndicator = defineUniversalComponent("nativescript", function ActivityIndicator(props) {
17
- if (props.busy === false) return null;
18
- return universalValue(__octaneUniversalPlan0, [
19
- props.id,
20
- cx(props.className),
24
+ var OverlayBody = defineUniversalComponent("nativescript", function OverlayBody(props) {
25
+ return universalValue(__octaneUniversalPlan0, [props.children]);
26
+ }, { "module": "@nativescript-community/octane" });
27
+ var Overlay = defineUniversalComponent("nativescript", function Overlay(props) {
28
+ const shown = useRef(null, _h$0);
29
+ const hostView = useRef(null, _h$1);
30
+ const dismiss = useRef(props.onDismiss, _h$2);
31
+ dismiss.current = props.onDismiss;
32
+ const rootLayout = () => rootLayoutFor(hostView.current);
33
+ useEffect(() => {
34
+ const current = shown.current;
35
+ if (!props.open) {
36
+ if (!current) return;
37
+ current.dismissOnClose = false;
38
+ shown.current = null;
39
+ const rl = rootLayout();
40
+ if (rl && rl?.hasChild?.(current.host)) rl.close(current.host).then(() => current.root.unmount?.(), (error) => {
41
+ console.error("[Overlay] close failed", error);
42
+ current.root.unmount?.();
43
+ });
44
+ else current.root.unmount?.();
45
+ return;
46
+ }
47
+ if (current) {
48
+ current.root.render(OverlayBody, { children: props.children });
49
+ current.unbindTheme = applyThemeClasses(current.host, cx("vx-overlay-host", props.className));
50
+ if (props.style) Object.assign(current.host.style, props.style);
51
+ Object.assign(current.host, isIOS ? props.ios : isAndroid ? props.android : void 0);
52
+ return;
53
+ }
54
+ const rl = rootLayout();
55
+ if (!rl) return;
56
+ const host = new GridLayout();
57
+ const unbindTheme = applyThemeClasses(host, cx("vx-overlay-host", props.className));
58
+ host.horizontalAlignment = "stretch";
59
+ host.verticalAlignment = "stretch";
60
+ if (props.style) Object.assign(host.style, props.style);
61
+ Object.assign(host, isIOS ? props.ios : isAndroid ? props.android : void 0);
62
+ const root = createNativeScriptRoot(host);
63
+ const opened = {
64
+ host,
65
+ root,
66
+ dismissOnClose: true,
67
+ unbindTheme
68
+ };
69
+ shown.current = opened;
70
+ root.render(OverlayBody, { children: props.children });
71
+ host.on("closed", () => {
72
+ if (shown.current === opened) shown.current = null;
73
+ opened.unbindTheme?.();
74
+ root.unmount?.();
75
+ if (opened.dismissOnClose) dismiss.current?.();
76
+ });
77
+ const open = () => rl.open(host, props.shadeCover ? { shadeCover: {
78
+ opacity: .45,
79
+ color: "#000000",
80
+ tapToClose: true
81
+ } } : {}).catch((error) => {
82
+ if (shown.current === opened) shown.current = null;
83
+ console.error("[Overlay] open failed", error);
84
+ root.unmount?.();
85
+ });
86
+ if (rl.hasChild?.(host)) rl.close(host).then(open, (error) => console.error("[Overlay] stale host close failed", error));
87
+ else open();
88
+ }, [
89
+ props.open,
90
+ props.children,
91
+ props.shadeCover,
92
+ props.className,
21
93
  props.style,
22
- props.busy ?? true,
23
- (el) => applyNativeProps(el, props)
24
- ]);
94
+ props.ios,
95
+ props.android
96
+ ], _h$3);
97
+ return universalValue(__octaneUniversalPlan1, [(v) => {
98
+ hostView.current = v;
99
+ }, {
100
+ width: 0,
101
+ height: 0
102
+ }]);
25
103
  }, { "module": "@nativescript-community/octane" });
26
104
  //#endregion
27
- export { ActivityIndicator };
105
+ export { Overlay };
@@ -1,34 +1,10 @@
1
- import { cx } from "./ui2.js";
2
- import { applyNativeProps } from "./ui34.js";
3
- import { defineUniversalComponent, universalPlan, universalValue } from "@nativescript-community/octane";
4
- //#region src/Slider.native.tsrx
5
- var __octaneUniversalPlan0 = universalPlan("nativescript", {
6
- "kind": "host",
7
- "type": "slider",
8
- "bindings": [
9
- ["id", 0],
10
- ["className", 1],
11
- ["style", 2],
12
- ["value", 3],
13
- ["minValue", 4],
14
- ["maxValue", 5],
15
- ["isEnabled", 6],
16
- ["onValueChange", 7],
17
- ["ref", 8]
18
- ]
19
- });
20
- var Slider = defineUniversalComponent("nativescript", function Slider(props) {
21
- return universalValue(__octaneUniversalPlan0, [
22
- props.id,
23
- cx(props.className),
24
- props.style,
25
- props.value,
26
- props.minValue ?? 0,
27
- props.maxValue ?? 100,
28
- props.disabled ? false : true,
29
- (e) => props.onValueChange?.(e.value),
30
- (el) => applyNativeProps(el, props)
31
- ]);
32
- }, { "module": "@nativescript-community/octane" });
1
+ import { isAndroid, isIOS } from "@nativescript/core";
2
+ //#region src/platformProps.native.ts
3
+ /** Apply the matching native escape-hatch bag after the primitive's props. */
4
+ function applyNativeProps(el, props) {
5
+ if (!el) return;
6
+ const bag = isIOS ? props.ios : isAndroid ? props.android : void 0;
7
+ if (bag) Object.assign(el, bag);
8
+ }
33
9
  //#endregion
34
- export { Slider };
10
+ export { applyNativeProps };
@@ -1,17 +1,44 @@
1
- //#region src/icons.ts
2
- /**
3
- * App-owned icon registry. `svg` is SVG path `d` data (not a full SVG
4
- * markup string). Native `font` glyphs render only when the app ships that font.
5
- */
6
- var icons = /* @__PURE__ */ new Map();
7
- function registerIcon(name, glyph) {
8
- icons.set(name, glyph);
9
- }
10
- function registerIcons(record) {
11
- for (const [name, glyph] of Object.entries(record)) icons.set(name, glyph);
12
- }
13
- function getIcon(name) {
14
- return icons.get(name);
1
+ //#region src/popover-position.ts
2
+ var opposite = {
3
+ top: "bottom",
4
+ bottom: "top",
5
+ left: "right",
6
+ right: "left"
7
+ };
8
+ /** Place beside the anchor, flip once when the requested side overflows, then clamp. */
9
+ function positionPopover(anchor, panel, viewport, requested = "bottom", gap = 8) {
10
+ const at = (placement) => {
11
+ switch (placement) {
12
+ case "top": return {
13
+ left: anchor.left,
14
+ top: anchor.top - panel.height - gap
15
+ };
16
+ case "bottom": return {
17
+ left: anchor.left,
18
+ top: anchor.top + anchor.height + gap
19
+ };
20
+ case "left": return {
21
+ left: anchor.left - panel.width - gap,
22
+ top: anchor.top
23
+ };
24
+ case "right": return {
25
+ left: anchor.left + anchor.width + gap,
26
+ top: anchor.top
27
+ };
28
+ }
29
+ throw new Error(`Unknown popover placement: ${placement}`);
30
+ };
31
+ const fits = (position) => position.left >= viewport.left && position.top >= viewport.top && position.left + panel.width <= viewport.left + viewport.width && position.top + panel.height <= viewport.top + viewport.height;
32
+ const preferred = at(requested);
33
+ const placement = fits(preferred) ? requested : opposite[requested];
34
+ const raw = placement === requested ? preferred : at(placement);
35
+ const maxLeft = Math.max(viewport.left, viewport.left + viewport.width - panel.width);
36
+ const maxTop = Math.max(viewport.top, viewport.top + viewport.height - panel.height);
37
+ return {
38
+ left: Math.min(maxLeft, Math.max(viewport.left, raw.left)),
39
+ top: Math.min(maxTop, Math.max(viewport.top, raw.top)),
40
+ placement
41
+ };
15
42
  }
16
43
  //#endregion
17
- export { getIcon, registerIcon, registerIcons };
44
+ export { positionPopover };
@@ -1,68 +1,197 @@
1
1
  import { cx } from "./ui2.js";
2
- import { applyNativeProps } from "./ui34.js";
3
- import { getIcon } from "./ui37.js";
4
- import { defineUniversalComponent, universalIf, universalPlan, universalValue } from "@nativescript-community/octane";
5
- //#region src/Icon.native.tsrx
2
+ import { applyThemeClasses, useThemeScheme } from "./ui31.js";
3
+ import { rootLayoutFor } from "./ui34.js";
4
+ import { applyNativeProps } from "./ui36.js";
5
+ import { positionPopover } from "./ui37.js";
6
+ import { createNativeScriptRoot, defineUniversalComponent, hookSlots, universalPlan, universalValue, useEffect, useRef, useState, withSlot } from "@nativescript-community/octane";
7
+ import { GridLayout } from "@nativescript/core";
8
+ //#region src/Popover.native.tsrx
9
+ var _hs$ = /* @__PURE__ */ hookSlots(8);
10
+ var _h$0 = /* @__PURE__ */ Symbol(_hs$);
11
+ var _h$1 = /* @__PURE__ */ Symbol(_hs$ + 1);
12
+ var _h$2 = /* @__PURE__ */ Symbol(_hs$ + 2);
13
+ var _h$3 = /* @__PURE__ */ Symbol(_hs$ + 3);
14
+ var _h$4 = /* @__PURE__ */ Symbol(_hs$ + 4);
15
+ var _h$5 = /* @__PURE__ */ Symbol(_hs$ + 5);
16
+ var _h$6 = /* @__PURE__ */ Symbol(_hs$ + 6);
17
+ var _h$7 = /* @__PURE__ */ Symbol(_hs$ + 7);
6
18
  var __octaneUniversalPlan0 = universalPlan("nativescript", {
7
19
  "kind": "host",
8
- "type": "label",
9
- "bindings": [
10
- ["id", 0],
11
- ["className", 1],
12
- ["text", 2],
13
- ["style", 3],
14
- ["ref", 4]
15
- ]
20
+ "type": "gridlayout",
21
+ "props": {
22
+ "width": "100%",
23
+ "height": "100%",
24
+ "className": "vx-popover-backdrop"
25
+ },
26
+ "bindings": [["backgroundColor", 0], ["onTap", 1]]
16
27
  });
17
28
  var __octaneUniversalPlan1 = universalPlan("nativescript", {
18
29
  "kind": "host",
19
- "type": "image",
20
- "bindings": [
21
- ["id", 0],
22
- ["className", 1],
23
- ["src", 2],
24
- ["style", 3],
25
- ["ref", 4]
26
- ]
30
+ "type": "absolutelayout",
31
+ "props": {
32
+ "width": "100%",
33
+ "height": "100%"
34
+ },
35
+ "bindings": [["className", 0]],
36
+ "children": [{
37
+ "kind": "slot",
38
+ "slot": 1
39
+ }, {
40
+ "kind": "host",
41
+ "type": "gridlayout",
42
+ "bindings": [
43
+ ["ref", 2],
44
+ ["left", 3],
45
+ ["top", 4],
46
+ ["opacity", 5],
47
+ ["className", 6],
48
+ ["style", 7],
49
+ ["onLoaded", 8],
50
+ ["onLayoutChanged", 9]
51
+ ],
52
+ "children": [{
53
+ "kind": "slot",
54
+ "slot": 10
55
+ }]
56
+ }]
27
57
  });
28
58
  var __octaneUniversalPlan2 = universalPlan("nativescript", {
29
- "kind": "slot",
30
- "slot": 0
59
+ "kind": "range",
60
+ "children": []
31
61
  });
32
- var __octaneUniversalPlan3 = universalPlan("nativescript", {
33
- "kind": "slot",
34
- "slot": 0
35
- });
36
- var Icon = defineUniversalComponent("nativescript", function Icon(props) {
37
- const glyph = getIcon(props.name);
38
- if (!glyph) return null;
39
- const size = props.size ?? 24;
40
- return universalValue(__octaneUniversalPlan3, [universalIf(glyph.font, () => {
41
- return universalValue(__octaneUniversalPlan0, [
42
- props.id,
43
- cx(props.className),
44
- glyph.font.glyph,
45
- {
46
- fontFamily: glyph.font.family,
47
- fontSize: size,
48
- color: props.color
49
- },
50
- (el) => applyNativeProps(el, props)
51
- ]);
52
- }, () => {
53
- return universalValue(__octaneUniversalPlan2, [universalIf(glyph.src, () => {
54
- return universalValue(__octaneUniversalPlan1, [
55
- props.id,
56
- cx(props.className),
57
- glyph.src,
58
- {
59
- width: size,
60
- height: size
61
- },
62
- (el) => applyNativeProps(el, props)
63
- ]);
64
- })]);
65
- })]);
62
+ var PopoverLayer = defineUniversalComponent("nativescript", function PopoverLayer(props) {
63
+ const panelRef = useRef(null, _h$0);
64
+ const [position, setPosition] = useState(null, _h$1);
65
+ const [settled, setSettled] = useState(false, _h$2);
66
+ const update = () => {
67
+ const anchor = props.anchorView;
68
+ const coordinateRoot = anchor?.page?.content;
69
+ if (!anchor?.getLocationRelativeTo || !coordinateRoot?.getActualSize) return;
70
+ const point = anchor.getLocationRelativeTo(coordinateRoot);
71
+ const anchorSize = anchor.getActualSize();
72
+ const panelSize = panelRef.current?.getActualSize?.();
73
+ if (!point || !anchorSize) return;
74
+ const next = positionPopover({
75
+ left: point.x,
76
+ top: point.y,
77
+ width: anchorSize.width,
78
+ height: anchorSize.height
79
+ }, {
80
+ width: panelSize?.width ?? 0,
81
+ height: panelSize?.height ?? 0
82
+ }, {
83
+ left: 0,
84
+ top: 0,
85
+ width: coordinateRoot.getActualSize().width,
86
+ height: coordinateRoot.getActualSize().height
87
+ }, props.placement ?? "bottom");
88
+ setPosition((current) => current?.left === next.left && current?.top === next.top && current?.placement === next.placement ? current : next);
89
+ if (panelSize?.width > 0 && panelSize?.height > 0) setSettled(true);
90
+ };
91
+ useEffect(() => {
92
+ const anchor = props.anchorView;
93
+ if (!props.open || !anchor) return;
94
+ const listeners = [];
95
+ let view = anchor;
96
+ while (view) {
97
+ for (const event of ["layoutChanged", "scroll"]) {
98
+ const handler = () => update();
99
+ view.on?.(event, handler);
100
+ listeners.push({
101
+ view,
102
+ event,
103
+ handler
104
+ });
105
+ }
106
+ view = view.parent;
107
+ }
108
+ update();
109
+ return () => {
110
+ for (const listener of listeners) listener.view.off?.(listener.event, listener.handler);
111
+ };
112
+ }, [
113
+ props.open,
114
+ props.anchorView,
115
+ props.placement,
116
+ props.children,
117
+ props.style
118
+ ], _h$3);
119
+ useEffect(() => {
120
+ applyNativeProps(panelRef.current, props);
121
+ }, [
122
+ props.ios,
123
+ props.android,
124
+ settled
125
+ ], _h$4);
126
+ const dismiss = () => props.onDismiss?.();
127
+ return universalValue(__octaneUniversalPlan1, [
128
+ cx("vx-popover-layer", withSlot(_h$5, useThemeScheme) === "dark" && "ns-dark"),
129
+ (props.dismissOnOutsideTap ?? true) && universalValue(__octaneUniversalPlan0, ["transparent", dismiss]),
130
+ panelRef,
131
+ position?.left ?? 0,
132
+ position?.top ?? 0,
133
+ settled ? 1 : 0,
134
+ cx("vx-popover", props.className),
135
+ props.style,
136
+ update,
137
+ update,
138
+ props.children
139
+ ]);
140
+ }, { "module": "@nativescript-community/octane" });
141
+ var Popover = defineUniversalComponent("nativescript", function Popover(props) {
142
+ const shown = useRef(null, _h$6);
143
+ useEffect(() => {
144
+ const cur = shown.current;
145
+ if (!props.open) {
146
+ if (!cur) return;
147
+ shown.current = null;
148
+ cur.unbindTheme?.();
149
+ const owner = cur.host.parent;
150
+ if (owner?.hasChild?.(cur.host)) owner.close(cur.host).then(() => cur.root.unmount?.(), (error) => {
151
+ console.error("[Popover] close failed", error);
152
+ cur.root.unmount?.();
153
+ });
154
+ else cur.root.unmount?.();
155
+ return;
156
+ }
157
+ const anchor = props.anchor?.current;
158
+ const rl = rootLayoutFor(anchor);
159
+ if (!anchor || !rl) return;
160
+ if (cur) {
161
+ cur.root.render(PopoverLayer, {
162
+ ...props,
163
+ anchorView: anchor
164
+ });
165
+ return;
166
+ }
167
+ const host = new GridLayout();
168
+ const unbindTheme = applyThemeClasses(host, cx("vx-popover-host", props.className));
169
+ host.horizontalAlignment = "stretch";
170
+ host.verticalAlignment = "stretch";
171
+ const root = createNativeScriptRoot(host);
172
+ shown.current = {
173
+ host,
174
+ root,
175
+ unbindTheme
176
+ };
177
+ root.render(PopoverLayer, {
178
+ ...props,
179
+ anchorView: anchor
180
+ });
181
+ rl.open(host).catch((error) => {
182
+ if (shown.current?.host === host) shown.current = null;
183
+ console.error("[Popover] open failed", error);
184
+ root.unmount?.();
185
+ });
186
+ }, [
187
+ props.open,
188
+ props.children,
189
+ props.placement,
190
+ props.className,
191
+ props.style,
192
+ props.dismissOnOutsideTap
193
+ ], _h$7);
194
+ return universalValue(__octaneUniversalPlan2, []);
66
195
  }, { "module": "@nativescript-community/octane" });
67
196
  //#endregion
68
- export { Icon };
197
+ export { Popover };
@@ -1,33 +1,105 @@
1
- import { cx } from "./ui2.js";
2
- import { applyNativeProps } from "./ui34.js";
3
- import { defineUniversalComponent, universalPlan, universalValue } from "@nativescript-community/octane";
4
- import { AccessibilityRole } from "@nativescript/core";
5
- //#region src/Heading.native.tsrx
1
+ import { applyThemeClasses } from "./ui31.js";
2
+ import { topRootLayout } from "./ui34.js";
3
+ import { createNativeScriptRoot, defineUniversalComponent, universalComponent, universalIf, universalPlan, universalProps, universalValue } from "@nativescript-community/octane";
4
+ import { GridLayout, isAndroid, isIOS } from "@nativescript/core";
5
+ //#region src/toast.native.tsrx
6
6
  var __octaneUniversalPlan0 = universalPlan("nativescript", {
7
7
  "kind": "host",
8
8
  "type": "label",
9
- "bindings": [
10
- ["id", 0],
11
- ["className", 1],
12
- ["style", 2],
13
- ["accessibilityRole", 3],
14
- ["ref", 4]
15
- ],
9
+ "props": { "className": "vx-toast" },
16
10
  "children": [{
17
11
  "kind": "slot",
18
- "slot": 5
12
+ "slot": 0
19
13
  }]
20
14
  });
21
- var Heading = defineUniversalComponent("nativescript", function Heading(props) {
22
- const level = props.level ?? 2;
23
- return universalValue(__octaneUniversalPlan0, [
24
- props.id,
25
- cx(`vx-h${level}`, props.className),
26
- props.style,
27
- AccessibilityRole.Header,
28
- (el) => applyNativeProps(el, props),
29
- props.children
30
- ]);
15
+ var __octaneUniversalPlan1 = universalPlan("nativescript", {
16
+ "kind": "host",
17
+ "type": "gridlayout",
18
+ "props": { "className": "vx-toast" },
19
+ "children": [{
20
+ "kind": "slot",
21
+ "slot": 0
22
+ }]
23
+ });
24
+ var __octaneUniversalPlan2 = universalPlan("nativescript", {
25
+ "kind": "slot",
26
+ "slot": 0
27
+ });
28
+ var queue = [];
29
+ var active = null;
30
+ var ToastBody = defineUniversalComponent("nativescript", function ToastBody(props) {
31
+ return universalValue(__octaneUniversalPlan2, [universalIf(typeof props.content === "string", () => {
32
+ return universalValue(__octaneUniversalPlan0, [props.content]);
33
+ }, () => {
34
+ const Component = props.content;
35
+ return universalValue(__octaneUniversalPlan1, [universalComponent("nativescript", Component, universalProps([]))]);
36
+ })]);
31
37
  }, { "module": "@nativescript-community/octane" });
38
+ function finishToast(entry) {
39
+ if (active !== entry) return;
40
+ if (entry.timer !== null) clearTimeout(entry.timer);
41
+ entry.timer = null;
42
+ const rootLayout = topRootLayout();
43
+ const finish = () => {
44
+ entry.unbindTheme?.();
45
+ entry.root.unmount?.();
46
+ if (active === entry) active = null;
47
+ showNext();
48
+ };
49
+ if (rootLayout && rootLayout?.hasChild?.(entry.host)) rootLayout.close(entry.host).then(finish, (error) => {
50
+ console.error("[Toast] close failed", error);
51
+ finish();
52
+ });
53
+ else finish();
54
+ }
55
+ function showNext() {
56
+ if (active || queue.length === 0) return;
57
+ const entry = queue.shift();
58
+ const rootLayout = topRootLayout();
59
+ if (!rootLayout) {
60
+ console.warn("[Toast] RootLayout is not mounted; toast was skipped");
61
+ return;
62
+ }
63
+ const host = new GridLayout();
64
+ const unbindTheme = applyThemeClasses(host, "vx-toast-host");
65
+ host.horizontalAlignment = "stretch";
66
+ host.verticalAlignment = entry.options.position === "top" ? "top" : "bottom";
67
+ host.marginTop = entry.options.position === "top" ? 24 : 0;
68
+ host.marginBottom = entry.options.position === "top" ? 0 : 24;
69
+ Object.assign(host, isIOS ? entry.options.ios : isAndroid ? entry.options.android : void 0);
70
+ const root = createNativeScriptRoot(host);
71
+ const current = {
72
+ ...entry,
73
+ host,
74
+ root,
75
+ timer: null,
76
+ unbindTheme
77
+ };
78
+ active = current;
79
+ root.render(ToastBody, { content: entry.content });
80
+ const open = () => {
81
+ rootLayout.open(host).then(() => {
82
+ if (active === current) current.timer = setTimeout(() => finishToast(current), Math.max(0, entry.options.duration ?? 3e3));
83
+ }, (error) => {
84
+ console.error("[Toast] open failed", error);
85
+ root.unmount?.();
86
+ if (active === current) active = null;
87
+ showNext();
88
+ });
89
+ };
90
+ if (rootLayout.hasChild?.(host)) rootLayout.close(host).then(open, (error) => {
91
+ console.error("[Toast] stale host close failed", error);
92
+ if (active === current) active = null;
93
+ showNext();
94
+ });
95
+ else open();
96
+ }
97
+ function showToast(content, options = {}) {
98
+ queue.push({
99
+ content,
100
+ options
101
+ });
102
+ showNext();
103
+ }
32
104
  //#endregion
33
- export { Heading };
105
+ export { showToast };