@mostrom/app-shell 0.1.3 → 0.1.5

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.
@@ -1,127 +0,0 @@
1
- "use client";
2
-
3
- import React from "react";
4
- import { Button } from "../ui/button";
5
- import {
6
- DropdownMenu,
7
- DropdownMenuContent,
8
- DropdownMenuGroup,
9
- DropdownMenuItem,
10
- DropdownMenuLabel,
11
- DropdownMenuSeparator,
12
- DropdownMenuTrigger,
13
- } from "../ui/dropdown-menu";
14
- import type {
15
- MenuDropdownItems,
16
- MenuDropdownItem,
17
- MenuDropdownItemGroup,
18
- MenuItemClickHandler,
19
- } from "./ServicesMenu";
20
-
21
- type AllServicesButtonProps = {
22
- items: MenuDropdownItems;
23
- onItemClick?: MenuItemClickHandler;
24
- };
25
-
26
- const DotsNineIcon = () => (
27
- <svg
28
- aria-hidden="true"
29
- focusable="false"
30
- width="24"
31
- height="24"
32
- viewBox="0 0 24 24"
33
- >
34
- {([5, 12, 19] as const).flatMap((cx) =>
35
- ([5, 12, 19] as const).map((cy) => (
36
- <circle key={`${cx}-${cy}`} cx={cx} cy={cy} r={1.6} fill="currentColor" />
37
- )),
38
- )}
39
- </svg>
40
- );
41
-
42
- const isGroup = (item: MenuDropdownItem | MenuDropdownItemGroup): item is MenuDropdownItemGroup =>
43
- typeof (item as MenuDropdownItemGroup).items !== "undefined";
44
-
45
- export function AllServicesButton({ items, onItemClick }: AllServicesButtonProps) {
46
- const handleItemClick = (item: MenuDropdownItem) => {
47
- if (item.disabled) return;
48
- onItemClick?.({
49
- id: item.id,
50
- href: item.href,
51
- external: item.external,
52
- });
53
- };
54
-
55
- const renderItem = (item: MenuDropdownItem) => {
56
- const content = (
57
- <>
58
- <span>{item.text}</span>
59
- {item.description && (
60
- <span className="text-xs text-muted-foreground ml-2">{item.description}</span>
61
- )}
62
- </>
63
- );
64
-
65
- if (item.href) {
66
- return (
67
- <DropdownMenuItem key={item.id} asChild disabled={item.disabled}>
68
- <a
69
- href={item.href}
70
- target={item.external ? "_blank" : undefined}
71
- rel={item.external ? "noopener noreferrer" : undefined}
72
- onClick={() => handleItemClick(item)}
73
- >
74
- {content}
75
- </a>
76
- </DropdownMenuItem>
77
- );
78
- }
79
-
80
- return (
81
- <DropdownMenuItem
82
- key={item.id}
83
- disabled={item.disabled}
84
- onSelect={() => handleItemClick(item)}
85
- >
86
- {content}
87
- </DropdownMenuItem>
88
- );
89
- };
90
-
91
- return (
92
- <div className="app-shell-apps-button">
93
- <DropdownMenu>
94
- <DropdownMenuTrigger asChild>
95
- <Button
96
- variant="ghost"
97
- size="icon"
98
- aria-label="Apps"
99
- className="h-9 w-9 hover:bg-transparent"
100
- >
101
- <span className="app-shell-apps-icon">
102
- <DotsNineIcon />
103
- </span>
104
- </Button>
105
- </DropdownMenuTrigger>
106
- <DropdownMenuContent align="start" sideOffset={8} className="w-64 max-h-96 overflow-y-auto">
107
- {items.map((item, index) => {
108
- if (isGroup(item)) {
109
- return (
110
- <React.Fragment key={item.text || `group-${index}`}>
111
- {index > 0 && <DropdownMenuSeparator />}
112
- <DropdownMenuGroup>
113
- {item.text && (
114
- <DropdownMenuLabel>{item.text}</DropdownMenuLabel>
115
- )}
116
- {item.items.map((subItem) => renderItem(subItem as MenuDropdownItem))}
117
- </DropdownMenuGroup>
118
- </React.Fragment>
119
- );
120
- }
121
- return renderItem(item as MenuDropdownItem);
122
- })}
123
- </DropdownMenuContent>
124
- </DropdownMenu>
125
- </div>
126
- );
127
- }
@@ -1,120 +0,0 @@
1
- "use client";
2
-
3
- import React from "react";
4
- import { Button } from "../ui/button";
5
- import {
6
- DropdownMenu,
7
- DropdownMenuContent,
8
- DropdownMenuItem,
9
- DropdownMenuTrigger,
10
- } from "../ui/dropdown-menu";
11
- import type {
12
- MenuDropdownItems,
13
- MenuDropdownItem,
14
- MenuDropdownItemGroup,
15
- MenuItemClickHandler,
16
- } from "./ServicesMenu";
17
-
18
- type CategoriesButtonProps = {
19
- items: MenuDropdownItems;
20
- onItemClick?: MenuItemClickHandler;
21
- };
22
-
23
- const SquaresFourIcon = () => (
24
- <svg
25
- aria-hidden="true"
26
- focusable="false"
27
- width="22"
28
- height="22"
29
- viewBox="0 0 24 24"
30
- >
31
- <rect x="4" y="4" width="7" height="7" rx="1.4" fill="currentColor" />
32
- <rect x="13" y="4" width="7" height="7" rx="1.4" fill="currentColor" />
33
- <rect x="4" y="13" width="7" height="7" rx="1.4" fill="currentColor" />
34
- <rect x="13" y="13" width="7" height="7" rx="1.4" fill="currentColor" />
35
- </svg>
36
- );
37
-
38
- const isGroup = (item: MenuDropdownItem | MenuDropdownItemGroup): item is MenuDropdownItemGroup =>
39
- typeof (item as MenuDropdownItemGroup).items !== "undefined";
40
-
41
- const flattenItems = (items: MenuDropdownItems): MenuDropdownItem[] => {
42
- const result: MenuDropdownItem[] = [];
43
- items.forEach((item) => {
44
- if (isGroup(item)) {
45
- result.push(...flattenItems(item.items));
46
- } else {
47
- result.push(item as MenuDropdownItem);
48
- }
49
- });
50
- return result;
51
- };
52
-
53
- export function CategoriesButton({ items, onItemClick }: CategoriesButtonProps) {
54
- const flatItems = flattenItems(items);
55
-
56
- const handleItemClick = (item: MenuDropdownItem) => {
57
- if (item.disabled) return;
58
- onItemClick?.({
59
- id: item.id,
60
- href: item.href,
61
- external: item.external,
62
- });
63
- };
64
-
65
- return (
66
- <div className="app-shell-categories-button">
67
- <DropdownMenu>
68
- <DropdownMenuTrigger asChild>
69
- <Button
70
- variant="ghost"
71
- size="icon"
72
- aria-label="Categories"
73
- className="h-9 w-9 hover:bg-transparent"
74
- >
75
- <span className="app-shell-categories-icon">
76
- <SquaresFourIcon />
77
- </span>
78
- </Button>
79
- </DropdownMenuTrigger>
80
- <DropdownMenuContent align="start" sideOffset={8} className="w-56">
81
- {flatItems.map((item) => {
82
- const content = (
83
- <>
84
- <span>{item.text}</span>
85
- {item.description && (
86
- <span className="text-xs text-muted-foreground ml-2">{item.description}</span>
87
- )}
88
- </>
89
- );
90
-
91
- if (item.href) {
92
- return (
93
- <DropdownMenuItem key={item.id} asChild disabled={item.disabled}>
94
- <a
95
- href={item.href}
96
- target={item.external ? "_blank" : undefined}
97
- rel={item.external ? "noopener noreferrer" : undefined}
98
- onClick={() => handleItemClick(item)}
99
- >
100
- {content}
101
- </a>
102
- </DropdownMenuItem>
103
- );
104
- }
105
-
106
- return (
107
- <DropdownMenuItem
108
- key={item.id}
109
- disabled={item.disabled}
110
- onSelect={() => handleItemClick(item)}
111
- >
112
- {content}
113
- </DropdownMenuItem>
114
- );
115
- })}
116
- </DropdownMenuContent>
117
- </DropdownMenu>
118
- </div>
119
- );
120
- }