Skip to content

Commit a972cee

Browse files
committed
feat: add sidebar
1 parent f85b485 commit a972cee

File tree

2 files changed

+95
-43
lines changed

2 files changed

+95
-43
lines changed

packages/omi-low-code/src/components/sidebar.tsx

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ interface ComponentWithRouter extends Sidebar {
66
router?: Router
77
}
88

9-
type SidebarItem = {
9+
export type SidebarItem = {
1010
text: string
11-
href: string
11+
href?: string
1212
target: string
1313
name: string
1414
path: string
@@ -35,11 +35,18 @@ export class Sidebar extends Component<Props> {
3535
:host {
3636
display: block;
3737
}
38+
.selected-item {
39+
background-color: #e2e8f0; /* Light gray background */
40+
}
41+
.dark .selected-item {
42+
background-color: #4a5568; /* Darker gray for dark mode */
43+
}
3844
`
3945

4046
state = {
4147
isOpen: false,
4248
active: '',
49+
selectedItem: null as SidebarItem | null
4350
}
4451

4552
onMouseEnter(item: SidebarItem) {
@@ -106,12 +113,18 @@ export class Sidebar extends Component<Props> {
106113

107114
@bind
108115
select(item: SidebarItem) {
109-
;(this as ComponentWithRouter).router?.push(item.href.replace('#', ''))
110-
111-
this.state.active = this.props.active
116+
if (this.state.selectedItem === item) {
117+
// If the clicked item is already selected, deselect it
118+
this.state.selectedItem = null;
119+
this.state.active = '';
120+
} else {
121+
// Otherwise, select the new item
122+
this.state.selectedItem = item;
123+
this.state.active = item.value;
124+
}
112125
this.update()
113126
this.fire('change', {
114-
item,
127+
item: this.state.selectedItem,
115128
})
116129
}
117130

@@ -122,23 +135,27 @@ export class Sidebar extends Component<Props> {
122135
class={classNames(
123136
'py-1 h-9 indent-10 rounded hover:bg-accent flex items-center text-sm text-zinc-500 dark:text-zinc-200 cursor-pointer',
124137
{
125-
'bg-accent': this.state.active === child.value,
138+
'selected-item': this.state.selectedItem === child,
126139
},
127140
)}
128141
>
129-
<a href="javascript:void()" class="flex items-center space-x-2 whitespace-nowrap">
130-
<span>{child.text}</span>
131-
</a>
142+
<span>{child.text}</span>
132143
</li>
133144
)
134145
}
135146

136147
renderToolTipChild(child: SidebarItem) {
137148
return (
138-
<li class="py-1 h-9 px-3 rounded hover:bg-accent flex items-center text-sm text-zinc-500 dark:text-zinc-200">
139-
<a href={child.href} class="flex items-center space-x-2 whitespace-nowrap">
140-
<span>{child.text}</span>
141-
</a>
149+
<li
150+
onClick={() => this.select(child)}
151+
class={classNames(
152+
'py-1 h-9 px-3 rounded hover:bg-accent flex items-center text-sm text-zinc-500 dark:text-zinc-200 cursor-pointer',
153+
{
154+
'selected-item': this.state.selectedItem === child,
155+
},
156+
)}
157+
>
158+
<span>{child.text}</span>
142159
</li>
143160
)
144161
}
@@ -148,46 +165,29 @@ export class Sidebar extends Component<Props> {
148165
<div class="h-screen flex">
149166
<div
150167
class={classNames('bg-background text-foreground transition-all p-2 flex flex-col justify-between', {
151-
'w-60': this.state.isOpen,
152-
'w-16': !this.state.isOpen,
168+
'w-30': this.state.isOpen
153169
})}
154170
>
155171
<div>
156-
<div class={classNames('flex items-center h-[50px] space-x-2 justify-center')}>
172+
{/* <div class={classNames('flex items-center h-[50px] space-x-2 justify-center')}>
157173
<i class="h-8 w-8">
158174
<img src="https://omi.cdn-go.cn/admin/latest/home/omi.svg"></img>
159175
</i>
160-
<h1
161-
class={classNames('text-2xl font-semibold whitespace-nowrap', {
162-
block: this.state.isOpen,
163-
hidden: !this.state.isOpen,
164-
})}
165-
>
166-
OMI Admin
167-
</h1>
168-
</div>
169-
<div
170-
class={classNames('mb-2', {
171-
block: this.state.isOpen,
172-
hidden: !this.state.isOpen,
173-
})}
174-
>
175-
<input type="text" placeholder="Search" class="px-3 w-full p-1 border rounded" />
176-
</div>
176+
</div> */}
177177
<nav class="h-[calc(100vh-300px)] overflow-auto">
178178
<ul>
179179
{this.props.items.map((item: SidebarItem) => {
180180
const hasChildren = !!(item.children && item.children.length)
181181
return (
182182
<li>
183-
<a
184-
href={hasChildren ? 'javascript:' : item.href}
185-
onClick={() => this.onItemClick(item)}
183+
<div
184+
onClick={() => hasChildren ? this.onItemClick(item) : this.select(item)}
186185
onMouseEnter={() => this.onMouseEnter(item)}
187186
onMouseLeave={() => this.onMouseLeave(item)}
188-
class={classNames('trigger flex items-center hover:bg-accent h-9 rounded px-2', {
187+
class={classNames('trigger flex items-center hover:bg-accent h-9 rounded px-2 cursor-pointer', {
189188
'justify-between': this.state.isOpen,
190189
'justify-center': !this.state.isOpen,
190+
'selected-item': this.state.selectedItem === item,
191191
})}
192192
>
193193
<div class="flex items-center space-x-2 text-zinc-600 dark:text-zinc-200">
@@ -216,7 +216,7 @@ export class Sidebar extends Component<Props> {
216216
)}
217217
></i>
218218
)}
219-
</a>
219+
</div>
220220
{hasChildren && this.state.isOpen && (
221221
<ul
222222
class="transition-all overflow-hidden"
@@ -235,7 +235,7 @@ export class Sidebar extends Component<Props> {
235235
</ul>
236236
</nav>
237237
</div>
238-
{this.state.isOpen && (
238+
{/* {this.state.isOpen && (
239239
<div class="bg-primary text-white rounded p-4 w-56">
240240
<h2 class="font-semibold mb-2">重点公告位</h2>
241241
<p class="text-sm mb-4">
@@ -245,7 +245,7 @@ export class Sidebar extends Component<Props> {
245245
知道了
246246
</button>
247247
</div>
248-
)}
248+
)} */}
249249
</div>
250250
</div>
251251
)

packages/omi-low-code/src/pages/home.tsx

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,64 @@
11
// import { isDark } from '../store.ts'
22
import '../components/omiu/button.tsx'
3+
import '../components/sidebar.tsx'
4+
import { SidebarItem } from '../components/sidebar.tsx'
35

46
export function Home() {
7+
// mock data
8+
const sidebarItems: SidebarItem[] = [
9+
{
10+
text: '文件',
11+
target: '_self',
12+
name: 'components',
13+
path: '/components',
14+
value: 'components',
15+
type: 'menu',
16+
icon: 'layers',
17+
children: []
18+
},
19+
{
20+
text: '样式设置',
21+
target: '_self',
22+
name: 'structure',
23+
path: '/structure',
24+
value: 'structure',
25+
type: 'menu',
26+
icon: 'layers',
27+
children: [],
28+
},
29+
{
30+
text: '状态变量',
31+
target: '_self',
32+
name: 'variables',
33+
path: '/variables',
34+
value: 'variables',
35+
type: 'menu',
36+
icon: 'layers',
37+
children: [],
38+
},
39+
{
40+
text: '事件绑定',
41+
target: '_self',
42+
name: 'api',
43+
path: '/api',
44+
value: 'api',
45+
type: 'menu',
46+
icon: 'layers',
47+
children: [],
48+
}
49+
];
50+
51+
552
return (
653
<>
754
<div class="flex h-screen">
8-
<div class="w-1/12 p-1 dark:bg-background dark:text-foreground">Sidebar</div>
9-
55+
{/* <div class="w-1/12 p-1 dark:bg-background dark:text-foreground">Sidebar</div> */}
56+
<o-sidebar
57+
items={sidebarItems}
58+
active=""
59+
isOpen={true}
60+
></o-sidebar>
61+
1062
<div class="flex-grow p-1 dark:bg-background dark:text-foreground">
1163
<div class="flex h-full">
1264
<section class="w-1/4 p-4 dark:bg-background bg-gray-200 dark:text-foreground">Column 1</section>

0 commit comments

Comments
 (0)