Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
5c322f1
feat(log): first pass at filtering commits in the log
TomPlum Jun 30, 2025
79e5565
chore(demo): hoisted theme state into demo context
TomPlum Jun 30, 2025
42f4a73
chore(demo): made search field styling consistent with other demo ui …
TomPlum Jun 30, 2025
f905e5c
feat(graph): added in filtered graph break points for the HTML graph
TomPlum Jul 1, 2025
0c44dc8
chore(demo): converted radios to selects and fixed typing in demos
TomPlum Jul 1, 2025
db1cb99
feat(graph): added breakpoint theme prop and extracted BreakPoint com…
TomPlum Jul 1, 2025
d762aac
feat(demo): added graph break point control to stories
TomPlum Jul 1, 2025
52e5c7e
feat(graph): added zig-zag and dot themes to graph break point
TomPlum Jul 1, 2025
1c06940
feat(graph): made dot breakpoint theme new default
TomPlum Jul 1, 2025
b1062e9
fix(log): fixed tsc compilation issues
TomPlum Jul 1, 2025
c4d2b40
feat(log): added line and double-line breakpoint themes
TomPlum Jul 2, 2025
7bf32d3
chore(log): combined redundant graph computation functions
TomPlum Jul 2, 2025
edce633
chore(config): added vite-bundle-analyser to library
TomPlum Jul 2, 2025
069fcb8
test(graph): added style override tests for graph breakpoint component
TomPlum Jul 2, 2025
a02672c
chore(graph): extracted graph matrix builder class from useColumnData
TomPlum Jul 3, 2025
92764b2
feat(graph): added ring breakpoint theme
TomPlum Jul 3, 2025
75bdb09
feat(graph): added arrow breakpoint theme
TomPlum Jul 4, 2025
7cccc63
chore(graph): extracted GraphEdgeRenderer and GraphMatrix classes
TomPlum Jul 5, 2025
21b27fa
chore(graph): extracted more classes and complexity from graph matrix
TomPlum Jul 5, 2025
33ac47c
chore(sonar): reduced cognitive complexity of GraphEdgeRenderer below…
TomPlum Jul 5, 2025
db27f27
chore(sonar): extracted VirtualEdgeRenderer from GraphMatrixBuilder
TomPlum Jul 5, 2025
3823ad1
chore(sonar): reduced cognitive complexity of VirtualEdgeRenderer bel…
TomPlum Jul 5, 2025
65fc304
chore(sonar): reduced cognitive complexity of VerticalLine below the …
TomPlum Jul 5, 2025
cf0d237
chore(sonar): refactored buildGraphData into GraphDataBuilder and red…
TomPlum Jul 5, 2025
5ae9d19
chore(docs): added filter and breakpoint theme props to docs
TomPlum Jul 5, 2025
057b441
fix(graph): guarded head commit rendering in canvas graph when filtered
TomPlum Jul 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .run/library _ bundle_analyse.run.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="library &gt; bundle:analyse" type="js.build_tools.npm" nameIsGenerated="true">
<package-json value="$PROJECT_DIR$/packages/library/package.json" />
<command value="run" />
<scripts>
<script value="bundle:analyse" />
</scripts>
<node-interpreter value="project" />
<envs />
<method v="2" />
</configuration>
</component>
74 changes: 55 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ A flexible and interactive React component for visualising Git commit history. D
* [GitLogPaging](#gitlogpaging)
* [GitLogIndexStatus](#gitlogindexstatus)
* [GitLogUrlBuilder](#gitlogurlbuilder)
* [CommitFilter](#commitfilter)
* [GraphHTMLGrid](#graphhtmlgrid)
* [GraphCanvas2D](#graphcanvas2d)
* [NodeTheme](#nodetheme)
* [Table](#table)
* [GitLogTableStylingProps](#gitlogtablestylingprops)
* [CustomTableRow](#customtablerow)
* [CustomCommitNode](#customcommitnode)
* [BreakPointTheme](#breakpointtheme)
* [Development](#development)
* [References](#references)
* [Roadmap](#roadmap)
Expand Down Expand Up @@ -299,22 +301,26 @@ All components have optional props to further configure the log.
| `paging` | [`GitLogPaging`](#gitlogpaging) | Optional paging settings for displaying a subset of log entries. |
| `indexStatus` | [`GitLogIndexStatus`](#gitlogindexstatus) | Renders information about added, deleted and modified files to the index pseudo-commit entry. |
| `showGitIndex` | `boolean` | Enables the Git index "pseudo-commit' entry above the HEAD commit. |
| `filter` | [`CommitFilter<T>`](#commitfilter) | Filters the commits in the log based on the response from the function. |

### GitLogPaged

| Property | Type | Description |
|---------------------|---------------------------------------------|-------------------------------------------------------------------------------------------------------------|
| `theme` | `ThemeMode` | The variant of the default color theme to apply to the log. |
| `colours` | `ThemeColours \| string[]` | Array of colors used for graph elements. One per column, looping if insufficient colors are provided. |
| `showHeaders` | `boolean` | Whether to show element names like "Graph" or "Commit message" at the top of the component. |
| `rowSpacing` | `number` | The spacing between log rows, affecting branches, graph, and table. Default: `0`. |
| `urls` | [`GitLogUrlBuilder`](#gitlogurlbuilder) | A function that returns built URLs to the remote Git provider. Enables links for commits, tags, and PRs. |
| `defaultGraphWidth` | `number` | Default width of the graph in pixels. Can be changed dynamically if resizing is enabled. Default: `300`. |
| `onSelectCommit` | `(commit?: Commit) => void` | Callback function when a commit is selected (clicked). `commit` is `undefined` if unselected. |
| `onPreviewCommit` | `(commit?: Commit) => void` | Callback function when a commit is previewed (hovered). `commit` is `undefined` if stopped being previewed. |
| `classes` | [`GitLogStylingProps`](#gitlogstylingprops) | CSS classes for various elements to enable custom styling. |
| `indexStatus` | [`GitLogIndexStatus`](#gitlogindexstatus) | Renders information about added, deleted and modified files to the index pseudo-commit entry. |
| `showGitIndex` | `boolean` | Enables the Git index "pseudo-commit' entry above the HEAD commit. |
| Property | Type | Description |
|--------------------------------|---------------------------------------------|-------------------------------------------------------------------------------------------------------------|
| `theme` | `ThemeMode` | The variant of the default color theme to apply to the log. |
| `colours` | `ThemeColours \| string[]` | Array of colors used for graph elements. One per column, looping if insufficient colors are provided. |
| `showHeaders` | `boolean` | Whether to show element names like "Graph" or "Commit message" at the top of the component. |
| `rowSpacing` | `number` | The spacing between log rows, affecting branches, graph, and table. Default: `0`. |
| `urls` | [`GitLogUrlBuilder`](#gitlogurlbuilder) | A function that returns built URLs to the remote Git provider. Enables links for commits, tags, and PRs. |
| `defaultGraphWidth` | `number` | Default width of the graph in pixels. Can be changed dynamically if resizing is enabled. Default: `300`. |
| `onSelectCommit` | `(commit?: Commit) => void` | Callback function when a commit is selected (clicked). `commit` is `undefined` if unselected. |
| `onPreviewCommit` | `(commit?: Commit) => void` | Callback function when a commit is previewed (hovered). `commit` is `undefined` if stopped being previewed. |
| `enableSelectedCommitStyling` | `boolean` | Enables the row styling across the log elements when a commit is selected (i.e. has been clicked on). |
| `enablePreviewedCommitStyling` | `boolean` | Enables the row styling across the log elements when a commit is previewed (i.e. is hovered over). |
| `classes` | [`GitLogStylingProps`](#gitlogstylingprops) | CSS classes for various elements to enable custom styling. |
| `indexStatus` | [`GitLogIndexStatus`](#gitlogindexstatus) | Renders information about added, deleted and modified files to the index pseudo-commit entry. |
| `showGitIndex` | `boolean` | Enables the Git index "pseudo-commit' entry above the HEAD commit. |
| `filter` | [`CommitFilter<T>`](#commitfilter) | Filters the commits in the log based on the response from the function. |


#### GitLogStylingProps
Expand Down Expand Up @@ -351,6 +357,17 @@ Returns an object of type `GitLogUrls` with the following fields.
| `commit` | `string` | A resolved URL to a particular commit hash on the external Git providers remote website. |
| `branch` | `string` | A resolved URL to a branch on the external Git providers remote website. |

#### CommitFilter

A function with the following signature
```typescript
type CommitFilter<T> = (commits: Commit<T>[]) => Commit<T>[]
```

Is passed the array of `Commit<T>` objects from the log based on the current pagination configuration and must return the filtered array based on your own domain-specific behaviour.

The logs' subcomponents will respond accordingly based on the filtered list of commits.

### GraphHTMLGrid

| Property | Type | Description |
Expand All @@ -363,15 +380,17 @@ Returns an object of type `GitLogUrls` with the following fields.
| `enableResize` | `boolean` | Enables horizontal resizing of the graph. Default: `false`. |
| `highlightedBackgroundHeight` | `number` | The height, in pixels, of the background colour of a row that is being previewed or has been selected. |
| `node` | [`CustomCommitNode`](#customcommitnode) | A function that returns a custom commit node implementation used by the graph. |
| `breakPointTheme` | [`BreakPointTheme`](#breakpointtheme) | Changes how the break-points between rows render when the log is being filtered. |

### GraphCanvas2D

| Property | Type | Description |
|--------------------------|---------------------------|----------------------------------------------------------------------------------------------------------------|
| `nodeTheme` | [`NodeTheme`](#nodetheme) | Theme applied to commit node elements in the graph. |
| `nodeSize` | `number` | The diameter, in pixels, of the commits nodes. Should be divisible by 2 and between 8 and 30 to render nicely. |
| `orientation` | `normal \| flipped` | The orientation of the graph. Normal renders the checked-out branch on the left, flipped on the right. |
| `enableResize` | `boolean` | Enables horizontal resizing of the graph. Default: `false`. |
| Property | Type | Description |
|-------------------|---------------------------------------|----------------------------------------------------------------------------------------------------------------|
| `nodeTheme` | [`NodeTheme`](#nodetheme) | Theme applied to commit node elements in the graph. |
| `nodeSize` | `number` | The diameter, in pixels, of the commits nodes. Should be divisible by 2 and between 8 and 30 to render nicely. |
| `orientation` | `normal \| flipped` | The orientation of the graph. Normal renders the checked-out branch on the left, flipped on the right. |
| `enableResize` | `boolean` | Enables horizontal resizing of the graph. Default: `false`. |
| `breakPointTheme` | [`BreakPointTheme`](#breakpointtheme) | Changes how the break-points between rows render when the log is being filtered. |

#### NodeTheme

Expand Down Expand Up @@ -477,6 +496,18 @@ The following properties are injected into the functions `props` argument:
| `nodeSize` | `number` | The diameter (in pixels) of the node. This defaults but can be changed in the graph props. |
| `isIndexPseudoNode` | `boolean` | Denotes whether the node is the "pseudo node" added above the head to represent the working tree index. |

#### BreakPointTheme

The following themes are available:

- slash
- dot
- ring
- zig-zag
- line
- double-line
- arrow

# Development

1. Clone the repository from GitHub
Expand Down Expand Up @@ -516,6 +547,10 @@ Graphs
- Tags should be independent. Add a new optional field to the log entry / commit objects.
- Branch / Tags column is fixed. Dynamically floor it to match the max tag size currently being rendered?
- Support filtering so that the graph skips nodes
- Does this work with GitLogPaged?
- Rework CommitNodeLocation from a tuple into an object
- Hover effect on lines to show missing commits?
- Prop to override graph fallback? No search results yields the placeholder nodes

Canvas2D
- Custom prop for BG colour because of how canvas alpha channel works
Expand All @@ -525,5 +560,6 @@ Canvas2D
# Known Bugs
- The `GraphCanvas2D` component has the preview/select background cut off by canvases left-edge.
- The `GraphCanvas2D` component does not set the correct selected node BG colour, it's slightly off from the table row.
- The `GraphCanvas2D` component assumes dark theme is enabled and uses a dark background colour to emulate transparency in its gradients.
- The `GraphHTMLGrid` component renders the node-edge gradient to last node, but should be solid.
- The `GraphHTMLGrid` component is missing node edges from some commit nodes that are present in the canvas variant.
15 changes: 0 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion packages/demo/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Preview } from '@storybook/react'
import './preview.scss'
import '@theme-toggles/react/css/Within.css'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { DemoContextProvider } from '@context'

const queryClient = new QueryClient()

Expand All @@ -17,7 +18,9 @@ const preview: Preview = {
decorators: [
Story => (
<QueryClientProvider client={queryClient}>
<Story />
<DemoContextProvider>
<Story />
</DemoContextProvider>
</QueryClientProvider>
)
]
Expand Down
83 changes: 57 additions & 26 deletions packages/demo/src/GitLog.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import { Loading } from '@components/Loading'
import { useStoryState } from '@hooks/useStoryState'
import { StoryHeader } from '@components/StoryHeader'
import { GitLogDemo, GitLogStoryProps } from '@components/GitLogDemo'
import { useDemoContext } from '@context'

const meta: Meta<GitLogStoryProps> = {
title: 'GitLog',
component: GitLog,
component: GitLog<unknown>,
parameters: {
layout: 'fullscreen'
},
Expand All @@ -25,6 +26,7 @@ const meta: Meta<GitLogStoryProps> = {
showGitIndex: true,
enableResize: false,
nodeTheme: 'default',
breakPointTheme: 'dot',
renderStrategy: 'html-grid',
nodeSize: 20,
orientation: 'normal',
Expand Down Expand Up @@ -88,11 +90,33 @@ const meta: Meta<GitLogStoryProps> = {
table: {
category: 'Visibility'
},
control: 'radio',
options: {
Default: 'default',
Plain: 'plain'
}
control: {
type: 'select',
labels: {
default: 'Default',
plain: 'Plain'
},
},
options: ['default', 'plain']
},
breakPointTheme: {
name: 'Break Point Style',
table: {
category: 'Visibility'
},
control: {
type: 'select',
labels: {
slash: 'Slash',
dot: 'Dot',
ring: 'Ring',
'zig-zag': 'Zig-Zag',
line: 'Line',
'double-line': 'Double Line',
arrow: 'Arrow'
},
},
options: ['slash', 'dot', 'ring', 'zig-zag', 'line', 'double-line', 'arrow']
},
showGitIndex: {
name: 'Show Git Index',
Expand All @@ -106,11 +130,14 @@ const meta: Meta<GitLogStoryProps> = {
table: {
category: 'Visibility'
},
control: 'radio',
options: {
'HTML Grid': 'html-grid',
Canvas2D: 'canvas'
}
control: {
type: 'select',
labels: {
'html-grid': 'HTML Grid',
canvas: 'Canvas2D'
}
},
options: ['html-grid', 'canvas'],
},
enableSelectedCommitStyling: {
name: 'Enable Selection Styling',
Expand Down Expand Up @@ -193,11 +220,14 @@ const meta: Meta<GitLogStoryProps> = {
table: {
category: 'Dimensions'
},
control: 'radio',
options: {
Normal: 'normal',
Flipped: 'flipped'
}
control: {
type: 'select',
labels: {
normal: 'Normal',
flipped: 'Flipped'
}
},
options: ['normal', 'flipped'],
},
onSelectCommit: {
name: 'onSelectCommit',
Expand Down Expand Up @@ -271,6 +301,11 @@ const meta: Meta<GitLogStoryProps> = {
table: {
disable: true
}
},
filter: {
table: {
disable: true
}
}
}
} satisfies Meta<GitLogStoryProps>
Expand All @@ -284,33 +319,31 @@ export const Demo: Story = {

export const CustomTableRow = () => {
const {
theme,
loading,
colours,
entries,
branch,
buildUrls,
repository,
backgroundColour,
handleChangeTheme,
handleChangeColors,
handleChangeRepository
} = useStoryState()

const { theme } = useDemoContext()

return (
<div style={{ background: backgroundColour }} className={styles.container}>
<StoryHeader
theme={theme}
colours={colours}
repository={repository}
onChangeTheme={handleChangeTheme}
onChangeColours={handleChangeColors}
onChangeRepository={handleChangeRepository}
/>

{loading && (
<div className={styles.loading}>
<Loading theme={theme} />
<Loading />
</div>
)}

Expand Down Expand Up @@ -388,33 +421,31 @@ const nodeImages = ['millie', 'neo', 'millie_neo', 'neo_banana', 'neo_2', 'bella

export const CustomCommitNode = () => {
const {
theme,
loading,
colours,
entries,
branch,
buildUrls,
repository,
backgroundColour,
handleChangeTheme,
handleChangeColors,
handleChangeRepository
} = useStoryState()

const { theme } = useDemoContext()

return (
<div style={{ background: backgroundColour }} className={styles.container}>
<StoryHeader
theme={theme}
colours={colours}
repository={repository}
onChangeTheme={handleChangeTheme}
onChangeColours={handleChangeColors}
onChangeRepository={handleChangeRepository}
/>

{loading && (
<div className={styles.loading}>
<Loading theme={theme} />
<Loading />
</div>
)}

Expand Down
Loading