@lateralus-ai/shipping-ui 1.4.13 → 1.4.14
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.
- package/README.md +108 -108
- package/dist/index.cjs +38 -38
- package/dist/index.esm.js +4495 -4489
- package/dist/tailwind-theme.d.ts +12 -0
- package/package.json +99 -99
- package/src/components/DocumentEditor/DocumentEditor.tsx +871 -871
- package/src/components/HelloWorld.tsx +3 -3
- package/src/components/InputPrompt.tsx +96 -96
- package/src/components/ModalPanel.tsx +49 -49
- package/src/components/PdfViewer/ImageViewer.tsx +211 -211
- package/src/components/PdfViewer/PdfViewer.tsx +232 -232
- package/src/components/PdfViewer/index.ts +2 -2
- package/src/components/PdfViewer/usePageManagement.ts +32 -32
- package/src/components/PdfViewer/usePanning.ts +42 -42
- package/src/components/PdfViewer/useRefDimensions.ts +16 -16
- package/src/components/PdfViewer/useRotation.ts +13 -13
- package/src/components/PdfViewer/useZoom.ts +26 -26
- package/src/components/SearchModal.tsx +320 -320
- package/src/components/Sidebar/Button.tsx +20 -20
- package/src/components/Sidebar/Container.tsx +31 -31
- package/src/components/Sidebar/Item.tsx +39 -39
- package/src/components/Sidebar/Layout.tsx +32 -32
- package/src/components/Sidebar/Provider.tsx +47 -47
- package/src/components/Sidebar/SecondaryItem.tsx +39 -39
- package/src/components/Sidebar/SideContainer.tsx +31 -31
- package/src/components/Sidebar/ToggleCollapseButton.tsx +24 -24
- package/src/components/Sidebar/index.ts +8 -8
- package/src/components/Tabs.tsx +43 -43
- package/src/components/icons/CloseSidebarIcon.tsx +19 -19
- package/src/components/icons/CloseSidebarMidIcon.tsx +19 -19
- package/src/components/icons/ExpandIcon.tsx +21 -21
- package/src/components/icons/SendArrowIcon.tsx +23 -23
- package/src/components/icons/SendArrowIconGreen.tsx +17 -17
- package/src/components/icons/SettingsIcon.tsx +33 -33
- package/src/components/icons/XIcon.tsx +21 -21
- package/src/components/index.ts +6 -6
- package/src/index.ts +4 -4
- package/src/material-theme.ts +477 -477
- package/src/stories/Buttons.stories.tsx +15 -15
- package/src/stories/Buttons.tsx +52 -52
- package/src/stories/Checkbox.stories.tsx +15 -15
- package/src/stories/Checkbox.tsx +56 -56
- package/src/stories/ColorPalette.stories.tsx +15 -15
- package/src/stories/ColorPalette.tsx +85 -72
- package/src/stories/DocumentEditor.stories.tsx +287 -287
- package/src/stories/Dropdowns.stories.tsx +15 -15
- package/src/stories/Dropdowns.tsx +52 -52
- package/src/stories/InputPrompt.stories.tsx +15 -15
- package/src/stories/InputPrompt.tsx +63 -63
- package/src/stories/ModalHeader.stories.tsx +35 -35
- package/src/stories/PDFViewer.stories.tsx +39 -39
- package/src/stories/SearchModal.stories.tsx +132 -132
- package/src/stories/SearchModal.tsx +82 -82
- package/src/stories/Sidebar.stories.tsx +15 -15
- package/src/stories/Sidebar.tsx +108 -108
- package/src/stories/Tabs.stories.tsx +51 -51
- package/src/stories/Typography.stories.tsx +15 -15
- package/src/stories/Typography.tsx +110 -110
- package/src/style.css +2 -2
- package/src/styles/tabs.css +55 -55
- package/src/tailwind-theme.ts +243 -231
- package/src/types/documentEditor.ts +55 -55
- package/src/utils/checkboxModule.ts +241 -241
- package/src/utils/cn.ts +11 -11
|
@@ -1,132 +1,132 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
-
import { useState } from "react";
|
|
3
|
-
import SearchModal from "../components/SearchModal";
|
|
4
|
-
import type { SearchItem } from "../components/SearchModal";
|
|
5
|
-
import { Icon } from "@iconify/react";
|
|
6
|
-
|
|
7
|
-
const meta: Meta<typeof SearchModal> = {
|
|
8
|
-
title: "Design System/SearchModal",
|
|
9
|
-
component: SearchModal,
|
|
10
|
-
parameters: {
|
|
11
|
-
layout: "centered",
|
|
12
|
-
},
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export default meta;
|
|
16
|
-
type Story = StoryObj<typeof SearchModal>;
|
|
17
|
-
|
|
18
|
-
const mockItems: SearchItem[] = [
|
|
19
|
-
{
|
|
20
|
-
id: "1",
|
|
21
|
-
title: "Engine maintenance report",
|
|
22
|
-
subtitle: "Created by John Doe on January 15, 2025",
|
|
23
|
-
icon: <Icon icon="lucide:users" />,
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
id: "2",
|
|
27
|
-
title: "Navigation system update",
|
|
28
|
-
subtitle: "Updated yesterday at 3:45 PM",
|
|
29
|
-
icon: <Icon icon="lucide:message-circle" />,
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
id: "3",
|
|
33
|
-
title: "Crew training schedule",
|
|
34
|
-
subtitle: "Due date: February 1, 2025",
|
|
35
|
-
icon: <Icon icon="lucide:file" />,
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
id: "4",
|
|
39
|
-
title: "Fuel consumption analysis",
|
|
40
|
-
subtitle: "Last reviewed 3 days ago",
|
|
41
|
-
icon: <Icon icon="lucide:file-lock" />,
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
id: "5",
|
|
45
|
-
title: "Weather routing optimization",
|
|
46
|
-
subtitle: "Active route to Singapore",
|
|
47
|
-
icon: <Icon icon="lucide:file-lock" />,
|
|
48
|
-
},
|
|
49
|
-
];
|
|
50
|
-
|
|
51
|
-
const SearchModalWrapper = (args: any) => {
|
|
52
|
-
const [open, setOpen] = useState(true);
|
|
53
|
-
const [items, setItems] = useState(mockItems);
|
|
54
|
-
const [loading, setLoading] = useState(false);
|
|
55
|
-
const [selectedFilter, setSelectedFilter] = useState("All");
|
|
56
|
-
|
|
57
|
-
const handleSearch = (query: string) => {
|
|
58
|
-
setLoading(true);
|
|
59
|
-
setTimeout(() => {
|
|
60
|
-
const filtered = mockItems.filter(
|
|
61
|
-
(item) =>
|
|
62
|
-
item.title.toLowerCase().includes(query.toLowerCase()) ||
|
|
63
|
-
item.subtitle?.toLowerCase().includes(query.toLowerCase()),
|
|
64
|
-
);
|
|
65
|
-
setItems(filtered);
|
|
66
|
-
setLoading(false);
|
|
67
|
-
}, 300);
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const handleSelect = (item: SearchItem) => {
|
|
71
|
-
console.log("Selected item:", item);
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
return (
|
|
75
|
-
<>
|
|
76
|
-
<button
|
|
77
|
-
onClick={() => setOpen(true)}
|
|
78
|
-
className="px-4 py-2 bg-blue-500 text-white rounded-lg"
|
|
79
|
-
>
|
|
80
|
-
Open Search
|
|
81
|
-
</button>
|
|
82
|
-
<SearchModal
|
|
83
|
-
{...args}
|
|
84
|
-
open={open}
|
|
85
|
-
onClose={() => setOpen(false)}
|
|
86
|
-
items={items}
|
|
87
|
-
loading={loading}
|
|
88
|
-
onSearch={handleSearch}
|
|
89
|
-
onSelect={handleSelect}
|
|
90
|
-
selectedFilter={selectedFilter}
|
|
91
|
-
onFilterChange={setSelectedFilter}
|
|
92
|
-
/>
|
|
93
|
-
</>
|
|
94
|
-
);
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
export const Default: Story = {
|
|
98
|
-
render: (args) => <SearchModalWrapper {...args} />,
|
|
99
|
-
args: {
|
|
100
|
-
placeholder: "Search reports, chats, or issues…",
|
|
101
|
-
recentlyViewedLabel: "Recently viewed",
|
|
102
|
-
noResultsText: "No results found.",
|
|
103
|
-
},
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
export const WithFilters: Story = {
|
|
107
|
-
render: (args) => <SearchModalWrapper {...args} />,
|
|
108
|
-
args: {
|
|
109
|
-
placeholder: "Search reports, chats, or issues…",
|
|
110
|
-
filterOptions: ["All", "Chats", "Issues", "Resolved"],
|
|
111
|
-
recentlyViewedLabel: "Recently viewed",
|
|
112
|
-
noResultsText: "No results found.",
|
|
113
|
-
},
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
export const Loading: Story = {
|
|
117
|
-
args: {
|
|
118
|
-
open: true,
|
|
119
|
-
loading: true,
|
|
120
|
-
onClose: () => console.log("Closed"),
|
|
121
|
-
},
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
export const Empty: Story = {
|
|
125
|
-
args: {
|
|
126
|
-
open: true,
|
|
127
|
-
items: [],
|
|
128
|
-
onClose: () => console.log("Closed"),
|
|
129
|
-
placeholder: "Search for something...",
|
|
130
|
-
noResultsText: "No items found. Try a different search.",
|
|
131
|
-
},
|
|
132
|
-
};
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import SearchModal from "../components/SearchModal";
|
|
4
|
+
import type { SearchItem } from "../components/SearchModal";
|
|
5
|
+
import { Icon } from "@iconify/react";
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof SearchModal> = {
|
|
8
|
+
title: "Design System/SearchModal",
|
|
9
|
+
component: SearchModal,
|
|
10
|
+
parameters: {
|
|
11
|
+
layout: "centered",
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default meta;
|
|
16
|
+
type Story = StoryObj<typeof SearchModal>;
|
|
17
|
+
|
|
18
|
+
const mockItems: SearchItem[] = [
|
|
19
|
+
{
|
|
20
|
+
id: "1",
|
|
21
|
+
title: "Engine maintenance report",
|
|
22
|
+
subtitle: "Created by John Doe on January 15, 2025",
|
|
23
|
+
icon: <Icon icon="lucide:users" />,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: "2",
|
|
27
|
+
title: "Navigation system update",
|
|
28
|
+
subtitle: "Updated yesterday at 3:45 PM",
|
|
29
|
+
icon: <Icon icon="lucide:message-circle" />,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: "3",
|
|
33
|
+
title: "Crew training schedule",
|
|
34
|
+
subtitle: "Due date: February 1, 2025",
|
|
35
|
+
icon: <Icon icon="lucide:file" />,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: "4",
|
|
39
|
+
title: "Fuel consumption analysis",
|
|
40
|
+
subtitle: "Last reviewed 3 days ago",
|
|
41
|
+
icon: <Icon icon="lucide:file-lock" />,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: "5",
|
|
45
|
+
title: "Weather routing optimization",
|
|
46
|
+
subtitle: "Active route to Singapore",
|
|
47
|
+
icon: <Icon icon="lucide:file-lock" />,
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
const SearchModalWrapper = (args: any) => {
|
|
52
|
+
const [open, setOpen] = useState(true);
|
|
53
|
+
const [items, setItems] = useState(mockItems);
|
|
54
|
+
const [loading, setLoading] = useState(false);
|
|
55
|
+
const [selectedFilter, setSelectedFilter] = useState("All");
|
|
56
|
+
|
|
57
|
+
const handleSearch = (query: string) => {
|
|
58
|
+
setLoading(true);
|
|
59
|
+
setTimeout(() => {
|
|
60
|
+
const filtered = mockItems.filter(
|
|
61
|
+
(item) =>
|
|
62
|
+
item.title.toLowerCase().includes(query.toLowerCase()) ||
|
|
63
|
+
item.subtitle?.toLowerCase().includes(query.toLowerCase()),
|
|
64
|
+
);
|
|
65
|
+
setItems(filtered);
|
|
66
|
+
setLoading(false);
|
|
67
|
+
}, 300);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const handleSelect = (item: SearchItem) => {
|
|
71
|
+
console.log("Selected item:", item);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<>
|
|
76
|
+
<button
|
|
77
|
+
onClick={() => setOpen(true)}
|
|
78
|
+
className="px-4 py-2 bg-blue-500 text-white rounded-lg"
|
|
79
|
+
>
|
|
80
|
+
Open Search
|
|
81
|
+
</button>
|
|
82
|
+
<SearchModal
|
|
83
|
+
{...args}
|
|
84
|
+
open={open}
|
|
85
|
+
onClose={() => setOpen(false)}
|
|
86
|
+
items={items}
|
|
87
|
+
loading={loading}
|
|
88
|
+
onSearch={handleSearch}
|
|
89
|
+
onSelect={handleSelect}
|
|
90
|
+
selectedFilter={selectedFilter}
|
|
91
|
+
onFilterChange={setSelectedFilter}
|
|
92
|
+
/>
|
|
93
|
+
</>
|
|
94
|
+
);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export const Default: Story = {
|
|
98
|
+
render: (args) => <SearchModalWrapper {...args} />,
|
|
99
|
+
args: {
|
|
100
|
+
placeholder: "Search reports, chats, or issues…",
|
|
101
|
+
recentlyViewedLabel: "Recently viewed",
|
|
102
|
+
noResultsText: "No results found.",
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export const WithFilters: Story = {
|
|
107
|
+
render: (args) => <SearchModalWrapper {...args} />,
|
|
108
|
+
args: {
|
|
109
|
+
placeholder: "Search reports, chats, or issues…",
|
|
110
|
+
filterOptions: ["All", "Chats", "Issues", "Resolved"],
|
|
111
|
+
recentlyViewedLabel: "Recently viewed",
|
|
112
|
+
noResultsText: "No results found.",
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export const Loading: Story = {
|
|
117
|
+
args: {
|
|
118
|
+
open: true,
|
|
119
|
+
loading: true,
|
|
120
|
+
onClose: () => console.log("Closed"),
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export const Empty: Story = {
|
|
125
|
+
args: {
|
|
126
|
+
open: true,
|
|
127
|
+
items: [],
|
|
128
|
+
onClose: () => console.log("Closed"),
|
|
129
|
+
placeholder: "Search for something...",
|
|
130
|
+
noResultsText: "No items found. Try a different search.",
|
|
131
|
+
},
|
|
132
|
+
};
|
|
@@ -1,82 +1,82 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
|
-
import { SearchModal } from "../components/SearchModal";
|
|
3
|
-
|
|
4
|
-
const mockResults = [
|
|
5
|
-
{
|
|
6
|
-
id: "1",
|
|
7
|
-
title: "Create React App",
|
|
8
|
-
description: "Set up a modern web app by running one command",
|
|
9
|
-
category: "Documentation",
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
id: "2",
|
|
13
|
-
title: "React Router",
|
|
14
|
-
description: "Declarative routing for React apps at any scale",
|
|
15
|
-
category: "Library",
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
id: "3",
|
|
19
|
-
title: "Redux Toolkit",
|
|
20
|
-
description:
|
|
21
|
-
"The official, opinionated, batteries-included toolset for efficient Redux development",
|
|
22
|
-
category: "State Management",
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
id: "4",
|
|
26
|
-
title: "Material Tailwind",
|
|
27
|
-
description:
|
|
28
|
-
"React components library that implements Google's Material Design",
|
|
29
|
-
category: "UI Library",
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
id: "5",
|
|
33
|
-
title: "Tailwind CSS",
|
|
34
|
-
description: "A utility-first CSS framework for rapid UI development",
|
|
35
|
-
category: "Styling",
|
|
36
|
-
},
|
|
37
|
-
];
|
|
38
|
-
|
|
39
|
-
export const SearchModals = () => {
|
|
40
|
-
const [open, setOpen] = useState(false);
|
|
41
|
-
const [searchQuery, setSearchQuery] = useState("");
|
|
42
|
-
const [activeFilter, setActiveFilter] = useState<string>("");
|
|
43
|
-
|
|
44
|
-
const filteredResults = mockResults.filter((result) => {
|
|
45
|
-
const matchesQuery = result.title
|
|
46
|
-
.toLowerCase()
|
|
47
|
-
.includes(searchQuery.toLowerCase());
|
|
48
|
-
const matchesFilter = !activeFilter || result.category === activeFilter;
|
|
49
|
-
return matchesQuery && matchesFilter;
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
return (
|
|
53
|
-
<div className="p-8">
|
|
54
|
-
<button
|
|
55
|
-
onClick={() => setOpen(true)}
|
|
56
|
-
className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
|
|
57
|
-
>
|
|
58
|
-
Open Search Modal
|
|
59
|
-
</button>
|
|
60
|
-
|
|
61
|
-
<SearchModal
|
|
62
|
-
open={open}
|
|
63
|
-
onClose={() => setOpen(false)}
|
|
64
|
-
results={searchQuery ? filteredResults : []}
|
|
65
|
-
onSearch={setSearchQuery}
|
|
66
|
-
onResultClick={(result) => {
|
|
67
|
-
console.log("Selected:", result);
|
|
68
|
-
alert(`Selected: ${result.title}`);
|
|
69
|
-
}}
|
|
70
|
-
filters={[
|
|
71
|
-
"Documentation",
|
|
72
|
-
"Library",
|
|
73
|
-
"State Management",
|
|
74
|
-
"UI Library",
|
|
75
|
-
"Styling",
|
|
76
|
-
]}
|
|
77
|
-
activeFilter={activeFilter}
|
|
78
|
-
onFilterChange={setActiveFilter}
|
|
79
|
-
/>
|
|
80
|
-
</div>
|
|
81
|
-
);
|
|
82
|
-
};
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { SearchModal } from "../components/SearchModal";
|
|
3
|
+
|
|
4
|
+
const mockResults = [
|
|
5
|
+
{
|
|
6
|
+
id: "1",
|
|
7
|
+
title: "Create React App",
|
|
8
|
+
description: "Set up a modern web app by running one command",
|
|
9
|
+
category: "Documentation",
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
id: "2",
|
|
13
|
+
title: "React Router",
|
|
14
|
+
description: "Declarative routing for React apps at any scale",
|
|
15
|
+
category: "Library",
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: "3",
|
|
19
|
+
title: "Redux Toolkit",
|
|
20
|
+
description:
|
|
21
|
+
"The official, opinionated, batteries-included toolset for efficient Redux development",
|
|
22
|
+
category: "State Management",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: "4",
|
|
26
|
+
title: "Material Tailwind",
|
|
27
|
+
description:
|
|
28
|
+
"React components library that implements Google's Material Design",
|
|
29
|
+
category: "UI Library",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: "5",
|
|
33
|
+
title: "Tailwind CSS",
|
|
34
|
+
description: "A utility-first CSS framework for rapid UI development",
|
|
35
|
+
category: "Styling",
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
export const SearchModals = () => {
|
|
40
|
+
const [open, setOpen] = useState(false);
|
|
41
|
+
const [searchQuery, setSearchQuery] = useState("");
|
|
42
|
+
const [activeFilter, setActiveFilter] = useState<string>("");
|
|
43
|
+
|
|
44
|
+
const filteredResults = mockResults.filter((result) => {
|
|
45
|
+
const matchesQuery = result.title
|
|
46
|
+
.toLowerCase()
|
|
47
|
+
.includes(searchQuery.toLowerCase());
|
|
48
|
+
const matchesFilter = !activeFilter || result.category === activeFilter;
|
|
49
|
+
return matchesQuery && matchesFilter;
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
return (
|
|
53
|
+
<div className="p-8">
|
|
54
|
+
<button
|
|
55
|
+
onClick={() => setOpen(true)}
|
|
56
|
+
className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
|
|
57
|
+
>
|
|
58
|
+
Open Search Modal
|
|
59
|
+
</button>
|
|
60
|
+
|
|
61
|
+
<SearchModal
|
|
62
|
+
open={open}
|
|
63
|
+
onClose={() => setOpen(false)}
|
|
64
|
+
results={searchQuery ? filteredResults : []}
|
|
65
|
+
onSearch={setSearchQuery}
|
|
66
|
+
onResultClick={(result) => {
|
|
67
|
+
console.log("Selected:", result);
|
|
68
|
+
alert(`Selected: ${result.title}`);
|
|
69
|
+
}}
|
|
70
|
+
filters={[
|
|
71
|
+
"Documentation",
|
|
72
|
+
"Library",
|
|
73
|
+
"State Management",
|
|
74
|
+
"UI Library",
|
|
75
|
+
"Styling",
|
|
76
|
+
]}
|
|
77
|
+
activeFilter={activeFilter}
|
|
78
|
+
onFilterChange={setActiveFilter}
|
|
79
|
+
/>
|
|
80
|
+
</div>
|
|
81
|
+
);
|
|
82
|
+
};
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
-
import { SidebarScreen as Sidebar } from "./Sidebar";
|
|
3
|
-
|
|
4
|
-
const meta = {
|
|
5
|
-
title: "Design System/Sidebar",
|
|
6
|
-
component: Sidebar,
|
|
7
|
-
parameters: {
|
|
8
|
-
layout: "fullscreen",
|
|
9
|
-
},
|
|
10
|
-
} satisfies Meta<typeof Sidebar>;
|
|
11
|
-
|
|
12
|
-
export default meta;
|
|
13
|
-
type Story = StoryObj<typeof meta>;
|
|
14
|
-
|
|
15
|
-
export const Default: Story = {};
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { SidebarScreen as Sidebar } from "./Sidebar";
|
|
3
|
+
|
|
4
|
+
const meta = {
|
|
5
|
+
title: "Design System/Sidebar",
|
|
6
|
+
component: Sidebar,
|
|
7
|
+
parameters: {
|
|
8
|
+
layout: "fullscreen",
|
|
9
|
+
},
|
|
10
|
+
} satisfies Meta<typeof Sidebar>;
|
|
11
|
+
|
|
12
|
+
export default meta;
|
|
13
|
+
type Story = StoryObj<typeof meta>;
|
|
14
|
+
|
|
15
|
+
export const Default: Story = {};
|
package/src/stories/Sidebar.tsx
CHANGED
|
@@ -1,108 +1,108 @@
|
|
|
1
|
-
import { Icon } from "@iconify/react"
|
|
2
|
-
import { Sidebar } from "../components"
|
|
3
|
-
import {
|
|
4
|
-
Button,
|
|
5
|
-
IconButton,
|
|
6
|
-
Menu,
|
|
7
|
-
MenuHandler,
|
|
8
|
-
MenuItem,
|
|
9
|
-
MenuList,
|
|
10
|
-
} from "@material-tailwind/react"
|
|
11
|
-
|
|
12
|
-
const menuExample = (
|
|
13
|
-
<div className="opacity-0 group-hover:opacity-100">
|
|
14
|
-
<Menu placement="right" offset={{ mainAxis: -40 }}>
|
|
15
|
-
<MenuHandler>
|
|
16
|
-
<IconButton color="gray" size="sm" variant="text">
|
|
17
|
-
<Icon icon="lucide:ellipsis" className="size-4" />
|
|
18
|
-
</IconButton>
|
|
19
|
-
</MenuHandler>
|
|
20
|
-
<MenuList>
|
|
21
|
-
<MenuItem>Menu Item 1</MenuItem>
|
|
22
|
-
<MenuItem>Menu Item 2</MenuItem>
|
|
23
|
-
<MenuItem className="text-red-500">Menu Item 3</MenuItem>
|
|
24
|
-
</MenuList>
|
|
25
|
-
</Menu>
|
|
26
|
-
</div>
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
const arrowExample = (
|
|
30
|
-
<button>
|
|
31
|
-
<Icon icon="mage:caret-right" className="size-4" />
|
|
32
|
-
</button>
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
export const SidebarScreen = () => (
|
|
36
|
-
<div className="p-8 flex ">
|
|
37
|
-
<Sidebar.Layout
|
|
38
|
-
className="h-[800px]"
|
|
39
|
-
sideClassName="bg-gray-100"
|
|
40
|
-
sideContainer={
|
|
41
|
-
<>
|
|
42
|
-
<Button>
|
|
43
|
-
<Icon icon="mage:message" className="size-5 text-orange-400" />
|
|
44
|
-
</Button>
|
|
45
|
-
<Button>
|
|
46
|
-
<Icon icon="mage:book" className="size-5 text-orange-400" />
|
|
47
|
-
</Button>
|
|
48
|
-
</>
|
|
49
|
-
}
|
|
50
|
-
>
|
|
51
|
-
<div className="w-full flex flex-col gap-2 justify-center">
|
|
52
|
-
<div className="flex justify-between pr-1">
|
|
53
|
-
<Sidebar.Button
|
|
54
|
-
onClick={() => alert("click")}
|
|
55
|
-
icon={<Icon icon="mage:box-check" className="size-6" />}
|
|
56
|
-
>
|
|
57
|
-
{" "}
|
|
58
|
-
Lorem ipsum
|
|
59
|
-
</Sidebar.Button>
|
|
60
|
-
|
|
61
|
-
<Sidebar.ToggleCollapseButton />
|
|
62
|
-
</div>
|
|
63
|
-
|
|
64
|
-
<Sidebar.Item
|
|
65
|
-
icon={<Icon icon="mage:book" className="size-6" />}
|
|
66
|
-
trailing={arrowExample}
|
|
67
|
-
>
|
|
68
|
-
Dorcet sit amet
|
|
69
|
-
</Sidebar.Item>
|
|
70
|
-
|
|
71
|
-
<Sidebar.Item
|
|
72
|
-
icon={<Icon icon="mage:calendar" className="size-6" />}
|
|
73
|
-
isActive
|
|
74
|
-
>
|
|
75
|
-
Tempore ipsa
|
|
76
|
-
</Sidebar.Item>
|
|
77
|
-
|
|
78
|
-
<Sidebar.Item icon={<Icon icon="mage:email" className="size-6" />}>
|
|
79
|
-
{" "}
|
|
80
|
-
Duis ditarcher
|
|
81
|
-
</Sidebar.Item>
|
|
82
|
-
|
|
83
|
-
<div className="w-full flex flex-col gap-1 relative">
|
|
84
|
-
<Sidebar.SecondaryItem
|
|
85
|
-
trailing={menuExample}
|
|
86
|
-
icon={
|
|
87
|
-
<Icon icon="mage:message" className="size-5 text-orange-400" />
|
|
88
|
-
}
|
|
89
|
-
>
|
|
90
|
-
{" "}
|
|
91
|
-
Dolore eu fugiat nulla
|
|
92
|
-
</Sidebar.SecondaryItem>
|
|
93
|
-
|
|
94
|
-
<Sidebar.SecondaryItem
|
|
95
|
-
trailing={menuExample}
|
|
96
|
-
icon={<Icon icon="mage:message" className="size-5" />}
|
|
97
|
-
>
|
|
98
|
-
Lorem ipsum dorcet sit
|
|
99
|
-
</Sidebar.SecondaryItem>
|
|
100
|
-
|
|
101
|
-
<Sidebar.SecondaryItem>Show all</Sidebar.SecondaryItem>
|
|
102
|
-
</div>
|
|
103
|
-
</div>
|
|
104
|
-
|
|
105
|
-
<div className="h-20 bg-gray-100 w-full rounded-xl"></div>
|
|
106
|
-
</Sidebar.Layout>
|
|
107
|
-
</div>
|
|
108
|
-
)
|
|
1
|
+
import { Icon } from "@iconify/react"
|
|
2
|
+
import { Sidebar } from "../components"
|
|
3
|
+
import {
|
|
4
|
+
Button,
|
|
5
|
+
IconButton,
|
|
6
|
+
Menu,
|
|
7
|
+
MenuHandler,
|
|
8
|
+
MenuItem,
|
|
9
|
+
MenuList,
|
|
10
|
+
} from "@material-tailwind/react"
|
|
11
|
+
|
|
12
|
+
const menuExample = (
|
|
13
|
+
<div className="opacity-0 group-hover:opacity-100">
|
|
14
|
+
<Menu placement="right" offset={{ mainAxis: -40 }}>
|
|
15
|
+
<MenuHandler>
|
|
16
|
+
<IconButton color="gray" size="sm" variant="text">
|
|
17
|
+
<Icon icon="lucide:ellipsis" className="size-4" />
|
|
18
|
+
</IconButton>
|
|
19
|
+
</MenuHandler>
|
|
20
|
+
<MenuList>
|
|
21
|
+
<MenuItem>Menu Item 1</MenuItem>
|
|
22
|
+
<MenuItem>Menu Item 2</MenuItem>
|
|
23
|
+
<MenuItem className="text-red-500">Menu Item 3</MenuItem>
|
|
24
|
+
</MenuList>
|
|
25
|
+
</Menu>
|
|
26
|
+
</div>
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
const arrowExample = (
|
|
30
|
+
<button>
|
|
31
|
+
<Icon icon="mage:caret-right" className="size-4" />
|
|
32
|
+
</button>
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
export const SidebarScreen = () => (
|
|
36
|
+
<div className="p-8 flex ">
|
|
37
|
+
<Sidebar.Layout
|
|
38
|
+
className="h-[800px]"
|
|
39
|
+
sideClassName="bg-gray-100"
|
|
40
|
+
sideContainer={
|
|
41
|
+
<>
|
|
42
|
+
<Button>
|
|
43
|
+
<Icon icon="mage:message" className="size-5 text-orange-400" />
|
|
44
|
+
</Button>
|
|
45
|
+
<Button>
|
|
46
|
+
<Icon icon="mage:book" className="size-5 text-orange-400" />
|
|
47
|
+
</Button>
|
|
48
|
+
</>
|
|
49
|
+
}
|
|
50
|
+
>
|
|
51
|
+
<div className="w-full flex flex-col gap-2 justify-center">
|
|
52
|
+
<div className="flex justify-between pr-1">
|
|
53
|
+
<Sidebar.Button
|
|
54
|
+
onClick={() => alert("click")}
|
|
55
|
+
icon={<Icon icon="mage:box-check" className="size-6" />}
|
|
56
|
+
>
|
|
57
|
+
{" "}
|
|
58
|
+
Lorem ipsum
|
|
59
|
+
</Sidebar.Button>
|
|
60
|
+
|
|
61
|
+
<Sidebar.ToggleCollapseButton />
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<Sidebar.Item
|
|
65
|
+
icon={<Icon icon="mage:book" className="size-6" />}
|
|
66
|
+
trailing={arrowExample}
|
|
67
|
+
>
|
|
68
|
+
Dorcet sit amet
|
|
69
|
+
</Sidebar.Item>
|
|
70
|
+
|
|
71
|
+
<Sidebar.Item
|
|
72
|
+
icon={<Icon icon="mage:calendar" className="size-6" />}
|
|
73
|
+
isActive
|
|
74
|
+
>
|
|
75
|
+
Tempore ipsa
|
|
76
|
+
</Sidebar.Item>
|
|
77
|
+
|
|
78
|
+
<Sidebar.Item icon={<Icon icon="mage:email" className="size-6" />}>
|
|
79
|
+
{" "}
|
|
80
|
+
Duis ditarcher
|
|
81
|
+
</Sidebar.Item>
|
|
82
|
+
|
|
83
|
+
<div className="w-full flex flex-col gap-1 relative">
|
|
84
|
+
<Sidebar.SecondaryItem
|
|
85
|
+
trailing={menuExample}
|
|
86
|
+
icon={
|
|
87
|
+
<Icon icon="mage:message" className="size-5 text-orange-400" />
|
|
88
|
+
}
|
|
89
|
+
>
|
|
90
|
+
{" "}
|
|
91
|
+
Dolore eu fugiat nulla
|
|
92
|
+
</Sidebar.SecondaryItem>
|
|
93
|
+
|
|
94
|
+
<Sidebar.SecondaryItem
|
|
95
|
+
trailing={menuExample}
|
|
96
|
+
icon={<Icon icon="mage:message" className="size-5" />}
|
|
97
|
+
>
|
|
98
|
+
Lorem ipsum dorcet sit
|
|
99
|
+
</Sidebar.SecondaryItem>
|
|
100
|
+
|
|
101
|
+
<Sidebar.SecondaryItem>Show all</Sidebar.SecondaryItem>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
<div className="h-20 bg-gray-100 w-full rounded-xl"></div>
|
|
106
|
+
</Sidebar.Layout>
|
|
107
|
+
</div>
|
|
108
|
+
)
|