Skip to content

Commit c3e7eb7

Browse files
committed
upd
1 parent 2d8021d commit c3e7eb7

13 files changed

Lines changed: 370 additions & 113 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Modern Metro design library for React.js, with look and feel close to Windows 8.
1717
- [Scale factor](./docs/scale-factor.md)
1818
- [Escapable](./docs/escapable.md)
1919
- [Button navigable](./docs/button-navigable.md)
20+
- [Scrolling](./docs/scrolling.md)
21+
- [Themes](./docs/themes.md)
2022
- Components
2123
- [PopoverMenu](./docs/components/popover-menu.md)
2224

docs/scrolling.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Scrolling
2+
3+
## Horizontal scrolling
4+
5+
- Container components have a `wheelHorizontal` option which when set to `true` makes horizontal scrolling through the mouse wheel possible, with a fast transition and pressure.
6+
7+
## Vertical scrolling
8+
9+
- Enhance wheel scrolling on vertical containers through the `wheelVertical` option, by setting it to `true`.
10+
- Add `wheelVertical` to any parents as needed, since they may get the most scroll available instead.

docs/themes.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Themes
2+
3+
## Where text color applies
4+
5+
The cascading `color` property is set to the surrounding theme's foreground within:
6+
7+
- `Root`
8+
- `Group`
9+
- `HGroup`
10+
- `VGroup`
11+
12+
If you see anything odd in terms of color, perhaps you've provided a theme without a child component like these above.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@hydroperx/metrodesign",
3-
"version": "1.0.0",
3+
"version": "1.0.1",
44
"type": "module",
55
"files": [
66
"/dist"

src/components/Button.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ const BigButton = styled.button<ButtonCSSProps>`
429429
padding: 0.3rem 0.6rem;
430430
border: none;
431431
border-radius: 0;
432-
font-size: 1.8rem;
432+
font-size: 4.5rem;
433433
font-weight: lighter;
434434
}
435435

src/components/DesktopGroup.tsx

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
import React from "react";
33
import { styled } from "styled-components";
44

5+
// local
6+
import { EnhancedWheel } from "../utils/EnhancedWheel";
7+
58
/**
69
* `DesktopGroup` is used for displaying UI
710
* only when the screen orientation is landscape.
@@ -12,12 +15,54 @@ export function DesktopGroup(params: {
1215
*/
1316
inline?: boolean,
1417

18+
/**
19+
* Enables horizontal scrolling through the mouse wheel.
20+
*/
21+
wheelHorizontal?: boolean,
22+
23+
/**
24+
* For vertically-scrollable groups, makes vertical scrolling through
25+
* the mouse wheel more faster and smoother.
26+
*/
27+
wheelVertical?: boolean,
28+
1529
id?: string,
1630
className?: string,
1731
style?: React.CSSProperties,
1832
children?: React.ReactNode,
1933
ref?: React.Ref<null | HTMLDivElement>,
2034
}): React.ReactNode {
35+
// basics
36+
const div_ref = React.useRef<null | HTMLDivElement>(null);
37+
38+
// Handle mouse wheel (horizontal)
39+
React.useEffect(() => {
40+
const div_el = div_ref.current!;
41+
let enhanced_wheel = null;
42+
if (params.wheelHorizontal) {
43+
enhanced_wheel = new EnhancedWheel(div_el, "horizontal");
44+
}
45+
return () => {
46+
if (enhanced_wheel) {
47+
enhanced_wheel.destroy();
48+
}
49+
};
50+
}, [params.wheelHorizontal]);
51+
52+
// Handle mouse wheel (vertical)
53+
React.useEffect(() => {
54+
const div_el = div_ref.current!;
55+
let enhanced_wheel = null;
56+
if (params.wheelVertical) {
57+
enhanced_wheel = new EnhancedWheel(div_el, "vertical");
58+
}
59+
return () => {
60+
if (enhanced_wheel) {
61+
enhanced_wheel.destroy();
62+
}
63+
};
64+
}, [params.wheelVertical]);
65+
2166
return (
2267
<_Div
2368
className={[
@@ -27,7 +72,11 @@ export function DesktopGroup(params: {
2772
].join(" ")}
2873
id={params.id}
2974
style={params.style}
30-
ref={params.ref}>
75+
ref={node => {
76+
div_ref.current = node;
77+
if (typeof params.ref == "function") params.ref(node);
78+
else if (params.ref) params.ref.current = node;
79+
}}>
3180

3281
{params.children}
3382
</_Div>

src/components/Group.tsx

Lines changed: 31 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
// third-party
22
import * as React from "react";
33
import { styled } from "styled-components";
4-
import gsap from "gsap";
5-
import { ScrollToPlugin } from "gsap/dist/ScrollToPlugin";
64

75
// local
86
import { Theme, ThemeContext } from "../theme/Theme";
97
import { AnchorSkin } from "../skins/AnchorSkin";
108
import { ScrollbarSkin } from "../skins/ScrollbarSkin";
119
import { SelectionSkin } from "../skins/SelectionSkin";
1210
import { TableSkin } from "../skins/TableSkin";
11+
import { EnhancedWheel } from "../utils/EnhancedWheel";
1312
import * as ColorUtils from "../utils/ColorUtils";
1413
import * as MathUtils from "../utils/MathUtils";
1514
import * as REMConvert from "../utils/REMConvert";
@@ -82,6 +81,12 @@ export function Group(params: {
8281
*/
8382
wheelHorizontal?: boolean,
8483

84+
/**
85+
* For vertically-scrollable groups, makes vertical scrolling through
86+
* the mouse wheel more faster and smoother.
87+
*/
88+
wheelVertical?: boolean,
89+
8590
contextMenu?: React.MouseEventHandler<HTMLDivElement>,
8691
click?: React.MouseEventHandler<HTMLDivElement>,
8792
mouseOver?: React.MouseEventHandler<HTMLDivElement>,
@@ -139,61 +144,33 @@ export function Group(params: {
139144
"opacity " + COMMON_DELAY + "ms " + params.easePosition
140145
}
141146

142-
// Handle mouse wheel
143-
React.useEffect(() => {
144-
const div_el = div.current!;
145-
let added_handler = false;
146-
if (params.wheelHorizontal) {
147-
div_el.addEventListener("wheel", wheel, { passive: false });
148-
added_handler = true;
149-
}
150-
return () => {
151-
if (added_handler) {
152-
div_el.removeEventListener("wheel", wheel);
147+
// Handle mouse wheel (horizontal)
148+
React.useEffect(() => {
149+
const div_el = div.current!;
150+
let enhanced_wheel = null;
151+
if (params.wheelHorizontal) {
152+
enhanced_wheel = new EnhancedWheel(div_el, "horizontal");
153153
}
154-
};
155-
}, [params.wheelHorizontal]);
156-
const last_wheel_timestamp = React.useRef<number>(-1);
157-
const wheel_multiplier = React.useRef<number>(2);
158-
const gsap_wheel_tween = React.useRef<null | gsap.core.Tween>(null);
159-
const wheel = (e: WheelEvent): void => {
160-
const div = e.currentTarget as HTMLDivElement;
161-
// deltaMode == DOM_DELTA_PIXEL
162-
if (e.deltaMode == 0) {
163-
if (e.deltaX || e.deltaY == 0) return;
164-
165-
e.preventDefault();
166-
// increase scroll depending on wheel-roll duration
167-
if (last_wheel_timestamp.current != -1) {
168-
const last_roll_recent = last_wheel_timestamp.current > Date.now() - 250;
169-
if (last_roll_recent) {
170-
wheel_multiplier.current *= 1.2;
171-
wheel_multiplier.current = MathUtils.clamp(wheel_multiplier.current, 1, 16);
172-
} else {
173-
wheel_multiplier.current = 2;
154+
return () => {
155+
if (enhanced_wheel) {
156+
enhanced_wheel.destroy();
174157
}
175-
} else {
176-
wheel_multiplier.current = 2;
177-
}
178-
const delta = e.deltaY * wheel_multiplier.current;
179-
let target_scroll = div.scrollLeft + delta;
180-
target_scroll = MathUtils.clamp(target_scroll, 0, div.scrollWidth);
181-
if (gsap_wheel_tween.current) {
182-
gsap_wheel_tween.current!.kill();
183-
gsap_wheel_tween.current = null;
158+
};
159+
}, [params.wheelHorizontal]);
160+
161+
// Handle mouse wheel (vertical)
162+
React.useEffect(() => {
163+
const div_el = div.current!;
164+
let enhanced_wheel = null;
165+
if (params.wheelVertical) {
166+
enhanced_wheel = new EnhancedWheel(div_el, "vertical");
184167
}
185-
gsap.registerPlugin(ScrollToPlugin);
186-
gsap_wheel_tween.current = gsap.to(div, {
187-
scrollLeft: target_scroll,
188-
duration: 0.3,
189-
ease: "power1.out",
190-
});
191-
gsap_wheel_tween.current!.then(() => {
192-
gsap_wheel_tween.current = null;
193-
});
194-
last_wheel_timestamp.current = Date.now();
195-
}
196-
};
168+
return () => {
169+
if (enhanced_wheel) {
170+
enhanced_wheel.destroy();
171+
}
172+
};
173+
}, [params.wheelVertical]);
197174

198175
// Layout
199176
return (

src/components/HGroup.tsx

Lines changed: 6 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@
22
import assert from "assert";
33
import * as React from "react";
44
import { styled } from "styled-components";
5-
import gsap from "gsap";
6-
import { ScrollToPlugin } from "gsap/dist/ScrollToPlugin";
75

86
// local
97
import { Theme, ThemeContext } from "../theme/Theme";
108
import { AnchorSkin } from "../skins/AnchorSkin";
119
import { ScrollbarSkin } from "../skins/ScrollbarSkin";
1210
import { SelectionSkin } from "../skins/SelectionSkin";
1311
import { TableSkin } from "../skins/TableSkin";
12+
import { EnhancedWheel } from "../utils/EnhancedWheel";
1413
import * as MathUtils from "../utils/MathUtils";
1514
import * as REMConvert from "../utils/REMConvert";
1615
import * as ColorUtils from "../utils/ColorUtils";
@@ -200,61 +199,19 @@ export function HGroup(params: {
200199
"opacity " + COMMON_DELAY + "ms " + params.easePosition
201200
}
202201

203-
// Handle mouse wheel
202+
// Handle mouse wheel (horizontal)
204203
React.useEffect(() => {
205204
const div_el = div.current!;
206-
let added_handler = false;
205+
let enhanced_wheel = null;
207206
if (params.wheelHorizontal) {
208-
div_el.addEventListener("wheel", wheel, { passive: false });
209-
added_handler = true;
207+
enhanced_wheel = new EnhancedWheel(div_el, "horizontal");
210208
}
211209
return () => {
212-
if (added_handler) {
213-
div_el.removeEventListener("wheel", wheel);
210+
if (enhanced_wheel) {
211+
enhanced_wheel.destroy();
214212
}
215213
};
216214
}, [params.wheelHorizontal]);
217-
const last_wheel_timestamp = React.useRef<number>(-1);
218-
const wheel_multiplier = React.useRef<number>(2);
219-
const gsap_wheel_tween = React.useRef<null | gsap.core.Tween>(null);
220-
const wheel = (e: WheelEvent): void => {
221-
const div = e.currentTarget as HTMLDivElement;
222-
// deltaMode == DOM_DELTA_PIXEL
223-
if (e.deltaMode == 0) {
224-
if (e.deltaX || e.deltaY == 0) return;
225-
226-
e.preventDefault();
227-
// increase scroll depending on wheel-roll duration
228-
if (last_wheel_timestamp.current != -1) {
229-
const last_roll_recent = last_wheel_timestamp.current > Date.now() - 250;
230-
if (last_roll_recent) {
231-
wheel_multiplier.current *= 1.2;
232-
wheel_multiplier.current = MathUtils.clamp(wheel_multiplier.current, 1, 16);
233-
} else {
234-
wheel_multiplier.current = 2;
235-
}
236-
} else {
237-
wheel_multiplier.current = 2;
238-
}
239-
const delta = e.deltaY * wheel_multiplier.current;
240-
let target_scroll = div.scrollLeft + delta;
241-
target_scroll = MathUtils.clamp(target_scroll, 0, div.scrollWidth);
242-
if (gsap_wheel_tween.current) {
243-
gsap_wheel_tween.current!.kill();
244-
gsap_wheel_tween.current = null;
245-
}
246-
gsap.registerPlugin(ScrollToPlugin);
247-
gsap_wheel_tween.current = gsap.to(div, {
248-
scrollLeft: target_scroll,
249-
duration: 0.3,
250-
ease: "power1.out",
251-
});
252-
gsap_wheel_tween.current!.then(() => {
253-
gsap_wheel_tween.current = null;
254-
});
255-
last_wheel_timestamp.current = Date.now();
256-
}
257-
};
258215

259216
// Layout
260217
return (

0 commit comments

Comments
 (0)