Skip to content

Commit

Permalink
Added ScrollBar component
Browse files Browse the repository at this point in the history
  • Loading branch information
viktor-podzigun committed Feb 13, 2024
1 parent 20f589a commit 7a07171
Show file tree
Hide file tree
Showing 4 changed files with 460 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/ScrollBar.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/// <reference types="node" />

import { Widgets } from "@farjs/blessed";

export interface ScrollBarProps {
readonly left: number;
readonly top: number;
readonly length: number;
readonly style: Widgets.Types.TStyle;
readonly value: number;
readonly extent: number;
readonly min: number;
readonly max: number;
onChange(value: number): void;
}
112 changes: 112 additions & 0 deletions src/ScrollBar.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/**
* @typedef {import("./ScrollBar").ScrollBarProps} ScrollBarProps
*/
import React from "react";

const h = React.createElement;

/**
* @param {ScrollBarProps} props
*/
const ScrollBar = (props) => {
const unitIncrement = 1;
const blockIncrement = Math.max(props.extent, 1);
const barLength = Math.max(props.length, 2) - 2;
const min = Math.max(props.min, 0);
const max = Math.max(props.max, 0);
const value = Math.min(Math.max(props.value, min), max);
const markerLength = 1;
const upLength =
value === min
? 0
: value === max
? barLength - markerLength
: Math.max(
Math.min(
Math.trunc((value * barLength) / Math.max(max - min, 1)),
barLength - markerLength - 1
),
1
);
const downLength = barLength - upLength - markerLength;

return h(
React.Fragment,
null,
h("text", {
width: 1,
height: 1,
left: props.left,
top: props.top,
clickable: true,
mouse: true,
autoFocus: false,
style: props.style,
onClick: () => {
props.onChange(Math.max(props.value - unitIncrement, min));
},
content: ScrollBar.upArrowCh,
}),
h("text", {
width: 1,
height: upLength,
left: props.left,
top: props.top + 1,
clickable: true,
mouse: true,
autoFocus: false,
style: props.style,
onClick: () => {
props.onChange(Math.max(props.value - blockIncrement, min));
},
content: ScrollBar.scrollCh.repeat(upLength),
}),
h("text", {
width: 1,
height: markerLength,
left: props.left,
top: props.top + 1 + upLength,
autoFocus: false,
style: props.style,
content: ScrollBar.markerCh,
}),
h("text", {
width: 1,
height: downLength,
left: props.left,
top: props.top + 1 + upLength + markerLength,
clickable: true,
mouse: true,
autoFocus: false,
style: props.style,
onClick: () => {
props.onChange(Math.min(props.value + blockIncrement, max));
},
content: ScrollBar.scrollCh.repeat(downLength),
}),
h("text", {
width: 1,
height: 1,
left: props.left,
top: props.top + 1 + upLength + markerLength + downLength,
clickable: true,
mouse: true,
autoFocus: false,
style: props.style,
onClick: () => {
props.onChange(Math.min(props.value + unitIncrement, max));
},
content: ScrollBar.downArrowCh,
})
);
};

ScrollBar.displayName = "ScrollBar";

ScrollBar.markerCh = "\u2588"; // █
ScrollBar.scrollCh = "\u2591"; // ░

ScrollBar.upArrowCh = "\u25b2"; // ▲
ScrollBar.downArrowCh = "\u25bc"; // ▼

export default ScrollBar;
Loading

0 comments on commit 7a07171

Please sign in to comment.