blixify-ui-web-mcp 0.1.49 → 0.1.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -97,6 +97,39 @@ const navigation = [
97
97
  />;
98
98
  ```
99
99
 
100
+ ##### Icon rail
101
+
102
+ A narrow column of icons left of the sidebar — the two-level layout of tools like monday.com. The rail switches between whole areas of the app (a workspace tree, chat, agents, notifications); the sidebar beside it navigates inside the area that is open. Without `railItems` nothing changes.
103
+
104
+ ```jsx
105
+ import { BellIcon, ChatBubbleLeftRightIcon, Cog6ToothIcon, Squares2X2Icon } from "@heroicons/react/24/outline";
106
+
107
+ const [railId, setRailId] = useState("workspace");
108
+
109
+ <LeftNav
110
+ railItems={[
111
+ { id: "workspace", name: "Workspace", icon: Squares2X2Icon },
112
+ { id: "chat", name: "Chat", icon: ChatBubbleLeftRightIcon, href: "/chat" },
113
+ { id: "notifications", name: "Alerts", icon: BellIcon, badge: 9 },
114
+ ]}
115
+ railFooterItems={[{ id: "settings", name: "Settings", icon: Cog6ToothIcon }]}
116
+ selectedRailId={railId}
117
+ handleRailOnClick={(id) => setRailId(id)}
118
+ {...otherProps}
119
+ />;
120
+ ```
121
+
122
+ | Name | Type | Description |
123
+ | ------------------ | ---------------------- | ------------------------------------------------------------------------------------------------ |
124
+ | `railItems` | `RailItem[]` | Icons at the top of the rail. Turns the rail on. |
125
+ | `railFooterItems` | `RailItem[]` | Icons pinned to the bottom of the rail, for settings-type entries. |
126
+ | `selectedRailId` | `string` | The `id` of the open area, highlighted. |
127
+ | `handleRailOnClick`| `(id: string) => void` | Called with the item `id` on every click, link or not. |
128
+
129
+ `RailItem` is `{ id, name, icon, href?, badge? }`. With `href` the item is a link through the same `linkType` / `custom` as the sidebar; without it the item only reports `handleRailOnClick`. `badge` shows a count on the icon — `0`, empty or absent hides it, and a number over 99 reads `99+`.
130
+
131
+ Below `lg` the rail moves into the mobile drawer as a row of icons above the sidebar's list.
132
+
100
133
  ##### Required props
101
134
 
102
135
  | Name | Type | Description |
@@ -1,11 +1,16 @@
1
1
  import {
2
+ BellIcon,
3
+ ChatBubbleLeftRightIcon,
4
+ Cog6ToothIcon,
5
+ CpuChipIcon,
2
6
  FolderIcon,
3
7
  FunnelIcon,
4
8
  HomeIcon,
9
+ Squares2X2Icon,
5
10
  UsersIcon,
6
11
  } from "@heroicons/react/24/outline";
7
12
  import React, { useState } from "react";
8
- import { LeftNav as LeftNavImpl, Navigation } from ".";
13
+ import { LeftNav as LeftNavImpl, Navigation, RailItem } from ".";
9
14
  import { BarMove } from "../bars";
10
15
  import { StorySection } from "../../storyUtils";
11
16
  import Logo from "../../../assets/logo.png";
@@ -221,6 +226,74 @@ const workspaceNavigation = [
221
226
  },
222
227
  ];
223
228
 
229
+ // INFO: the rail switches between whole areas; the sidebar beside it lists the
230
+ // pages inside the area that is open
231
+ const railItems: RailItem[] = [
232
+ { id: "workspace", name: "Workspace", icon: Squares2X2Icon },
233
+ { id: "chat", name: "Chat", icon: ChatBubbleLeftRightIcon },
234
+ { id: "agents", name: "Agents", icon: CpuChipIcon },
235
+ { id: "notifications", name: "Alerts", icon: BellIcon, badge: 9 },
236
+ ];
237
+
238
+ // INFO: each area brings its own sidebar list
239
+ const railNavigation: { [railId: string]: Navigation[] } = {
240
+ chat: [
241
+ {
242
+ id: "chat-new",
243
+ name: "New chat",
244
+ href: "/chat",
245
+ icon: ChatBubbleLeftRightIcon,
246
+ },
247
+ {
248
+ id: "chat-1",
249
+ name: "Quarterly sales recap",
250
+ href: "/chat/1",
251
+ icon: ChatBubbleLeftRightIcon,
252
+ },
253
+ ],
254
+ agents: [
255
+ {
256
+ id: "agent-1",
257
+ name: "Lead qualifier",
258
+ href: "/agents/1",
259
+ icon: CpuChipIcon,
260
+ },
261
+ {
262
+ id: "agent-2",
263
+ name: "Support triage",
264
+ href: "/agents/2",
265
+ icon: CpuChipIcon,
266
+ },
267
+ ],
268
+ notifications: [
269
+ { id: "note-all", name: "All", href: "/alerts", icon: BellIcon },
270
+ {
271
+ id: "note-unread",
272
+ name: "Unread",
273
+ href: "/alerts/unread",
274
+ icon: BellIcon,
275
+ },
276
+ ],
277
+ settings: [
278
+ {
279
+ id: "set-members",
280
+ name: "Members",
281
+ href: "/settings/members",
282
+ icon: UsersIcon,
283
+ },
284
+ {
285
+ id: "set-workspace",
286
+ name: "Workspace",
287
+ href: "/settings/workspace",
288
+ icon: Cog6ToothIcon,
289
+ },
290
+ ],
291
+ };
292
+
293
+ const railFooterItems: RailItem[] = [
294
+ { id: "settings", name: "Settings", icon: Cog6ToothIcon },
295
+ ];
296
+
224
297
  const renderLogo = (collapse?: boolean) => (
225
298
  <div className="flex items-center flex-shrink-0 px-6 cursor-pointer">
226
299
  <img
@@ -285,6 +358,8 @@ export const LeftNav = () => {
285
358
  // button, so each story needs its own open state for that button to work on
286
359
  // a phone
287
360
  const [mobileStoryId, setMobileStoryId] = useState("");
361
+ const [railId, setRailId] = useState("workspace");
362
+ const [darkRailId, setDarkRailId] = useState("workspace");
288
363
 
289
364
  const handleMobileMenu = (storyId: string) => ({
290
365
  leftNavMobileMenu: mobileStoryId === storyId,
@@ -639,6 +714,63 @@ export const LeftNav = () => {
639
714
  </div>
640
715
  </StorySection>
641
716
 
717
+ <StorySection
718
+ title="Icon Rail"
719
+ description="railItems adds a narrow column of icons left of the sidebar, the two-level layout of tools like monday.com: the rail switches between whole areas (workspace, chat, agents, alerts), the sidebar beside it navigates inside the open one. selectedRailId highlights the open area, badge shows a count (over 99 reads 99+), and railFooterItems sit at the bottom for settings-type entries. An item with href is a link; without one it only reports handleRailOnClick. Without railItems nothing changes. Below lg the rail moves into the drawer as a row of icons above the list — open the menu at phone width to see it."
720
+ >
721
+ <div className="w-full h-96 relative overflow-hidden border rounded-lg">
722
+ <LeftNavImpl
723
+ selectedId={workspaceSelectedId}
724
+ navigation={
725
+ railId === "workspace"
726
+ ? workspaceNavigation
727
+ : (railNavigation[railId] ?? [])
728
+ }
729
+ {...handleMobileMenu("story-rail")}
730
+ compactMode={true}
731
+ railItems={railItems}
732
+ railFooterItems={railFooterItems}
733
+ selectedRailId={railId}
734
+ handleRailOnClick={(id) => setRailId(id)}
735
+ handleBarsOnClick={(id) => setWorkspaceSelectedId(id)}
736
+ renderDashboardLogo={() => renderLogo()}
737
+ renderDashboardContent={() => (
738
+ <div className="p-6 text-sm text-gray-500">
739
+ {`Open area: ${railId}`}
740
+ </div>
741
+ )}
742
+ renderDashboardHeaderContent={renderHeader}
743
+ />
744
+ </div>
745
+ </StorySection>
746
+
747
+ <StorySection
748
+ title="Icon Rail — Dark Mode"
749
+ description="The rail follows darkMode and navbarBgColor like the sidebar, so the two read as one surface."
750
+ dark
751
+ >
752
+ <div className="w-full h-96 relative overflow-hidden border border-gray-700 rounded-lg">
753
+ <LeftNavImpl
754
+ selectedId={selectedId}
755
+ navigation={navigation}
756
+ {...handleMobileMenu("story-rail-dark")}
757
+ darkMode={true}
758
+ railItems={railItems}
759
+ railFooterItems={railFooterItems}
760
+ selectedRailId={darkRailId}
761
+ handleRailOnClick={(id) => setDarkRailId(id)}
762
+ handleBarsOnClick={(id) => setSelectedId(id)}
763
+ renderDashboardLogo={() => renderLogo()}
764
+ renderDashboardContent={() => (
765
+ <div className="p-6 text-gray-400 text-sm">
766
+ {`Open area: ${darkRailId}`}
767
+ </div>
768
+ )}
769
+ renderDashboardHeaderContent={renderHeader}
770
+ />
771
+ </div>
772
+ </StorySection>
773
+
642
774
  <StorySection
643
775
  title="Transparent"
644
776
  description="transparent makes the TOP HEADER BAR see-through, dropping its background, shadow and bottom border so a page can run its own hero or image up under it — the same pair Header carries. mobileOpaque keeps that bar solid below lg, where it holds the hamburger and is the only way back to the nav. The sidebar itself is unaffected. Shown over a gradient page so the effect is visible."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blixify-ui-web-mcp",
3
- "version": "0.1.49",
3
+ "version": "0.1.50",
4
4
  "license": "MIT",
5
5
  "main": "lib/mcp/server.js",
6
6
  "bin": {