Skip to content

Commit ccffa02

Browse files
committed
#132 Add sticky header option
1 parent 2b88194 commit ccffa02

File tree

7 files changed

+95
-4
lines changed

7 files changed

+95
-4
lines changed

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,11 @@
465465
},
466466
"description": "An object specifying the default visibility of the Date, Author & Commit columns. Example: {\"Date\": true, \"Author\": true, \"Commit\": true}"
467467
},
468+
"git-graph.stickyHeader": {
469+
"type": "boolean",
470+
"default": true,
471+
"description": "Keeps the header visible when the view is scrolled"
472+
},
468473
"git-graph.dialog.addTag.pushToRemote": {
469474
"type": "boolean",
470475
"default": false,

src/config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,13 @@ class Config {
489489
return !!this.config.get('showStatusBarItem', true);
490490
}
491491

492+
/**
493+
* Get the value of the `git-graph.stickyHeader` Extension Setting.
494+
*/
495+
get stickyHeader() {
496+
return !!this.config.get('stickyHeader', true);
497+
}
498+
492499
/**
493500
* Get the value of the `git-graph.tabIconColourTheme` Extension Setting.
494501
*/

src/gitGraphView.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ export class GitGraphView extends Disposable {
589589
customPullRequestProviders: config.customPullRequestProviders,
590590
dateFormat: config.dateFormat,
591591
defaultColumnVisibility: config.defaultColumnVisibility,
592+
stickyHeader: config.stickyHeader,
592593
dialogDefaults: config.dialogDefaults,
593594
enhancedAccessibility: config.enhancedAccessibility,
594595
fetchAndPrune: config.fetchAndPrune,
@@ -628,9 +629,10 @@ export class GitGraphView extends Disposable {
628629
<p class="unableToLoadMessage">${UNABLE_TO_FIND_GIT_MSG}</p>
629630
</body>`;
630631
} else if (numRepos > 0) {
632+
const stickyClassAttr = initialState.config.stickyHeader ? ' class="sticky"' : '';
631633
body = `<body>
632634
<div id="view" tabindex="-1">
633-
<div id="controls">
635+
<div id="controls"${stickyClassAttr}>
634636
<span id="repoControl"><span class="unselectable">Repo: </span><div id="repoDropdown" class="dropdown"></div></span>
635637
<span id="branchControl"><span class="unselectable">Branches: </span><div id="branchDropdown" class="dropdown"></div></span>
636638
<label id="showRemoteBranchesControl"><input type="checkbox" id="showRemoteBranchesCheckbox" tabindex="-1"><span class="customCheckbox"></span>Show Remote Branches</label>

src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ export interface GitGraphViewConfig {
235235
readonly repoDropdownOrder: RepoDropdownOrder;
236236
readonly showRemoteBranches: boolean;
237237
readonly showTags: boolean;
238+
readonly stickyHeader: boolean;
238239
}
239240

240241
export interface GitGraphViewGlobalState {

tests/config.test.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3878,4 +3878,66 @@ describe('Config', () => {
38783878
expect(value).toBe(false);
38793879
});
38803880
});
3881+
3882+
describe('stickyHeader', () => {
3883+
it('Should return TRUE when the configuration value is TRUE', () => {
3884+
// Setup
3885+
workspaceConfiguration.get.mockReturnValueOnce(true);
3886+
3887+
// Run
3888+
const value = config.stickyHeader;
3889+
3890+
// Assert
3891+
expect(workspaceConfiguration.get).toBeCalledWith('stickyHeader', true);
3892+
expect(value).toBe(true);
3893+
});
3894+
3895+
it('Should return FALSE when the configuration value is FALSE', () => {
3896+
// Setup
3897+
workspaceConfiguration.get.mockReturnValueOnce(false);
3898+
3899+
// Run
3900+
const value = config.stickyHeader;
3901+
3902+
// Assert
3903+
expect(workspaceConfiguration.get).toBeCalledWith('stickyHeader', true);
3904+
expect(value).toBe(false);
3905+
});
3906+
3907+
it('Should return TRUE when the configuration value is truthy', () => {
3908+
// Setup
3909+
workspaceConfiguration.get.mockReturnValueOnce(5);
3910+
3911+
// Run
3912+
const value = config.stickyHeader;
3913+
3914+
// Assert
3915+
expect(workspaceConfiguration.get).toBeCalledWith('stickyHeader', true);
3916+
expect(value).toBe(true);
3917+
});
3918+
3919+
it('Should return FALSE when the configuration value is falsy', () => {
3920+
// Setup
3921+
workspaceConfiguration.get.mockReturnValueOnce(0);
3922+
3923+
// Run
3924+
const value = config.stickyHeader;
3925+
3926+
// Assert
3927+
expect(workspaceConfiguration.get).toBeCalledWith('stickyHeader', true);
3928+
expect(value).toBe(false);
3929+
});
3930+
3931+
it('Should return the default value (TRUE) when the configuration value is not set', () => {
3932+
// Setup
3933+
workspaceConfiguration.get.mockImplementationOnce((_, defaultValue) => defaultValue);
3934+
3935+
// Run
3936+
const value = config.stickyHeader;
3937+
3938+
// Assert
3939+
expect(workspaceConfiguration.get).toBeCalledWith('stickyHeader', true);
3940+
expect(value).toBe(true);
3941+
});
3942+
});
38813943
});

web/main.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,8 @@ class GitGraphView {
736736
markdown: this.config.markdown
737737
});
738738

739-
let html = '<tr id="tableColHeaders"><th id="tableHeaderGraphCol" class="tableColHeader" data-col="0">Graph</th><th class="tableColHeader" data-col="1">Description</th>' +
739+
const stickyClassAttr = this.config.stickyHeader ? ' class="sticky"' : '';
740+
let html = '<tr id="tableColHeaders"' + stickyClassAttr + '><th id="tableHeaderGraphCol" class="tableColHeader" data-col="0">Graph</th><th class="tableColHeader" data-col="1">Description</th>' +
740741
(colVisibility.date ? '<th class="tableColHeader dateCol" data-col="2">Date</th>' : '') +
741742
(colVisibility.author ? '<th class="tableColHeader authorCol" data-col="3">Author</th>' : '') +
742743
(colVisibility.commit ? '<th class="tableColHeader" data-col="4">Commit</th>' : '') +

web/styles/main.css

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ body.selection-background-color-exists ::selection{
215215
padding:0 4px;
216216
}
217217
#commitTable th{
218-
border-bottom:1px solid rgba(128,128,128,0.5);
218+
border-bottom:1px solid transparent;
219+
box-shadow: 0 1px 0 rgba(128,128,128,0.5);
219220
line-height:18px;
220221
padding:6px 12px;
221222
}
@@ -278,6 +279,12 @@ body.selection-background-color-exists ::selection{
278279
.tableColHeader{
279280
position:relative;
280281
}
282+
#tableColHeaders.sticky .tableColHeader {
283+
position: sticky;
284+
top: 41px;
285+
z-index: 3;
286+
background-color: var(--vscode-editor-background);
287+
}
281288
.resizeCol{
282289
position:absolute;
283290
top:0;
@@ -766,11 +773,12 @@ body.tagLabelsRightAligned .gitRef.tag{
766773

767774
#controls{
768775
display:block;
769-
position:relative;
776+
position: relative;
770777
left:0;
771778
right:0;
772779
top:0;
773780
padding:4px 132px 4px 0;
781+
background-color: var(--vscode-editor-background);
774782
border-bottom:1px solid rgba(128,128,128,0.5);
775783
line-height:32px;
776784
text-align:center;
@@ -780,6 +788,11 @@ body.tagLabelsRightAligned .gitRef.tag{
780788
user-select:none;
781789
}
782790

791+
#controls.sticky {
792+
position:sticky;
793+
z-index: 4;
794+
}
795+
783796
#repoControl, #branchControl, #showRemoteBranchesControl{
784797
display:inline-block;
785798
white-space:nowrap;

0 commit comments

Comments
 (0)