@octane-xplat/ui 0.4.0 → 0.6.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 +3 -0
- package/dist/native/Absolute.native.tsrx.js +43 -0
- package/dist/native/Accordion.native.tsrx.js +75 -0
- package/dist/native/ActivityIndicator.native.tsrx.js +35 -0
- package/dist/native/Alert.native.tsrx.js +74 -0
- package/dist/native/Avatar.native.tsrx.js +76 -0
- package/dist/native/AvatarGroup.native.tsrx.js +84 -0
- package/dist/native/Badge.native.tsrx.js +29 -0
- package/dist/native/Banner.native.tsrx.js +80 -0
- package/dist/native/Breadcrumb.native.tsrx.js +66 -0
- package/dist/native/Button.native.tsrx.js +62 -0
- package/dist/native/CameraView.native.tsrx.js +165 -0
- package/dist/native/Card.native.tsrx.js +64 -0
- package/dist/native/Checkbox.native.tsrx.js +58 -0
- package/dist/native/CheckboxGroup.native.tsrx.js +70 -0
- package/dist/native/Chip.native.tsrx.js +83 -0
- package/dist/native/Collapsible.native.tsrx.js +74 -0
- package/dist/native/CommandPalette.native.tsrx.js +143 -0
- package/dist/native/ContextMenu.native.tsrx.js +140 -0
- package/dist/native/Drawer.native.tsrx.js +60 -0
- package/dist/native/DropdownMenu.native.tsrx.js +155 -0
- package/dist/native/Empty.native.tsrx.js +82 -0
- package/dist/native/FieldGroup.native.tsrx.js +39 -0
- package/dist/native/FormField.native.tsrx.js +53 -0
- package/dist/native/{ui8.js → Grid.native.tsrx.js} +19 -8
- package/dist/native/{ui56.js → Heading.native.tsrx.js} +2 -2
- package/dist/native/{ui55.js → Icon.native.tsrx.js} +4 -4
- package/dist/native/{ui29.js → Image.native.tsrx.js} +4 -4
- package/dist/native/InputNumber.native.tsrx.js +146 -0
- package/dist/native/InputRating.native.tsrx.js +74 -0
- package/dist/native/InputTags.native.tsrx.js +131 -0
- package/dist/native/Kbd.native.tsrx.js +29 -0
- package/dist/native/{ui48.js → KeyboardAvoiding.native.tsrx.js} +1 -1
- package/dist/native/{ui17.js → Link.native.tsrx.js} +1 -1
- package/dist/native/{ui52.js → Meter.native.tsrx.js} +2 -2
- package/dist/native/{ui22.js → NavLink.native.tsrx.js} +3 -3
- package/dist/native/NavigationMenu.native.tsrx.js +67 -0
- package/dist/native/{ui35.js → Overlay.native.tsrx.js} +3 -3
- package/dist/native/Pager.native.tsrx.js +282 -0
- package/dist/native/Pagination.native.tsrx.js +107 -0
- package/dist/native/PinInput.native.tsrx.js +94 -0
- package/dist/native/{ui38.js → Popover.native.tsrx.js} +5 -5
- package/dist/native/{ui16.js → Pressable.native.tsrx.js} +21 -15
- package/dist/native/ProgressGroup.native.tsrx.js +66 -0
- package/dist/native/RadioGroup.native.tsrx.js +85 -0
- package/dist/native/{ui15.js → RichText.native.tsrx.js} +15 -22
- package/dist/native/Row.native.tsrx.js +98 -0
- package/dist/native/{ui47.js → SafeArea.native.tsrx.js} +2 -2
- package/dist/native/{ui43.js → Screen.native.tsrx.js} +3 -3
- package/dist/native/{ui26.js → ScrollBox.native.tsrx.js} +1 -1
- package/dist/native/ScrollView.native.tsrx.js +233 -0
- package/dist/native/SearchInput.native.tsrx.js +151 -0
- package/dist/native/SegmentedControl.native.tsrx.js +75 -0
- package/dist/native/Select.native.tsrx.js +202 -0
- package/dist/native/Separator.native.tsrx.js +25 -0
- package/dist/native/{ui60.js → Sheet.native.tsrx.js} +15 -7
- package/dist/native/Skeleton.native.tsrx.js +28 -0
- package/dist/native/Slider.native.tsrx.js +98 -0
- package/dist/native/{ui13.js → Spacer.native.tsrx.js} +2 -2
- package/dist/native/{ui9.js → Stack.native.tsrx.js} +20 -9
- package/dist/native/Stepper.native.tsrx.js +75 -0
- package/dist/native/Switch.native.tsrx.js +33 -0
- package/dist/native/Table.native.tsrx.js +103 -0
- package/dist/native/Tabs.native.tsrx.js +163 -0
- package/dist/native/{ui14.js → Text.native.tsrx.js} +19 -3
- package/dist/native/{ui24.js → TextArea.native.tsrx.js} +19 -17
- package/dist/native/{ui23.js → TextInput.native.tsrx.js} +21 -16
- package/dist/native/Timeline.native.tsrx.js +112 -0
- package/dist/native/Tree.native.tsrx.js +140 -0
- package/dist/native/User.native.tsrx.js +95 -0
- package/dist/native/Video.native.tsrx.js +248 -0
- package/dist/native/{ui6.js → View.native.tsrx.js} +39 -25
- package/dist/native/WebView.native.tsrx.js +110 -0
- package/dist/native/aliases.native.tsrx.js +38 -0
- package/dist/native/android/BottomNavigationView.android.tsrx.js +171 -0
- package/dist/native/android/CircularProgressIndicator.android.tsrx.js +27 -0
- package/dist/native/{ui49.js → android/DrawerLayout.android.tsrx.js} +5 -7
- package/dist/native/android/MaterialDialog.android.tsrx.js +62 -0
- package/dist/native/android/MaterialSwitch.android.tsrx.js +28 -0
- package/dist/native/android/RecyclerView.android.tsrx.js +248 -0
- package/dist/native/android/SeekBar.android.tsrx.js +34 -0
- package/dist/native/android/index.js +9 -0
- package/dist/native/android/openModal.android.js +39 -0
- package/dist/native/camera-permission.native.js +47 -0
- package/dist/native/child-array.js +15 -0
- package/dist/native/{ui3.js → escape-props.native.js} +22 -1
- package/dist/native/icons.js +25 -0
- package/dist/native/{ui11.js → ios/LiquidGlass.ios.tsrx.js} +4 -4
- package/dist/native/{ui12.js → ios/LiquidGlassContainer.ios.tsrx.js} +4 -4
- package/dist/native/ios/SideDrawer.ios.tsrx.js +64 -0
- package/dist/native/{ui50.js → ios/UIActivityIndicatorView.ios.tsrx.js} +5 -5
- package/dist/native/{ui32.js → ios/UIModal.ios.tsrx.js} +10 -6
- package/dist/native/{ui53.js → ios/UISlider.ios.tsrx.js} +5 -5
- package/dist/native/{ui45.js → ios/UISwitch.ios.tsrx.js} +5 -5
- package/dist/native/ios/UITabBar.ios.tsrx.js +166 -0
- package/dist/native/ios/UITableView.ios.tsrx.js +270 -0
- package/dist/native/ios/index.js +11 -0
- package/dist/native/{ui33.js → ios/openModal.ios.js} +5 -4
- package/dist/native/modal-presenter.native.js +19 -0
- package/dist/native/native/index.js +4 -0
- package/dist/native/octane-client-build.json +1 -1
- package/dist/native/pan.native.tsrx.js +66 -0
- package/dist/native/platform.native.js +10 -0
- package/dist/native/refresh-metrics.js +9 -0
- package/dist/native/refresh.native.js +177 -0
- package/dist/native/{ui34.js → root-layout.native.js} +6 -1
- package/dist/native/{ui21.js → route.native.js} +96 -12
- package/dist/native/sheet-detents.native.js +102 -0
- package/dist/native/{ui61.js → sheet-service.native.js} +19 -9
- package/dist/native/sheet-snap.js +35 -0
- package/dist/native/text-write.native.js +27 -0
- package/dist/native/theme/status-bar-scheme.native.js +17 -0
- package/dist/{web/ui29.js → native/theme/theme-scheme.js} +2 -2
- package/dist/native/toast-anchor.native.tsrx.js +185 -0
- package/dist/native/translate.native.js +11 -0
- package/dist/native/ui.js +93 -52
- package/dist/native/use-back.native.tsrx.js +9 -0
- package/dist/native/useMeasure.native.tsrx.js +64 -0
- package/dist/native/video-chrome.native.tsrx.js +365 -0
- package/dist/web/Absolute.web.tsrx.js +47 -0
- package/dist/web/Accordion.web.tsrx.js +85 -0
- package/dist/web/{ui46.js → ActivityIndicator.web.tsrx.js} +1 -1
- package/dist/web/Alert.web.tsrx.js +79 -0
- package/dist/web/Avatar.web.tsrx.js +106 -0
- package/dist/web/AvatarGroup.web.tsrx.js +108 -0
- package/dist/web/Badge.web.tsrx.js +37 -0
- package/dist/web/Banner.web.tsrx.js +79 -0
- package/dist/web/Breadcrumb.web.tsrx.js +135 -0
- package/dist/web/Button.web.tsrx.js +45 -0
- package/dist/web/CameraView.web.tsrx.js +310 -0
- package/dist/web/Card.web.tsrx.js +73 -0
- package/dist/web/Checkbox.web.tsrx.js +89 -0
- package/dist/web/CheckboxGroup.web.tsrx.js +79 -0
- package/dist/web/Chip.web.tsrx.js +64 -0
- package/dist/web/Collapsible.web.tsrx.js +94 -0
- package/dist/web/CommandPalette.web.tsrx.js +125 -0
- package/dist/web/ContextMenu.web.tsrx.js +154 -0
- package/dist/web/{ui44.js → Drawer.web.tsrx.js} +13 -9
- package/dist/web/DropdownMenu.web.tsrx.js +162 -0
- package/dist/web/Empty.web.tsrx.js +89 -0
- package/dist/web/FieldGroup.web.tsrx.js +57 -0
- package/dist/web/FormField.web.tsrx.js +92 -0
- package/dist/web/Grid.web.tsrx.js +65 -0
- package/dist/web/{ui52.js → Heading.web.tsrx.js} +2 -2
- package/dist/web/Icon.web.tsrx.js +273 -0
- package/dist/web/{ui25.js → Image.web.tsrx.js} +2 -2
- package/dist/web/InputNumber.web.tsrx.js +99 -0
- package/dist/web/InputRating.web.tsrx.js +72 -0
- package/dist/web/InputTags.web.tsrx.js +122 -0
- package/dist/web/Kbd.web.tsrx.js +37 -0
- package/dist/web/{ui48.js → Meter.web.tsrx.js} +1 -1
- package/dist/web/{ui19.js → NavLink.web.tsrx.js} +1 -1
- package/dist/web/NavigationMenu.web.tsrx.js +118 -0
- package/dist/web/{ui31.js → Overlay.web.tsrx.js} +2 -2
- package/dist/web/Pager.web.tsrx.js +337 -0
- package/dist/web/Pagination.web.tsrx.js +80 -0
- package/dist/web/PinInput.web.tsrx.js +72 -0
- package/dist/web/{ui33.js → Popover.web.tsrx.js} +3 -3
- package/dist/web/{ui15.js → Pressable.web.tsrx.js} +68 -95
- package/dist/web/ProgressGroup.web.tsrx.js +109 -0
- package/dist/web/RadioGroup.web.tsrx.js +69 -0
- package/dist/web/{ui14.js → RichText.web.tsrx.js} +2 -2
- package/dist/web/Row.web.tsrx.js +250 -0
- package/dist/web/{ui42.js → SafeArea.web.tsrx.js} +1 -1
- package/dist/web/{ui38.js → Screen.web.tsrx.js} +1 -1
- package/dist/web/{ui24.js → ScrollBox.web.tsrx.js} +1 -1
- package/dist/web/ScrollView.web.tsrx.js +388 -0
- package/dist/web/SearchInput.web.tsrx.js +137 -0
- package/dist/web/SegmentedControl.web.tsrx.js +75 -0
- package/dist/web/Select.web.tsrx.js +149 -0
- package/dist/web/Separator.web.tsrx.js +42 -0
- package/dist/web/Sheet.web.tsrx.js +81 -0
- package/dist/web/Skeleton.web.tsrx.js +56 -0
- package/dist/web/Slider.web.tsrx.js +97 -0
- package/dist/web/{ui12.js → Spacer.web.tsrx.js} +1 -1
- package/dist/web/Stack.web.tsrx.js +47 -0
- package/dist/web/Stepper.web.tsrx.js +65 -0
- package/dist/web/Switch.web.tsrx.js +59 -0
- package/dist/web/Table.web.tsrx.js +161 -0
- package/dist/web/{ui39.js → Tabs.web.tsrx.js} +33 -16
- package/dist/web/{ui13.js → Text.web.tsrx.js} +79 -46
- package/dist/web/{ui21.js → TextArea.web.tsrx.js} +4 -4
- package/dist/web/{ui20.js → TextInput.web.tsrx.js} +8 -8
- package/dist/web/Timeline.web.tsrx.js +172 -0
- package/dist/web/Tree.web.tsrx.js +146 -0
- package/dist/web/User.web.tsrx.js +116 -0
- package/dist/web/Video.web.tsrx.js +400 -0
- package/dist/web/View.web.tsrx.js +250 -0
- package/dist/web/WebView.web.tsrx.js +235 -0
- package/dist/web/aliases.web.tsrx.js +24 -0
- package/dist/web/{ui35.js → anim.web.tsrx.js} +3 -2
- package/dist/web/child-array.js +15 -0
- package/dist/web/icons.js +25 -0
- package/dist/web/octane-client-build.json +1 -1
- package/dist/web/pan.web.tsrx.js +66 -0
- package/dist/web/platform.web.js +9 -0
- package/dist/web/refresh-metrics.js +9 -0
- package/dist/web/refresh.web.js +133 -0
- package/dist/web/{ui18.js → route.web.js} +14 -2
- package/dist/web/sheet-detents.web.js +103 -0
- package/dist/web/{ui58.js → sheet-service.web.js} +5 -1
- package/dist/web/sheet-snap.js +35 -0
- package/dist/{native/ui31.js → web/theme/theme-scheme.js} +2 -2
- package/dist/web/toast-anchor.web.tsrx.js +142 -0
- package/dist/web/transform.web.js +43 -0
- package/dist/web/translate.web.js +13 -0
- package/dist/web/ui.js +91 -51
- package/dist/web/use-back.web.tsrx.js +9 -0
- package/dist/web/useMeasure.web.tsrx.js +50 -0
- package/dist/web/video-chrome.web.tsrx.js +207 -0
- package/dist/web/web/Hoverable.web.tsrx.js +150 -0
- package/dist/web/web/Tooltip.web.tsrx.js +183 -0
- package/dist/web/web/index.js +3 -0
- package/package.json +34 -3
- package/src/theme/tokens.css +1599 -194
- package/types/android.d.ts +53 -0
- package/types/index.d.ts +39 -14
- package/types/index.native.d.ts +273 -0
- package/types/index.web.d.ts +272 -0
- package/types/ios.d.ts +59 -0
- package/types/native.d.ts +5 -0
- package/types/props.d.ts +989 -44
- package/types/web.d.ts +17 -0
- package/dist/native/ui10.js +0 -32
- package/dist/native/ui25.js +0 -141
- package/dist/native/ui27.js +0 -61
- package/dist/native/ui39.js +0 -105
- package/dist/native/ui4.js +0 -24
- package/dist/native/ui44.js +0 -267
- package/dist/native/ui54.js +0 -17
- package/dist/native/ui57.js +0 -14
- package/dist/native/ui7.js +0 -52
- package/dist/web/ui10.js +0 -46
- package/dist/web/ui11.js +0 -42
- package/dist/web/ui22.js +0 -108
- package/dist/web/ui23.js +0 -96
- package/dist/web/ui26.js +0 -45
- package/dist/web/ui3.js +0 -31
- package/dist/web/ui30.js +0 -34
- package/dist/web/ui34.js +0 -70
- package/dist/web/ui40.js +0 -43
- package/dist/web/ui43.js +0 -42
- package/dist/web/ui49.js +0 -47
- package/dist/web/ui5.js +0 -168
- package/dist/web/ui50.js +0 -17
- package/dist/web/ui51.js +0 -149
- package/dist/web/ui53.js +0 -17
- package/dist/web/ui57.js +0 -44
- package/dist/web/ui6.js +0 -94
- package/dist/web/ui7.js +0 -62
- package/dist/web/ui8.js +0 -46
- package/dist/web/ui9.js +0 -46
- /package/dist/native/{ui20.js → RouteHost.native.tsrx.js} +0 -0
- /package/dist/native/{ui40.js → anim.native.tsrx.js} +0 -0
- /package/dist/native/{ui2.js → cx.js} +0 -0
- /package/dist/native/{ui5.js → layout-child.native.js} +0 -0
- /package/dist/native/{ui51.js → meter-math.js} +0 -0
- /package/dist/native/{ui36.js → platformProps.native.js} +0 -0
- /package/dist/native/{ui37.js → popover-position.js} +0 -0
- /package/dist/native/{ui19.js → route-table.js} +0 -0
- /package/dist/native/{ui46.js → safeAreaInsets.native.tsrx.js} +0 -0
- /package/dist/native/{ui18.js → stacks.native.js} +0 -0
- /package/dist/native/{ui58.js → store.js} +0 -0
- /package/dist/native/{ui41.js → styled.native.tsrx.js} +0 -0
- /package/dist/native/{ui28.js → svg.native.js} +0 -0
- /package/dist/native/{ui30.js → theme/colorScheme.native.js} +0 -0
- /package/dist/native/{ui59.js → use-store.native.tsrx.js} +0 -0
- /package/dist/native/{ui42.js → windows.native.js} +0 -0
- /package/dist/web/{ui16.js → Link.web.tsrx.js} +0 -0
- /package/dist/web/{ui28.js → cx.js} +0 -0
- /package/dist/web/{ui2.js → escape-props.web.js} +0 -0
- /package/dist/web/{ui4.js → layout-child.web.js} +0 -0
- /package/dist/web/{ui47.js → meter-math.js} +0 -0
- /package/dist/web/{ui45.js → platformProps.web.js} +0 -0
- /package/dist/web/{ui32.js → popover-position.js} +0 -0
- /package/dist/web/{ui17.js → route-table.js} +0 -0
- /package/dist/web/{ui41.js → safeAreaInsets.web.tsrx.js} +0 -0
- /package/dist/web/{ui54.js → stacks.web.js} +0 -0
- /package/dist/web/{ui55.js → store.js} +0 -0
- /package/dist/web/{ui36.js → styled.web.tsrx.js} +0 -0
- /package/dist/web/{ui27.js → theme/colorScheme.web.js} +0 -0
- /package/dist/web/{ui56.js → use-store.web.tsrx.js} +0 -0
- /package/dist/web/{ui37.js → windows.web.js} +0 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { setTranslate } from "./translate.web.js";
|
|
2
|
+
import { dampenPull } from "./refresh-metrics.js";
|
|
3
|
+
//#region src/refresh.web.ts
|
|
4
|
+
var DOCK_ANIM_MS = 180;
|
|
5
|
+
/** Pointer/touch-driven pull-to-refresh for the DOM leaf — the web has no
|
|
6
|
+
* native overscroll, so drag distance translates the scroller inside the
|
|
7
|
+
* clipped wrapper while the self-drawn indicator slides into the gap.
|
|
8
|
+
* `touchmove` must be non-passive: `preventDefault` is what keeps the
|
|
9
|
+
* browser from taking the gesture as a scroll (or Chrome's own
|
|
10
|
+
* pull-to-refresh on Android). Mouse drags ride the pointer events. */
|
|
11
|
+
function createPullToRefresh(host) {
|
|
12
|
+
const { scroller, indicator, cfg } = host;
|
|
13
|
+
if (!scroller || !indicator) return {
|
|
14
|
+
sync: () => {},
|
|
15
|
+
detach: () => {}
|
|
16
|
+
};
|
|
17
|
+
let pulling = false;
|
|
18
|
+
let y0 = 0;
|
|
19
|
+
let pull = 0;
|
|
20
|
+
let docked = false;
|
|
21
|
+
let grace = null;
|
|
22
|
+
const threshold = () => cfg.current.threshold ?? 64;
|
|
23
|
+
/** Resting gap: the strip stays docked while the gesture docked it OR
|
|
24
|
+
* the controlled `refreshing` prop holds it open. */
|
|
25
|
+
const held = () => docked || !!cfg.current.refreshing;
|
|
26
|
+
const applyReveal = (reveal) => {
|
|
27
|
+
setTranslate(indicator, 0, reveal - 64);
|
|
28
|
+
setTranslate(scroller, 0, reveal);
|
|
29
|
+
};
|
|
30
|
+
const settle = (reveal) => {
|
|
31
|
+
for (const el of [scroller, indicator]) el.style.transition = `transform ${DOCK_ANIM_MS}ms ease-out`;
|
|
32
|
+
applyReveal(reveal);
|
|
33
|
+
setTimeout(() => {
|
|
34
|
+
for (const el of [scroller, indicator]) el.style.transition = "";
|
|
35
|
+
}, DOCK_ANIM_MS);
|
|
36
|
+
};
|
|
37
|
+
const dock = () => {
|
|
38
|
+
docked = true;
|
|
39
|
+
pull = 0;
|
|
40
|
+
settle(64);
|
|
41
|
+
};
|
|
42
|
+
const collapse = () => {
|
|
43
|
+
docked = false;
|
|
44
|
+
pull = 0;
|
|
45
|
+
settle(0);
|
|
46
|
+
};
|
|
47
|
+
/** `pull` is drag distance beyond the held baseline — a release only
|
|
48
|
+
* fires `onRefresh` when the user actually pulled (a resting release
|
|
49
|
+
* inside the dock re-fires nothing). */
|
|
50
|
+
const release = () => {
|
|
51
|
+
pulling = false;
|
|
52
|
+
const reveal = pull + (held() ? 64 : 0);
|
|
53
|
+
if (pull > 0 && reveal >= threshold()) {
|
|
54
|
+
cfg.current.onRefresh?.();
|
|
55
|
+
dock();
|
|
56
|
+
if (grace) clearTimeout(grace);
|
|
57
|
+
grace = setTimeout(() => {
|
|
58
|
+
if (!cfg.current.refreshing) collapse();
|
|
59
|
+
}, 350);
|
|
60
|
+
} else if (held()) {
|
|
61
|
+
docked = true;
|
|
62
|
+
pull = 0;
|
|
63
|
+
settle(64);
|
|
64
|
+
} else collapse();
|
|
65
|
+
};
|
|
66
|
+
const begin = (y, prevent) => {
|
|
67
|
+
if (scroller.scrollTop > 0) return;
|
|
68
|
+
pulling = true;
|
|
69
|
+
y0 = y;
|
|
70
|
+
pull = 0;
|
|
71
|
+
prevent?.();
|
|
72
|
+
};
|
|
73
|
+
const move = (y, prevent) => {
|
|
74
|
+
if (!pulling) return;
|
|
75
|
+
const dy = y - y0;
|
|
76
|
+
if (dy <= 0 || scroller.scrollTop > 0) {
|
|
77
|
+
pulling = false;
|
|
78
|
+
pull = 0;
|
|
79
|
+
applyReveal(held() ? 64 : 0);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
prevent();
|
|
83
|
+
pull = dampenPull(dy);
|
|
84
|
+
applyReveal(pull + (held() ? 64 : 0));
|
|
85
|
+
};
|
|
86
|
+
const end = () => {
|
|
87
|
+
if (pulling) release();
|
|
88
|
+
};
|
|
89
|
+
const touchStart = (e) => begin(e.touches[0].clientY);
|
|
90
|
+
const touchMove = (e) => move(e.touches[0].clientY, () => e.preventDefault());
|
|
91
|
+
const touchEnd = () => end();
|
|
92
|
+
const pointerDown = (e) => {
|
|
93
|
+
if (e.pointerType === "mouse" && e.button === 0) begin(e.clientY, () => e.preventDefault());
|
|
94
|
+
};
|
|
95
|
+
const pointerMove = (e) => {
|
|
96
|
+
if (e.pointerType === "mouse") move(e.clientY, () => e.preventDefault());
|
|
97
|
+
};
|
|
98
|
+
const pointerUp = (e) => {
|
|
99
|
+
if (e.pointerType === "mouse") end();
|
|
100
|
+
};
|
|
101
|
+
scroller.addEventListener("touchstart", touchStart, { passive: true });
|
|
102
|
+
scroller.addEventListener("touchmove", touchMove, { passive: false });
|
|
103
|
+
scroller.addEventListener("touchend", touchEnd);
|
|
104
|
+
scroller.addEventListener("touchcancel", touchEnd);
|
|
105
|
+
scroller.addEventListener("pointerdown", pointerDown);
|
|
106
|
+
scroller.addEventListener("pointermove", pointerMove);
|
|
107
|
+
scroller.addEventListener("pointerup", pointerUp);
|
|
108
|
+
scroller.addEventListener("pointercancel", pointerUp);
|
|
109
|
+
return {
|
|
110
|
+
sync: () => {
|
|
111
|
+
if (cfg.current.refreshing) {
|
|
112
|
+
if (grace) clearTimeout(grace);
|
|
113
|
+
if (!docked && !pulling) dock();
|
|
114
|
+
} else if (docked && !pulling) collapse();
|
|
115
|
+
},
|
|
116
|
+
detach: () => {
|
|
117
|
+
if (grace) clearTimeout(grace);
|
|
118
|
+
scroller.removeEventListener("touchstart", touchStart);
|
|
119
|
+
scroller.removeEventListener("touchmove", touchMove);
|
|
120
|
+
scroller.removeEventListener("touchend", touchEnd);
|
|
121
|
+
scroller.removeEventListener("touchcancel", touchEnd);
|
|
122
|
+
scroller.removeEventListener("pointerdown", pointerDown);
|
|
123
|
+
scroller.removeEventListener("pointermove", pointerMove);
|
|
124
|
+
scroller.removeEventListener("pointerup", pointerUp);
|
|
125
|
+
scroller.removeEventListener("pointercancel", pointerUp);
|
|
126
|
+
scroller.style.transition = "";
|
|
127
|
+
indicator.style.transition = "";
|
|
128
|
+
applyReveal(0);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
//#endregion
|
|
133
|
+
export { createPullToRefresh };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RouteRedirect, buildRoutePath, layoutChain, linkPath, matchUrl } from "./
|
|
1
|
+
import { RouteRedirect, buildRoutePath, layoutChain, linkPath, matchUrl } from "./route-table.js";
|
|
2
2
|
import { hookSlots, useSyncExternalStore } from "octane";
|
|
3
3
|
//#region src/route.web.ts
|
|
4
4
|
var screens = {};
|
|
@@ -162,6 +162,18 @@ function presentationFor(name) {
|
|
|
162
162
|
function popRoute(_stack = "root") {
|
|
163
163
|
history.back();
|
|
164
164
|
}
|
|
165
|
+
var backInterceptorWarned = false;
|
|
166
|
+
/** No-op twin of the native leaf. Browser back is already real history —
|
|
167
|
+
* there is no hardware-back event to intercept on web, so registered
|
|
168
|
+
* interceptors never fire. Warns once so a mistaken call site isn't
|
|
169
|
+
* silently absent. */
|
|
170
|
+
function addBackInterceptor(_fn) {
|
|
171
|
+
if (!backInterceptorWarned) {
|
|
172
|
+
backInterceptorWarned = true;
|
|
173
|
+
console.warn("[octane-xplat] addBackInterceptor is a no-op on web — browser back is URL history, not an interceptable event.");
|
|
174
|
+
}
|
|
175
|
+
return () => {};
|
|
176
|
+
}
|
|
165
177
|
window.addEventListener("popstate", () => {
|
|
166
178
|
saveScroll();
|
|
167
179
|
historyDepth = history.state?.__octaneXplatDepth ?? 0;
|
|
@@ -237,4 +249,4 @@ var _h$0 = /* @__PURE__ */ Symbol(_hs$);
|
|
|
237
249
|
var _h$1 = /* @__PURE__ */ Symbol(_hs$ + 1);
|
|
238
250
|
var _h$2 = /* @__PURE__ */ Symbol(_hs$ + 2);
|
|
239
251
|
//#endregion
|
|
240
|
-
export { canGoBack, currentModalRoute, currentRoute, hrefFor, layoutsFor, popRoute, pushDeepLink, pushRoute, redirect, registerRoutes, registerScreens, routeFor, routeStacks, screenFor, useCanGoBack, useModalRoute, useRoute };
|
|
252
|
+
export { addBackInterceptor, canGoBack, currentModalRoute, currentRoute, hrefFor, layoutsFor, popRoute, pushDeepLink, pushRoute, redirect, registerRoutes, registerScreens, routeFor, routeStacks, screenFor, useCanGoBack, useModalRoute, useRoute };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { setTranslate } from "./translate.web.js";
|
|
2
|
+
import { detentOffset, normalizeDetents, snapDetentIndex } from "./sheet-snap.js";
|
|
3
|
+
//#region src/sheet-detents.web.ts
|
|
4
|
+
var SNAP_MS = 200;
|
|
5
|
+
/** Drag-to-snap detents on a `.vx-sheet` panel: a self-drawn grabber strip
|
|
6
|
+
* (the only drag target — it never fights inner scrolling) drives the
|
|
7
|
+
* panel's translateY; the panel is sized to the largest detent and parked
|
|
8
|
+
* at the offset for the current one. `closeNow` fires after the dismiss
|
|
9
|
+
* slide-out — the caller decides what closing means (declarative
|
|
10
|
+
* `onDismiss` or the `openSheet` resolution). In-window on every target —
|
|
11
|
+
* the OS detent presentations (UISheetPresentationController /
|
|
12
|
+
* BottomSheetDialog) host a modal VC/dialog window, not a RootLayout
|
|
13
|
+
* child, so the snap mechanics stay self-drawn for pixel parity. */
|
|
14
|
+
function attachSheetDetents(panel, detents, closeNow) {
|
|
15
|
+
const sorted = normalizeDetents(detents);
|
|
16
|
+
if (!sorted.length) return { detach: () => {} };
|
|
17
|
+
const vh = () => panel.parentElement?.clientHeight || window.innerHeight || 1;
|
|
18
|
+
const max = sorted[sorted.length - 1];
|
|
19
|
+
panel.classList.add("vx-sheet-detents");
|
|
20
|
+
panel.style.height = `${max * 100}%`;
|
|
21
|
+
const grabber = document.createElement("div");
|
|
22
|
+
grabber.className = "vx-sheet-grabber";
|
|
23
|
+
const grip = document.createElement("div");
|
|
24
|
+
grip.className = "vx-sheet-grip";
|
|
25
|
+
grabber.appendChild(grip);
|
|
26
|
+
panel.appendChild(grabber);
|
|
27
|
+
let cur = 0;
|
|
28
|
+
let ty = 0;
|
|
29
|
+
let dragging = false;
|
|
30
|
+
let y0 = 0;
|
|
31
|
+
let ty0 = 0;
|
|
32
|
+
let vy = 0;
|
|
33
|
+
let lastY = 0;
|
|
34
|
+
let lastT = 0;
|
|
35
|
+
const applyTy = (value) => {
|
|
36
|
+
ty = value;
|
|
37
|
+
setTranslate(panel, 0, value);
|
|
38
|
+
};
|
|
39
|
+
const animateTo = (value, then) => {
|
|
40
|
+
panel.style.transition = `transform ${SNAP_MS}ms ease-out`;
|
|
41
|
+
applyTy(value);
|
|
42
|
+
setTimeout(() => {
|
|
43
|
+
panel.style.transition = "";
|
|
44
|
+
then?.();
|
|
45
|
+
}, SNAP_MS);
|
|
46
|
+
};
|
|
47
|
+
const down = (e) => {
|
|
48
|
+
if (e.pointerType === "mouse" && e.button !== 0) return;
|
|
49
|
+
dragging = true;
|
|
50
|
+
grabber.setPointerCapture?.(e.pointerId);
|
|
51
|
+
y0 = e.clientY;
|
|
52
|
+
lastY = e.clientY;
|
|
53
|
+
lastT = Date.now();
|
|
54
|
+
ty0 = ty;
|
|
55
|
+
vy = 0;
|
|
56
|
+
panel.style.transition = "";
|
|
57
|
+
e.preventDefault();
|
|
58
|
+
};
|
|
59
|
+
const move = (e) => {
|
|
60
|
+
if (!dragging) return;
|
|
61
|
+
const now = Date.now();
|
|
62
|
+
const dt = (now - lastT) / 1e3;
|
|
63
|
+
if (dt > 0) vy = vy * .7 + (e.clientY - lastY) / dt * .3;
|
|
64
|
+
lastY = e.clientY;
|
|
65
|
+
lastT = now;
|
|
66
|
+
applyTy(Math.min(Math.max(ty0 + (e.clientY - y0), 0), vh()));
|
|
67
|
+
e.preventDefault();
|
|
68
|
+
};
|
|
69
|
+
const up = () => {
|
|
70
|
+
if (!dragging) return;
|
|
71
|
+
dragging = false;
|
|
72
|
+
const next = snapDetentIndex(ty, vy, sorted, vh());
|
|
73
|
+
if (next < 0) animateTo(vh(), closeNow);
|
|
74
|
+
else {
|
|
75
|
+
cur = next;
|
|
76
|
+
animateTo(detentOffset(sorted, cur, vh()));
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
const pinGrabber = () => {
|
|
80
|
+
grabber.style.top = `${panel.scrollTop}px`;
|
|
81
|
+
};
|
|
82
|
+
panel.addEventListener("scroll", pinGrabber);
|
|
83
|
+
grabber.addEventListener("pointerdown", down);
|
|
84
|
+
grabber.addEventListener("pointermove", move);
|
|
85
|
+
grabber.addEventListener("pointerup", up);
|
|
86
|
+
grabber.addEventListener("pointercancel", up);
|
|
87
|
+
applyTy(vh());
|
|
88
|
+
const raf = requestAnimationFrame(() => animateTo(detentOffset(sorted, cur, vh())));
|
|
89
|
+
return { detach: () => {
|
|
90
|
+
cancelAnimationFrame(raf);
|
|
91
|
+
panel.removeEventListener("scroll", pinGrabber);
|
|
92
|
+
grabber.removeEventListener("pointerdown", down);
|
|
93
|
+
grabber.removeEventListener("pointermove", move);
|
|
94
|
+
grabber.removeEventListener("pointerup", up);
|
|
95
|
+
grabber.removeEventListener("pointercancel", up);
|
|
96
|
+
grabber.remove();
|
|
97
|
+
panel.classList.remove("vx-sheet-detents");
|
|
98
|
+
panel.style.height = "";
|
|
99
|
+
panel.style.transition = "";
|
|
100
|
+
} };
|
|
101
|
+
}
|
|
102
|
+
//#endregion
|
|
103
|
+
export { attachSheetDetents };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { applyThemeClasses } from "./
|
|
1
|
+
import { applyThemeClasses } from "./theme/theme-scheme.js";
|
|
2
|
+
import { attachSheetDetents } from "./sheet-detents.web.js";
|
|
2
3
|
import { createRoot } from "octane";
|
|
3
4
|
//#region src/sheet-service.web.ts
|
|
4
5
|
var active = /* @__PURE__ */ new Set();
|
|
@@ -13,12 +14,14 @@ var openSheet = (Component, params, options = {}) => new Promise((resolve) => {
|
|
|
13
14
|
const unbindTheme = applyThemeClasses(layer, "vx-sheet-layer");
|
|
14
15
|
const panel = document.createElement("div");
|
|
15
16
|
panel.className = "vx-sheet";
|
|
17
|
+
if (options.detents?.length) panel.classList.add("vx-sheet-detents");
|
|
16
18
|
let finished = false;
|
|
17
19
|
const finish = (result) => {
|
|
18
20
|
if (finished) return;
|
|
19
21
|
finished = true;
|
|
20
22
|
active.delete(entry);
|
|
21
23
|
unbindTheme();
|
|
24
|
+
detents?.detach();
|
|
22
25
|
root.unmount();
|
|
23
26
|
layer.remove();
|
|
24
27
|
resolve(result);
|
|
@@ -35,6 +38,7 @@ var openSheet = (Component, params, options = {}) => new Promise((resolve) => {
|
|
|
35
38
|
}
|
|
36
39
|
layer.appendChild(panel);
|
|
37
40
|
document.body.appendChild(layer);
|
|
41
|
+
const detents = options.detents?.length ? attachSheetDetents(panel, options.detents, () => finish()) : null;
|
|
38
42
|
const root = createRoot(panel);
|
|
39
43
|
root.render(Component, {
|
|
40
44
|
params,
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Sorted, filtered, deduped detent fractions. Empty → the caller keeps
|
|
2
|
+
* the content-sized sheet behavior (detents off). */
|
|
3
|
+
function normalizeDetents(input) {
|
|
4
|
+
if (!input?.length) return [];
|
|
5
|
+
return [...new Set(input.filter((d) => d > 0 && d <= 1))].sort((a, b) => a - b);
|
|
6
|
+
}
|
|
7
|
+
/** Resting translateY for a detent: the panel is `max * vh` tall, so the
|
|
8
|
+
* portion below the screen edge is `(max - detent) * vh`. */
|
|
9
|
+
function detentOffset(detents, index, vh) {
|
|
10
|
+
return (detents[detents.length - 1] - detents[index]) * vh;
|
|
11
|
+
}
|
|
12
|
+
/** Snap target for a release at translateY `ty` with vertical velocity
|
|
13
|
+
* `vy` (positive = dragging down). Returns the detent index, or -1 to
|
|
14
|
+
* dismiss: released below half of the smallest detent, or a downward
|
|
15
|
+
* fling while at/below it. */
|
|
16
|
+
function snapDetentIndex(ty, vy, detents, vh) {
|
|
17
|
+
const max = detents[detents.length - 1];
|
|
18
|
+
const frac = Math.min(Math.max(max - ty / vh, 0), 1);
|
|
19
|
+
if (vy > 500) {
|
|
20
|
+
let i = -1;
|
|
21
|
+
while (i + 1 < detents.length && detents[i + 1] < frac - 1e-6) i++;
|
|
22
|
+
return i;
|
|
23
|
+
}
|
|
24
|
+
if (vy < -500) {
|
|
25
|
+
let i = detents.length - 1;
|
|
26
|
+
while (i - 1 >= 0 && detents[i - 1] > frac + 1e-6) i--;
|
|
27
|
+
return i;
|
|
28
|
+
}
|
|
29
|
+
if (frac < detents[0] * .5) return -1;
|
|
30
|
+
let best = 0;
|
|
31
|
+
for (let i = 1; i < detents.length; i++) if (Math.abs(detents[i] - frac) < Math.abs(detents[best] - frac)) best = i;
|
|
32
|
+
return best;
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { detentOffset, normalizeDetents, snapDetentIndex };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { getColorScheme, subscribeSystemScheme } from "./colorScheme.web.js";
|
|
2
|
+
import { cx } from "../cx.js";
|
|
3
3
|
import { hookSlots, useSyncExternalStore } from "octane";
|
|
4
4
|
//#region src/theme/theme-scheme.ts
|
|
5
5
|
var preference = "system";
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { cx } from "./cx.js";
|
|
2
|
+
import { applyThemeClasses } from "./theme/theme-scheme.js";
|
|
3
|
+
import { Popover } from "./Popover.web.tsrx.js";
|
|
4
|
+
import { bag1, bag3, clone, componentSlot, componentSlotVoid, createRoot, ifBlock, markChildrenBlock, template } from "octane";
|
|
5
|
+
import { childTextHoleUpdate } from "octane/internal/client";
|
|
6
|
+
//#region src/toast-anchor.web.tsrx
|
|
7
|
+
var _t$0 = /* @__PURE__ */ template("<div class=\"vx-toast\"></div>");
|
|
8
|
+
function __then$3(__props, __s, __extra) {
|
|
9
|
+
const props = __extra[0];
|
|
10
|
+
let _b = __s.slots[0];
|
|
11
|
+
if (_b === void 0) {
|
|
12
|
+
let _m0;
|
|
13
|
+
const _root = clone(_t$0);
|
|
14
|
+
_m0 = _root;
|
|
15
|
+
_b = bag3(__s, _root, _m0, null, void 0);
|
|
16
|
+
}
|
|
17
|
+
{
|
|
18
|
+
const _v = props.content;
|
|
19
|
+
_b.b = childTextHoleUpdate(__s, 1, _b.a, _v, _b.b, _b.c);
|
|
20
|
+
_b.c = _v;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function __else$5(__props, __s, __extra) {
|
|
24
|
+
const Component = __extra[0].content;
|
|
25
|
+
let _b = __s.slots[0];
|
|
26
|
+
if (_b === void 0) {
|
|
27
|
+
let _m0;
|
|
28
|
+
const _root = clone(_t$0);
|
|
29
|
+
_m0 = _root;
|
|
30
|
+
_b = bag1(__s, _root, _m0);
|
|
31
|
+
}
|
|
32
|
+
componentSlot(__s, 1, _b.a, Component, {}, void 0, void 0, void 0, void 0, void 0, "c:46bd91a2");
|
|
33
|
+
}
|
|
34
|
+
var __childrenBody = {};
|
|
35
|
+
function __then$0(__props, __s, __extra) {
|
|
36
|
+
const __block = __s.block;
|
|
37
|
+
const props = __extra[0];
|
|
38
|
+
function __children$2(__props, __s, __extra) {
|
|
39
|
+
const __block = __s.block;
|
|
40
|
+
ifBlock(__s, 0, __block.parentNode, typeof props.content === "string", __then$3, __else$5, __block.endMarker, [props]);
|
|
41
|
+
}
|
|
42
|
+
componentSlotVoid(__s, 0, __block.parentNode, Popover, {
|
|
43
|
+
"open": props.open,
|
|
44
|
+
"anchor": props.options.anchor,
|
|
45
|
+
"placement": props.options.placement ?? placementFor(props.options.position),
|
|
46
|
+
"dismissOnOutsideTap": false,
|
|
47
|
+
"children": markChildrenBlock(__children$2, __childrenBody)
|
|
48
|
+
}, __block.endMarker, void 0, void 0, void 0, void 0, "c:fb0a2e5d");
|
|
49
|
+
}
|
|
50
|
+
function __then$9(__props, __s, __extra) {
|
|
51
|
+
const props = __extra[0];
|
|
52
|
+
let _b = __s.slots[0];
|
|
53
|
+
if (_b === void 0) {
|
|
54
|
+
let _m0;
|
|
55
|
+
const _root = clone(_t$0);
|
|
56
|
+
_m0 = _root;
|
|
57
|
+
_b = bag3(__s, _root, _m0, null, void 0);
|
|
58
|
+
}
|
|
59
|
+
{
|
|
60
|
+
const _v = props.content;
|
|
61
|
+
_b.b = childTextHoleUpdate(__s, 1, _b.a, _v, _b.b, _b.c);
|
|
62
|
+
_b.c = _v;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function __else$11(__props, __s, __extra) {
|
|
66
|
+
const Component = __extra[0].content;
|
|
67
|
+
let _b = __s.slots[0];
|
|
68
|
+
if (_b === void 0) {
|
|
69
|
+
let _m0;
|
|
70
|
+
const _root = clone(_t$0);
|
|
71
|
+
_m0 = _root;
|
|
72
|
+
_b = bag1(__s, _root, _m0);
|
|
73
|
+
}
|
|
74
|
+
componentSlot(__s, 1, _b.a, Component, {}, void 0, void 0, void 0, void 0, void 0, "c:75cbf224");
|
|
75
|
+
}
|
|
76
|
+
function __else$8(__props, __s, __extra) {
|
|
77
|
+
const __block = __s.block;
|
|
78
|
+
const props = __extra[0];
|
|
79
|
+
ifBlock(__s, 0, __block.parentNode, typeof props.content === "string", __then$9, __else$11, __block.endMarker, __extra);
|
|
80
|
+
}
|
|
81
|
+
var queue = [];
|
|
82
|
+
var active = false;
|
|
83
|
+
var ToastBody = function ToastBody(props, __s, __extra) {
|
|
84
|
+
const __block = __s.block;
|
|
85
|
+
ifBlock(__s, 0, __block.parentNode, props.options.anchor, __then$0, __else$8, __block.endMarker, [props]);
|
|
86
|
+
};
|
|
87
|
+
function placementFor(position = "bottom") {
|
|
88
|
+
return position.startsWith("top") ? "top" : "bottom";
|
|
89
|
+
}
|
|
90
|
+
function applyWebProps(host, props) {
|
|
91
|
+
for (const [key, value] of Object.entries(props ?? {})) if (key.includes("-")) host.setAttribute(key, String(value));
|
|
92
|
+
else host[key] = value;
|
|
93
|
+
}
|
|
94
|
+
function alignmentFor(position = "bottom") {
|
|
95
|
+
if (position.endsWith("-start")) return "flex-start";
|
|
96
|
+
if (position.endsWith("-end")) return "flex-end";
|
|
97
|
+
return "center";
|
|
98
|
+
}
|
|
99
|
+
function showNext() {
|
|
100
|
+
if (active || queue.length === 0) return;
|
|
101
|
+
active = true;
|
|
102
|
+
const entry = queue.shift();
|
|
103
|
+
const anchored = Boolean(entry.options.anchor);
|
|
104
|
+
const host = document.createElement("div");
|
|
105
|
+
const position = entry.options.position ?? "bottom";
|
|
106
|
+
const unbindTheme = applyThemeClasses(host, cx("vx-toast-host", placementFor(position) === "top" ? "vx-toast-top" : "vx-toast-bottom"));
|
|
107
|
+
applyWebProps(host, entry.options.web);
|
|
108
|
+
if (anchored) host.style.display = "none";
|
|
109
|
+
else host.style.justifyContent = alignmentFor(position);
|
|
110
|
+
document.body.appendChild(host);
|
|
111
|
+
const root = createRoot(host);
|
|
112
|
+
root.render(ToastBody, {
|
|
113
|
+
...entry,
|
|
114
|
+
open: true
|
|
115
|
+
});
|
|
116
|
+
const finish = () => {
|
|
117
|
+
const cleanup = () => {
|
|
118
|
+
unbindTheme();
|
|
119
|
+
root.unmount();
|
|
120
|
+
host.remove();
|
|
121
|
+
active = false;
|
|
122
|
+
showNext();
|
|
123
|
+
};
|
|
124
|
+
if (anchored) {
|
|
125
|
+
root.render(ToastBody, {
|
|
126
|
+
...entry,
|
|
127
|
+
open: false
|
|
128
|
+
});
|
|
129
|
+
setTimeout(cleanup, 0);
|
|
130
|
+
} else cleanup();
|
|
131
|
+
};
|
|
132
|
+
setTimeout(finish, Math.max(0, entry.options.duration ?? 3e3));
|
|
133
|
+
}
|
|
134
|
+
function showToast(content, options = {}) {
|
|
135
|
+
queue.push({
|
|
136
|
+
content,
|
|
137
|
+
options
|
|
138
|
+
});
|
|
139
|
+
showNext();
|
|
140
|
+
}
|
|
141
|
+
//#endregion
|
|
142
|
+
export { showToast };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
//#region src/transform.web.ts
|
|
2
|
+
/** Per-element transform composition for imperative writes. The DOM has a
|
|
3
|
+
* single `transform` string where native has discrete view props, so web
|
|
4
|
+
* keeps the last-written value per transform prop and re-joins them —
|
|
5
|
+
* an AnimatedValue on `rotate` and a setTranslate drag on the same
|
|
6
|
+
* element don't clobber each other. */
|
|
7
|
+
var transformProps = {
|
|
8
|
+
translateX: (v) => `translateX(${v}px)`,
|
|
9
|
+
translateY: (v) => `translateY(${v}px)`,
|
|
10
|
+
translateZ: (v) => `translateZ(${v}px)`,
|
|
11
|
+
scale: (v) => `scale(${v})`,
|
|
12
|
+
scaleX: (v) => `scaleX(${v})`,
|
|
13
|
+
scaleY: (v) => `scaleY(${v})`,
|
|
14
|
+
rotate: (v) => `rotate(${v}deg)`,
|
|
15
|
+
rotateX: (v) => `rotateX(${v}deg)`,
|
|
16
|
+
rotateY: (v) => `rotateY(${v}deg)`,
|
|
17
|
+
skewX: (v) => `skewX(${v}deg)`,
|
|
18
|
+
skewY: (v) => `skewY(${v}deg)`
|
|
19
|
+
};
|
|
20
|
+
var transformStates = /* @__PURE__ */ new WeakMap();
|
|
21
|
+
/** Write one transform prop without disturbing the element's other
|
|
22
|
+
* transform components (or its stylesheet/base transform). */
|
|
23
|
+
function writeTransformProp(el, prop, value) {
|
|
24
|
+
if (Object.prototype.hasOwnProperty.call(transformProps, prop)) {
|
|
25
|
+
const transformProp = prop;
|
|
26
|
+
let state = transformStates.get(el);
|
|
27
|
+
if (!state) {
|
|
28
|
+
const computed = getComputedStyle(el).transform;
|
|
29
|
+
state = {
|
|
30
|
+
base: computed === "none" ? "" : computed,
|
|
31
|
+
values: /* @__PURE__ */ new Map()
|
|
32
|
+
};
|
|
33
|
+
transformStates.set(el, state);
|
|
34
|
+
}
|
|
35
|
+
state.values.set(transformProp, value);
|
|
36
|
+
const transforms = Object.entries(transformProps).filter(([name]) => state.values.has(name)).map(([name, toTransform]) => toTransform(state.values.get(name)));
|
|
37
|
+
el.style.transform = [state.base, ...transforms].filter(Boolean).join(" ");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
el.style[prop] = value;
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { writeTransformProp };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { writeTransformProp } from "./transform.web.js";
|
|
2
|
+
//#region src/translate.web.ts
|
|
3
|
+
/** Imperative translate write on a bound view — the gesture seam. Called
|
|
4
|
+
* per frame from pan handlers (docs/animation-gestures.md: animation
|
|
5
|
+
* writes imperative, state stays declarative). Composes with other
|
|
6
|
+
* transform writes on the same element via ./transform.web. */
|
|
7
|
+
var setTranslate = (el, x = 0, y = 0) => {
|
|
8
|
+
if (!el) return;
|
|
9
|
+
writeTransformProp(el, "translateX", x);
|
|
10
|
+
writeTransformProp(el, "translateY", y);
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { setTranslate };
|