Skip to content

Commit f3c44df

Browse files
committed
feat: implement Breadcrumbs component with styling and navigation functionality
1 parent 50d3a5c commit f3c44df

8 files changed

Lines changed: 271 additions & 289 deletions

File tree

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
.breadcrumbs {
2+
position: relative;
3+
display: flex;
4+
align-items: center;
5+
justify-content: flex-start;
6+
gap: 8px;
7+
min-width: 0;
8+
overflow-x: auto;
9+
overflow-y: hidden;
10+
white-space: nowrap;
11+
scrollbar-width: none;
12+
-webkit-mask-image: none;
13+
mask-image: none;
14+
}
15+
16+
.breadcrumbs::-webkit-scrollbar {
17+
display: none;
18+
}
19+
20+
.breadcrumbs.is-cropped-left {
21+
-webkit-mask-image: linear-gradient(to right, transparent 0, black 18px, black 100%);
22+
mask-image: linear-gradient(to right, transparent 0, black 18px, black 100%);
23+
-webkit-mask-size: 100% 100%;
24+
mask-size: 100% 100%;
25+
-webkit-mask-repeat: no-repeat;
26+
mask-repeat: no-repeat;
27+
}
28+
29+
.breadcrumbs.is-cropped-right {
30+
-webkit-mask-image: linear-gradient(to right, black 0, black calc(100% - 18px), transparent 100%);
31+
mask-image: linear-gradient(to right, black 0, black calc(100% - 18px), transparent 100%);
32+
-webkit-mask-size: 100% 100%;
33+
mask-size: 100% 100%;
34+
-webkit-mask-repeat: no-repeat;
35+
mask-repeat: no-repeat;
36+
}
37+
38+
.breadcrumbs.is-cropped-left.is-cropped-right {
39+
-webkit-mask-image: linear-gradient(to right, transparent 0, black 18px, black calc(100% - 18px), transparent 100%);
40+
mask-image: linear-gradient(to right, transparent 0, black 18px, black calc(100% - 18px), transparent 100%);
41+
}
42+
43+
.breadcrumb-segment {
44+
position: relative;
45+
display: flex;
46+
align-items: center;
47+
flex: 0 0 auto;
48+
cursor: pointer;
49+
padding: 2px 6px;
50+
margin: -2px -6px;
51+
border-radius: 4px;
52+
transition: background-color 0.1s ease;
53+
}
54+
55+
.breadcrumb-segment:hover {
56+
background: var(--entry-hover, rgba(255, 255, 255, 0.06));
57+
}
58+
59+
.breadcrumb-segment-text {
60+
white-space: nowrap;
61+
}
62+
63+
.breadcrumb-separator {
64+
flex-shrink: 0;
65+
opacity: 0.6;
66+
pointer-events: none;
67+
user-select: none;
68+
}

packages/ui/lib/components/FileList/Breadcrumbs.tsx renamed to packages/ui/lib/components/Breadcrumbs/Breadcrumbs.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { cx } from "@/utils/cssModules";
22
import { getBreadcrumbSegments } from "@/utils/path";
33
import { Fragment, memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
4-
import styles from "./FileList.module.css";
4+
import styles from "./Breadcrumbs.module.css";
55

66
interface BreadcrumbsProps {
77
currentPath: string;

packages/ui/lib/components/FileList/FileList.module.css

Lines changed: 0 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -22,92 +22,6 @@
2222
overflow: visible;
2323
}
2424

25-
.breadcrumbs {
26-
position: relative;
27-
display: flex;
28-
align-items: center;
29-
justify-content: flex-start;
30-
gap: 8px;
31-
min-width: 0;
32-
overflow-x: auto;
33-
overflow-y: hidden;
34-
white-space: nowrap;
35-
scrollbar-width: none;
36-
-webkit-mask-image: none;
37-
mask-image: none;
38-
}
39-
40-
.breadcrumbs::-webkit-scrollbar {
41-
display: none;
42-
}
43-
44-
.breadcrumbs.is-cropped-left {
45-
-webkit-mask-image: linear-gradient(to right, transparent 0, black 18px, black 100%);
46-
mask-image: linear-gradient(to right, transparent 0, black 18px, black 100%);
47-
-webkit-mask-size: 100% 100%;
48-
mask-size: 100% 100%;
49-
-webkit-mask-repeat: no-repeat;
50-
mask-repeat: no-repeat;
51-
}
52-
53-
.breadcrumbs.is-cropped-right {
54-
-webkit-mask-image: linear-gradient(to right, black 0, black calc(100% - 18px), transparent 100%);
55-
mask-image: linear-gradient(to right, black 0, black calc(100% - 18px), transparent 100%);
56-
-webkit-mask-size: 100% 100%;
57-
mask-size: 100% 100%;
58-
-webkit-mask-repeat: no-repeat;
59-
mask-repeat: no-repeat;
60-
}
61-
62-
.breadcrumbs.is-cropped-left.is-cropped-right {
63-
-webkit-mask-image: linear-gradient(to right, transparent 0, black 18px, black calc(100% - 18px), transparent 100%);
64-
mask-image: linear-gradient(to right, transparent 0, black 18px, black calc(100% - 18px), transparent 100%);
65-
}
66-
67-
.breadcrumbs .breadcrumb-copied-tooltip {
68-
position: absolute;
69-
left: 0;
70-
top: 100%;
71-
margin-top: 4px;
72-
padding: 4px 8px;
73-
background: var(--fg);
74-
color: var(--bg);
75-
font-size: 11px;
76-
font-weight: 500;
77-
border-radius: 4px;
78-
white-space: nowrap;
79-
pointer-events: none;
80-
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
81-
z-index: 10;
82-
}
83-
84-
.breadcrumb-segment {
85-
position: relative;
86-
display: flex;
87-
align-items: center;
88-
flex: 0 0 auto;
89-
cursor: pointer;
90-
padding: 2px 6px;
91-
margin: -2px -6px;
92-
border-radius: 4px;
93-
transition: background-color 0.1s ease;
94-
}
95-
96-
.breadcrumb-segment:hover {
97-
background: var(--entry-hover, rgba(255, 255, 255, 0.06));
98-
}
99-
100-
.breadcrumb-segment-text {
101-
white-space: nowrap;
102-
}
103-
104-
.breadcrumb-separator {
105-
flex-shrink: 0;
106-
opacity: 0.6;
107-
pointer-events: none;
108-
user-select: none;
109-
}
110-
11125
.file-list-body {
11226
flex: 1;
11327
min-height: 0;

packages/ui/lib/components/FileList/FileList.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { ActionQueue } from "@/components/FileList/actionQueue";
22
import type { PanelSide } from "@/entities/panel/model/types";
33
import type { FileListTabState } from "@/entities/tab/model/types";
4-
import { useCommandRegistry } from "@/features/commands/commands";
54
import { TERMINAL_EXECUTE, VIEW_FILE } from "@/features/commands/commandIds";
5+
import { useCommandRegistry } from "@/features/commands/commands";
66
import { useFileStyleResolver } from "@/features/fss/fileStyleResolver";
77
import { usePanelControllerRegistry } from "@/features/panels/panelControllers";
88
import { useMediaQuery } from "@/hooks/useMediaQuery";
@@ -11,7 +11,7 @@ import { dirname, join } from "@/utils/path";
1111
import { useEditorRegistry, useViewerRegistry } from "@/viewerEditorRegistry";
1212
import type { FsNode } from "fss-lang";
1313
import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
14-
import { Breadcrumbs } from "./Breadcrumbs";
14+
import { Breadcrumbs } from "../Breadcrumbs/Breadcrumbs";
1515
import { ColumnsScroller, type ColumnsScrollerProps } from "./ColumnsScroller";
1616
import { FileInfoFooter } from "./FileInfoFooter";
1717
import styles from "./FileList.module.css";

packages/ui/lib/features/command-line/CommandLine/CommandLine.tsx

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
import { panelsVisibleAtom } from "@/atoms";
22
import { useCommandLine, useCommandLineRegistration } from "@/features/command-line/useCommandLine";
3-
import { useCommandRegistry } from "@/features/commands/commands";
43
import {
5-
COMMANDLINE_CLEAR,
6-
COMMANDLINE_COPY,
7-
COMMANDLINE_CUT,
8-
COMMANDLINE_DELETE_LEFT,
9-
COMMANDLINE_DELETE_RIGHT,
10-
COMMANDLINE_END,
11-
COMMANDLINE_EXECUTE,
12-
COMMANDLINE_HOME,
13-
COMMANDLINE_LEFT,
14-
COMMANDLINE_MOVE_WORD_LEFT,
15-
COMMANDLINE_MOVE_WORD_RIGHT,
16-
COMMANDLINE_PASTE,
17-
COMMANDLINE_RIGHT,
18-
COMMANDLINE_SELECT_ALL,
19-
COMMANDLINE_SELECT_END,
20-
COMMANDLINE_SELECT_HOME,
21-
COMMANDLINE_SELECT_LEFT,
22-
COMMANDLINE_SELECT_RIGHT,
23-
COMMANDLINE_SELECT_WORD_LEFT,
24-
COMMANDLINE_SELECT_WORD_RIGHT,
4+
COMMANDLINE_CLEAR,
5+
COMMANDLINE_COPY,
6+
COMMANDLINE_CURSOR_END,
7+
COMMANDLINE_CURSOR_HOME,
8+
COMMANDLINE_CURSOR_LEFT,
9+
COMMANDLINE_CURSOR_RIGHT,
10+
COMMANDLINE_CURSOR_WORD_LEFT,
11+
COMMANDLINE_CURSOR_WORD_RIGHT,
12+
COMMANDLINE_CUT,
13+
COMMANDLINE_DELETE_LEFT,
14+
COMMANDLINE_DELETE_RIGHT,
15+
COMMANDLINE_EXECUTE,
16+
COMMANDLINE_PASTE,
17+
COMMANDLINE_SELECT_ALL,
18+
COMMANDLINE_SELECT_END,
19+
COMMANDLINE_SELECT_HOME,
20+
COMMANDLINE_SELECT_LEFT,
21+
COMMANDLINE_SELECT_RIGHT,
22+
COMMANDLINE_SELECT_WORD_LEFT,
23+
COMMANDLINE_SELECT_WORD_RIGHT,
2524
} from "@/features/commands/commandIds";
25+
import { useCommandRegistry } from "@/features/commands/commands";
2626
import { registerCommandLineKeybindings } from "@/features/commands/registerKeybindings";
2727
import { useTerminal } from "@/features/terminal/useTerminal";
2828
import terminalStyles from "@/styles/terminal.module.css";
@@ -144,7 +144,7 @@ export function CommandLine() {
144144
);
145145

146146
d.push(
147-
commandRegistry.registerCommand(COMMANDLINE_MOVE_WORD_LEFT, () => {
147+
commandRegistry.registerCommand(COMMANDLINE_CURSOR_WORD_LEFT, () => {
148148
const v = valueRef.current;
149149
let p = cursorRef.current;
150150
while (p > 0 && v[p - 1] === " ") p--;
@@ -154,7 +154,7 @@ export function CommandLine() {
154154
);
155155

156156
d.push(
157-
commandRegistry.registerCommand(COMMANDLINE_MOVE_WORD_RIGHT, () => {
157+
commandRegistry.registerCommand(COMMANDLINE_CURSOR_WORD_RIGHT, () => {
158158
const v = valueRef.current;
159159
let p = cursorRef.current;
160160
while (p < v.length && v[p] !== " ") p++;
@@ -163,10 +163,10 @@ export function CommandLine() {
163163
}),
164164
);
165165

166-
d.push(commandRegistry.registerCommand(COMMANDLINE_HOME, () => moveCursor(0, false)));
167-
d.push(commandRegistry.registerCommand(COMMANDLINE_END, () => moveCursor(valueRef.current.length, false)));
168-
d.push(commandRegistry.registerCommand(COMMANDLINE_LEFT, () => moveCursor(Math.max(0, cursorRef.current - 1), false)));
169-
d.push(commandRegistry.registerCommand(COMMANDLINE_RIGHT, () => moveCursor(Math.min(valueRef.current.length, cursorRef.current + 1), false)));
166+
d.push(commandRegistry.registerCommand(COMMANDLINE_CURSOR_HOME, () => moveCursor(0, false)));
167+
d.push(commandRegistry.registerCommand(COMMANDLINE_CURSOR_END, () => moveCursor(valueRef.current.length, false)));
168+
d.push(commandRegistry.registerCommand(COMMANDLINE_CURSOR_LEFT, () => moveCursor(Math.max(0, cursorRef.current - 1), false)));
169+
d.push(commandRegistry.registerCommand(COMMANDLINE_CURSOR_RIGHT, () => moveCursor(Math.min(valueRef.current.length, cursorRef.current + 1), false)));
170170

171171
d.push(
172172
commandRegistry.registerCommand(COMMANDLINE_SELECT_ALL, () => {

0 commit comments

Comments
 (0)