feat: invert scroll

This commit is contained in:
Michael Freno
2026-01-05 11:07:38 -05:00
parent 8c43b45344
commit 121d787a0c
3 changed files with 12 additions and 0 deletions

View File

@@ -133,6 +133,7 @@
---@field scrollbarRadius number? -- Scrollbar corner radius ---@field scrollbarRadius number? -- Scrollbar corner radius
---@field scrollbarPadding number? -- Scrollbar padding from edges ---@field scrollbarPadding number? -- Scrollbar padding from edges
---@field scrollSpeed number? -- Scroll speed multiplier ---@field scrollSpeed number? -- Scroll speed multiplier
---@field invertScroll boolean? -- Invert mouse wheel scroll direction (default: false)
---@field scrollBarStyle string? -- Scrollbar style name from theme (selects from theme.scrollbars) ---@field scrollBarStyle string? -- Scrollbar style name from theme (selects from theme.scrollbars)
---@field scrollbarKnobOffset number|table? -- Scrollbar knob/handle offset (number or {x, y} or {horizontal, vertical}) ---@field scrollbarKnobOffset number|table? -- Scrollbar knob/handle offset (number or {x, y} or {horizontal, vertical})
---@field _overflowX boolean? -- Internal: whether content overflows horizontally ---@field _overflowX boolean? -- Internal: whether content overflows horizontally
@@ -1845,6 +1846,7 @@ function Element.new(props)
scrollbarRadius = props.scrollbarRadius, scrollbarRadius = props.scrollbarRadius,
scrollbarPadding = props.scrollbarPadding, scrollbarPadding = props.scrollbarPadding,
scrollSpeed = props.scrollSpeed, scrollSpeed = props.scrollSpeed,
invertScroll = props.invertScroll,
smoothScrollEnabled = props.smoothScrollEnabled, smoothScrollEnabled = props.smoothScrollEnabled,
scrollBarStyle = props.scrollBarStyle, scrollBarStyle = props.scrollBarStyle,
scrollbarKnobOffset = props.scrollbarKnobOffset, scrollbarKnobOffset = props.scrollbarKnobOffset,
@@ -1863,6 +1865,7 @@ function Element.new(props)
self.scrollbarRadius = self._scrollManager.scrollbarRadius self.scrollbarRadius = self._scrollManager.scrollbarRadius
self.scrollbarPadding = self._scrollManager.scrollbarPadding self.scrollbarPadding = self._scrollManager.scrollbarPadding
self.scrollSpeed = self._scrollManager.scrollSpeed self.scrollSpeed = self._scrollManager.scrollSpeed
self.invertScroll = self._scrollManager.invertScroll
self.scrollBarStyle = self._scrollManager.scrollBarStyle self.scrollBarStyle = self._scrollManager.scrollBarStyle
self.scrollbarKnobOffset = self._scrollManager.scrollbarKnobOffset self.scrollbarKnobOffset = self._scrollManager.scrollbarKnobOffset
self.hideScrollbars = self._scrollManager.hideScrollbars self.hideScrollbars = self._scrollManager.hideScrollbars

View File

@@ -8,6 +8,7 @@
---@field scrollbarRadius number -- Border radius for scrollbars ---@field scrollbarRadius number -- Border radius for scrollbars
---@field scrollbarPadding number -- Padding around scrollbar ---@field scrollbarPadding number -- Padding around scrollbar
---@field scrollSpeed number -- Scroll speed for wheel events (pixels per wheel unit) ---@field scrollSpeed number -- Scroll speed for wheel events (pixels per wheel unit)
---@field invertScroll boolean -- Invert mouse wheel scroll direction (default: false)
---@field scrollBarStyle string? -- Scrollbar style name from theme (selects from theme.scrollbars) ---@field scrollBarStyle string? -- Scrollbar style name from theme (selects from theme.scrollbars)
---@field scrollbarKnobOffset table -- {x: number, y: number, horizontal: number, vertical: number} -- Offset for scrollbar knob/handle position ---@field scrollbarKnobOffset table -- {x: number, y: number, horizontal: number, vertical: number} -- Offset for scrollbar knob/handle position
---@field hideScrollbars table -- {vertical: boolean, horizontal: boolean} ---@field hideScrollbars table -- {vertical: boolean, horizontal: boolean}
@@ -83,6 +84,7 @@ function ScrollManager.new(config, deps)
self.scrollbarRadius = config.scrollbarRadius or 6 self.scrollbarRadius = config.scrollbarRadius or 6
self.scrollbarPadding = config.scrollbarPadding or 2 self.scrollbarPadding = config.scrollbarPadding or 2
self.scrollSpeed = config.scrollSpeed or 20 self.scrollSpeed = config.scrollSpeed or 20
self.invertScroll = config.invertScroll or false
self.scrollBarStyle = config.scrollBarStyle -- Theme scrollbar style name (nil = use default) self.scrollBarStyle = config.scrollBarStyle -- Theme scrollbar style name (nil = use default)
-- scrollbarKnobOffset can be number or table {x, y} or {horizontal, vertical} -- scrollbarKnobOffset can be number or table {x, y} or {horizontal, vertical}
@@ -582,6 +584,9 @@ function ScrollManager:handleWheel(x, y)
-- Vertical scrolling -- Vertical scrolling
if y ~= 0 and hasVerticalOverflow then if y ~= 0 and hasVerticalOverflow then
local delta = -y * self.scrollSpeed -- Negative because wheel up = scroll up local delta = -y * self.scrollSpeed -- Negative because wheel up = scroll up
if self.invertScroll then
delta = -delta -- Invert scroll direction if enabled
end
if self.smoothScrollEnabled then if self.smoothScrollEnabled then
-- Set target for smooth scrolling instead of instant jump -- Set target for smooth scrolling instead of instant jump
self._targetScrollY = self._utils.clamp((self._targetScrollY or self._scrollY) + delta, 0, self._maxScrollY) self._targetScrollY = self._utils.clamp((self._targetScrollY or self._scrollY) + delta, 0, self._maxScrollY)
@@ -596,6 +601,9 @@ function ScrollManager:handleWheel(x, y)
-- Horizontal scrolling -- Horizontal scrolling
if x ~= 0 and hasHorizontalOverflow then if x ~= 0 and hasHorizontalOverflow then
local delta = -x * self.scrollSpeed local delta = -x * self.scrollSpeed
if self.invertScroll then
delta = -delta -- Invert scroll direction if enabled
end
if self.smoothScrollEnabled then if self.smoothScrollEnabled then
-- Set target for smooth scrolling instead of instant jump -- Set target for smooth scrolling instead of instant jump
self._targetScrollX = self._utils.clamp((self._targetScrollX or self._scrollX) + delta, 0, self._maxScrollX) self._targetScrollX = self._utils.clamp((self._targetScrollX or self._scrollX) + delta, 0, self._maxScrollX)

View File

@@ -122,6 +122,7 @@ local AnimationProps = {}
---@field scrollbarRadius number? -- Corner radius for scrollbar (default: 6) ---@field scrollbarRadius number? -- Corner radius for scrollbar (default: 6)
---@field scrollbarPadding number? -- Padding between scrollbar and edge (default: 2) ---@field scrollbarPadding number? -- Padding between scrollbar and edge (default: 2)
---@field scrollSpeed number? -- Pixels per wheel notch (default: 20) ---@field scrollSpeed number? -- Pixels per wheel notch (default: 20)
---@field invertScroll boolean? -- Invert mouse wheel scroll direction (default: false)
---@field smoothScrollEnabled boolean? -- Enable smooth scrolling animation for wheel events (default: false) ---@field smoothScrollEnabled boolean? -- Enable smooth scrolling animation for wheel events (default: false)
---@field scrollBarStyle string? -- Scrollbar style name from theme (selects from theme.scrollbars, default: uses first scrollbar or fallback rendering) ---@field scrollBarStyle string? -- Scrollbar style name from theme (selects from theme.scrollbars, default: uses first scrollbar or fallback rendering)
---@field scrollbarKnobOffset number|{x:number, y:number}|{horizontal:number, vertical:number}? -- Offset for scrollbar knob/handle position in pixels (number for both axes, or table for per-axis control, default: 0, adds to theme offset) ---@field scrollbarKnobOffset number|{x:number, y:number}|{horizontal:number, vertical:number}? -- Offset for scrollbar knob/handle position in pixels (number for both axes, or table for per-axis control, default: 0, adds to theme offset)