@turtleclub/ui 0.7.0-beta.33 → 0.7.0-beta.35

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.
Files changed (135) hide show
  1. package/dist/index.cjs +10331 -110
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +7227 -48026
  4. package/dist/index.js.map +1 -1
  5. package/package.json +17 -11
  6. package/.prettierrc.json +0 -4
  7. package/.turbo/turbo-build.log +0 -182
  8. package/CHANGELOG.md +0 -801
  9. package/components.json +0 -21
  10. package/src/components/charts/QUICK_REFERENCE.md +0 -323
  11. package/src/components/charts/README.md +0 -658
  12. package/src/components/charts/RECHARTS_FEATURES.md +0 -458
  13. package/src/components/charts/area-chart.tsx +0 -248
  14. package/src/components/charts/bar-chart.tsx +0 -362
  15. package/src/components/charts/index.ts +0 -4
  16. package/src/components/charts/pie-chart.tsx +0 -277
  17. package/src/components/charts/radial-chart.tsx +0 -312
  18. package/src/components/features/api-status/index.tsx +0 -23
  19. package/src/components/features/data-table/data-table.tsx +0 -538
  20. package/src/components/features/data-table/expand-toggle.tsx +0 -17
  21. package/src/components/features/data-table/fuzzy-filter.tsx +0 -34
  22. package/src/components/features/data-table/index.ts +0 -3
  23. package/src/components/features/data-table/item-info.tsx +0 -19
  24. package/src/components/features/data-table/skeleton.tsx +0 -23
  25. package/src/components/features/data-table/sort-dropdown.tsx +0 -118
  26. package/src/components/features/data-table/sortable-header.tsx +0 -37
  27. package/src/components/features/index.ts +0 -6
  28. package/src/components/features/page-heading.tsx +0 -27
  29. package/src/components/features/search-bar.tsx +0 -55
  30. package/src/components/features/segmented-navigation.tsx +0 -18
  31. package/src/components/features/sidebar-layout.tsx +0 -279
  32. package/src/components/features/turtle-tooltip.tsx +0 -67
  33. package/src/components/icons/arrow.tsx +0 -23
  34. package/src/components/icons/beta.tsx +0 -95
  35. package/src/components/icons/dot.tsx +0 -102
  36. package/src/components/icons/index.ts +0 -7
  37. package/src/components/icons/issue.tsx +0 -106
  38. package/src/components/icons/turtle.tsx +0 -156
  39. package/src/components/icons/update.tsx +0 -113
  40. package/src/components/icons/warning.tsx +0 -95
  41. package/src/components/molecules/index.ts +0 -9
  42. package/src/components/molecules/opportunity/index.ts +0 -10
  43. package/src/components/molecules/opportunity/opportunity-apr.tsx +0 -129
  44. package/src/components/molecules/opportunity/opportunity-disclaimer.tsx +0 -46
  45. package/src/components/molecules/opportunity/opportunity-rate-estimator.tsx +0 -62
  46. package/src/components/molecules/opportunity/opportunity-section.tsx +0 -113
  47. package/src/components/molecules/opportunity/opportunity-selector.tsx +0 -30
  48. package/src/components/molecules/opportunity/opportunity-type.tsx +0 -16
  49. package/src/components/molecules/route-details.tsx +0 -112
  50. package/src/components/molecules/slippage-selector.tsx +0 -200
  51. package/src/components/molecules/swap-details.tsx +0 -55
  52. package/src/components/molecules/swap-input.tsx +0 -186
  53. package/src/components/molecules/tabs.tsx +0 -79
  54. package/src/components/molecules/token-selector.tsx +0 -180
  55. package/src/components/molecules/tx-status.tsx +0 -312
  56. package/src/components/molecules/widget/asset-list/asset-filters.tsx +0 -113
  57. package/src/components/molecules/widget/asset-list/asset-list.tsx +0 -178
  58. package/src/components/molecules/widget/asset-list/asset-row.tsx +0 -45
  59. package/src/components/molecules/widget/asset-list/hooks/index.ts +0 -2
  60. package/src/components/molecules/widget/asset-list/hooks/use-asset-filtering.ts +0 -44
  61. package/src/components/molecules/widget/asset-list/hooks/use-asset-grouping.ts +0 -87
  62. package/src/components/molecules/widget/asset-list/index.ts +0 -3
  63. package/src/components/molecules/widget/base-selector.tsx +0 -121
  64. package/src/components/molecules/widget/campaign-item.tsx +0 -82
  65. package/src/components/molecules/widget/deal-item.tsx +0 -92
  66. package/src/components/molecules/widget/index.ts +0 -36
  67. package/src/components/molecules/widget/opportunity-item.tsx +0 -105
  68. package/src/components/molecules/widget/widget-item-stats.tsx +0 -50
  69. package/src/components/molecules/widget/widget-item.tsx +0 -139
  70. package/src/components/molecules/widget/widget-list-items.tsx +0 -86
  71. package/src/components/ui/alert-dialog.tsx +0 -163
  72. package/src/components/ui/animated-background/animated-background.tsx +0 -182
  73. package/src/components/ui/animated-background/index.ts +0 -1
  74. package/src/components/ui/avatar.tsx +0 -73
  75. package/src/components/ui/badge.tsx +0 -59
  76. package/src/components/ui/banner.tsx +0 -84
  77. package/src/components/ui/button.tsx +0 -100
  78. package/src/components/ui/card.tsx +0 -119
  79. package/src/components/ui/chart.tsx +0 -346
  80. package/src/components/ui/checkbox.tsx +0 -32
  81. package/src/components/ui/chip.tsx +0 -52
  82. package/src/components/ui/collapsible.tsx +0 -34
  83. package/src/components/ui/combobox.tsx +0 -730
  84. package/src/components/ui/command.tsx +0 -184
  85. package/src/components/ui/dialog.tsx +0 -129
  86. package/src/components/ui/dropdown.tsx +0 -316
  87. package/src/components/ui/field.tsx +0 -244
  88. package/src/components/ui/heading.tsx +0 -74
  89. package/src/components/ui/hover-card.tsx +0 -139
  90. package/src/components/ui/icon-animation.tsx +0 -82
  91. package/src/components/ui/icon-list.tsx +0 -168
  92. package/src/components/ui/index.ts +0 -48
  93. package/src/components/ui/info-card.tsx +0 -110
  94. package/src/components/ui/input-group.tsx +0 -170
  95. package/src/components/ui/input.tsx +0 -72
  96. package/src/components/ui/label-with-icon.tsx +0 -122
  97. package/src/components/ui/label.tsx +0 -24
  98. package/src/components/ui/multi-select.tsx +0 -1090
  99. package/src/components/ui/navigation-bar.tsx +0 -153
  100. package/src/components/ui/navigation-menu.tsx +0 -188
  101. package/src/components/ui/opportunity-details-v1.tsx +0 -104
  102. package/src/components/ui/pagination.tsx +0 -127
  103. package/src/components/ui/popover.tsx +0 -48
  104. package/src/components/ui/scroll-area.tsx +0 -64
  105. package/src/components/ui/segment-control.tsx +0 -146
  106. package/src/components/ui/select.tsx +0 -199
  107. package/src/components/ui/separator.tsx +0 -26
  108. package/src/components/ui/sheet.tsx +0 -139
  109. package/src/components/ui/sidebar.tsx +0 -728
  110. package/src/components/ui/skeleton.tsx +0 -14
  111. package/src/components/ui/slider.tsx +0 -58
  112. package/src/components/ui/sonner.tsx +0 -24
  113. package/src/components/ui/switch.tsx +0 -29
  114. package/src/components/ui/table-shadcn.tsx +0 -110
  115. package/src/components/ui/table.tsx +0 -117
  116. package/src/components/ui/textarea.tsx +0 -22
  117. package/src/components/ui/toggle-group.tsx +0 -71
  118. package/src/components/ui/toggle.tsx +0 -47
  119. package/src/components/ui/tooltip.tsx +0 -66
  120. package/src/hooks/index.ts +0 -1
  121. package/src/hooks/useIsMobile.ts +0 -77
  122. package/src/index.ts +0 -16
  123. package/src/lib/utils.ts +0 -6
  124. package/src/styles/globals.css +0 -181
  125. package/src/styles/themes/index.css +0 -9
  126. package/src/styles/themes/semantic.css +0 -117
  127. package/src/styles/tokens/colors.css +0 -124
  128. package/src/styles/tokens/index.css +0 -15
  129. package/src/styles/tokens/radius.css +0 -18
  130. package/src/styles/tokens/spacing.css +0 -58
  131. package/src/styles/tokens/typography.css +0 -87
  132. package/src/tokens/index.ts +0 -108
  133. package/tsconfig.json +0 -20
  134. package/vite.config.js +0 -49
  135. /package/{src/images/enso.png → dist/enso-22FJ4GNK.png} +0 -0
@@ -1,118 +0,0 @@
1
- "use client";
2
-
3
- import * as React from "react";
4
- import { ArrowDown, ArrowUp, ArrowUpDown, X } from "lucide-react";
5
- import { flexRender, Header } from "@tanstack/react-table";
6
- import {
7
- DropdownMenu,
8
- DropdownMenuContent,
9
- DropdownMenuItem,
10
- DropdownMenuLabel,
11
- DropdownMenuSeparator,
12
- DropdownMenuTrigger,
13
- } from "../../ui/dropdown";
14
-
15
- interface SortDropdownProps<TData> {
16
- headers: Header<TData, unknown>[];
17
- currentSort?: { id: string; desc: boolean } | null;
18
- onSortChange: (columnId: string, desc: boolean) => void;
19
- onClearSort?: () => void;
20
- }
21
-
22
- export function SortDropdown<TData>({
23
- headers,
24
- currentSort,
25
- onSortChange,
26
- onClearSort,
27
- }: SortDropdownProps<TData>) {
28
- // Filter only sortable columns
29
- const sortableHeaders = headers.filter(
30
- (header) => header.column.getCanSort() && !header.isPlaceholder
31
- );
32
-
33
- const getCurrentSortLabel = () => {
34
- if (!currentSort) return "Sort";
35
-
36
- const header = sortableHeaders.find((h) => h.column.id === currentSort.id);
37
- if (!header) return "Sort";
38
-
39
- return (
40
- <span className="flex items-center gap-2">
41
- {currentSort.desc ? (
42
- <ArrowDown className="text-primary size-3" />
43
- ) : (
44
- <ArrowUp className="text-primary size-3" />
45
- )}
46
- <span className="truncate">
47
- {flexRender(header.column.columnDef.header, header.getContext())}
48
- </span>
49
- </span>
50
- );
51
- };
52
-
53
- const handleColumnClick = (columnId: string) => {
54
- // If this column is already sorted, toggle the direction
55
- if (currentSort?.id === columnId) {
56
- // If descending, switch to ascending; if ascending, switch to descending
57
- onSortChange(columnId, !currentSort.desc);
58
- } else {
59
- // New column, start with ascending
60
- onSortChange(columnId, false);
61
- }
62
- };
63
-
64
- if (sortableHeaders.length === 0) return null;
65
-
66
- return (
67
- <DropdownMenu>
68
- <DropdownMenuTrigger size="sm" className="bg-neutral-alpha-2">
69
- {currentSort ? (
70
- getCurrentSortLabel()
71
- ) : (
72
- <div className="text-muted-foreground flex items-center gap-2">
73
- <ArrowUpDown className="size-3" />
74
- <span>Sort by</span>
75
- </div>
76
- )}
77
- </DropdownMenuTrigger>
78
- <DropdownMenuContent align="end" className="w-[200px] space-y-1">
79
- <DropdownMenuLabel>Sort by</DropdownMenuLabel>
80
- <DropdownMenuSeparator />
81
- {sortableHeaders.map((header) => {
82
- const isCurrentAsc = currentSort?.id === header.column.id && !currentSort.desc;
83
- const isCurrentDesc = currentSort?.id === header.column.id && currentSort.desc;
84
- const isActive = currentSort?.id === header.column.id;
85
-
86
- return (
87
- <DropdownMenuItem
88
- key={header.column.id}
89
- onClick={() => handleColumnClick(header.column.id)}
90
- className={
91
- isActive ? "bg-secondary flex items-center gap-2" : "flex items-center gap-2"
92
- }
93
- >
94
- <span className="w-fit truncate">
95
- {flexRender(header.column.columnDef.header, header.getContext())}
96
- </span>
97
- {isActive &&
98
- (isCurrentDesc ? (
99
- <ArrowDown className="text-primary size-4" />
100
- ) : (
101
- <ArrowUp className="text-primary size-4" />
102
- ))}
103
- </DropdownMenuItem>
104
- );
105
- })}
106
- {currentSort && onClearSort && (
107
- <>
108
- <DropdownMenuSeparator />
109
- <DropdownMenuItem onClick={onClearSort}>
110
- <X className="size-4" />
111
- Clear sorting
112
- </DropdownMenuItem>
113
- </>
114
- )}
115
- </DropdownMenuContent>
116
- </DropdownMenu>
117
- );
118
- }
@@ -1,37 +0,0 @@
1
- "use client";
2
-
3
- import { flexRender, type Header } from "@tanstack/react-table";
4
- import { ArrowDown, ArrowUp, ArrowUpDown } from "lucide-react";
5
- import { useMemo } from "react";
6
-
7
- export default function SortableHeader({
8
- header,
9
- }: {
10
- header: Header<any, unknown>;
11
- }) {
12
- const getSortIcon = useMemo(() => {
13
- if (header.column.getIsSorted() === "asc")
14
- return <ArrowUp className="text-primary size-3.5" />;
15
- if (header.column.getIsSorted() === "desc")
16
- return <ArrowDown className="text-primary size-3.5" />;
17
- return (
18
- header.column.getCanSort() && (
19
- <ArrowUpDown className="text-secondary group-hover:text-muted-foreground size-3" />
20
- )
21
- );
22
- }, [header.column.getIsSorted(), header.column.getCanSort()]);
23
-
24
- return header.isPlaceholder ? null : (
25
- <div
26
- className={
27
- header.column.getCanSort()
28
- ? "group flex cursor-pointer items-center gap-1 select-none"
29
- : ""
30
- }
31
- onClick={header.column.getToggleSortingHandler()}
32
- >
33
- {flexRender(header.column.columnDef.header, header.getContext())}
34
- {getSortIcon}
35
- </div>
36
- );
37
- }
@@ -1,6 +0,0 @@
1
- export * from "./data-table";
2
- export * from "./search-bar";
3
- export * from "./sidebar-layout";
4
- export * from "./page-heading";
5
- export * from "./turtle-tooltip";
6
- export * from "./api-status";
@@ -1,27 +0,0 @@
1
- import React from "react";
2
- import { HeadingH3, HeadingH6 } from "../ui";
3
-
4
- type PageHeadingProps = {
5
- icon?: React.ReactNode;
6
- title: string;
7
- description: string;
8
- action?: React.ReactNode;
9
- };
10
-
11
- export function PageHeading({
12
- icon,
13
- title,
14
- description,
15
- action,
16
- }: PageHeadingProps) {
17
- return (
18
- <div className="flex items-center gap-3">
19
- <div>{icon}</div>
20
- <div className="grow">
21
- <HeadingH3>{title}</HeadingH3>
22
- <HeadingH6>{description}</HeadingH6>
23
- </div>
24
- {action}
25
- </div>
26
- );
27
- }
@@ -1,55 +0,0 @@
1
- import * as React from "react";
2
- import { Input, InputProps } from "../ui";
3
- import { Search } from "lucide-react";
4
- import { cn } from "@/lib/utils";
5
-
6
- type Props = {
7
- value: string;
8
- onChange: (value: string) => void;
9
- debounce?: number;
10
- size?: "default" | "sm";
11
- } & Omit<InputProps, "onChange">;
12
-
13
- export const SearchBar: React.FC<Props> = ({
14
- value: initialValue,
15
- onChange,
16
- debounce = 300,
17
- size = "default",
18
- ...props
19
- }) => {
20
- const [value, setValue] = React.useState<string>(initialValue);
21
-
22
- const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) =>
23
- setValue(event.target.value);
24
-
25
- React.useEffect(() => {
26
- setValue(initialValue);
27
- }, [initialValue]);
28
-
29
- React.useEffect(() => {
30
- const timeout = setTimeout(() => {
31
- onChange(value);
32
- }, debounce);
33
-
34
- return () => clearTimeout(timeout);
35
- }, [value]);
36
-
37
- const inputClasses = size === "sm" ? "text-sm" : "";
38
-
39
- return (
40
- <div className="border-border relative w-full max-w-md rounded-full border">
41
- <Input
42
- value={value}
43
- onChange={handleInputChange}
44
- className={cn("-my-px h-9", inputClasses)}
45
- {...props}
46
- />
47
- <button
48
- type="button"
49
- className="bg-border border-border absolute inset-y-0 right-0 flex aspect-square h-full items-center justify-center rounded rounded-full"
50
- >
51
- <Search className="text-primary size-3" />
52
- </button>
53
- </div>
54
- );
55
- };
@@ -1,18 +0,0 @@
1
- import * as React from "react";
2
- import { SegmentControl, SegmentControlProps } from "../ui";
3
-
4
- type SegmentedNavigationProps<T extends string> = SegmentControlProps<T> & {
5
- shouldMobileSelect: boolean;
6
- };
7
-
8
- export function SegmentedNavigation<T extends string>({
9
- value,
10
- onChange,
11
- items,
12
- }: SegmentedNavigationProps<T>) {
13
- return (
14
- <div className="">
15
- <SegmentControl value={value} onChange={onChange} items={items} />
16
- </div>
17
- );
18
- }
@@ -1,279 +0,0 @@
1
- import React from "react";
2
- import { ChevronRight, Lock } from "lucide-react";
3
- import {
4
- Sidebar,
5
- SidebarProvider,
6
- SidebarHeader,
7
- SidebarContent,
8
- SidebarGroup,
9
- SidebarGroupContent,
10
- SidebarMenu,
11
- SidebarMenuItem,
12
- SidebarMenuButton,
13
- SidebarMenuSub,
14
- SidebarMenuSubItem,
15
- SidebarMenuSubButton,
16
- Collapsible,
17
- CollapsibleTrigger,
18
- CollapsibleContent,
19
- SidebarFooter,
20
- useSidebar,
21
- SidebarTrigger,
22
- } from "../ui";
23
- import { cn } from "@/lib/utils";
24
- import { DotIcon, TurtleIcon } from "../icons";
25
- import { TurtleTooltip } from "./turtle-tooltip";
26
-
27
- type SidebarItemBase = {
28
- title: string;
29
- icon?: any;
30
- };
31
-
32
- // Item with a URL (no children)
33
- type SidebarLink = SidebarItemBase & {
34
- url: string;
35
- isActive: boolean;
36
- isEnabled?: boolean;
37
- children?: never;
38
- };
39
-
40
- // Item with children (no URL)
41
- type SidebarGroupBase = SidebarItemBase & {
42
- children: SidebarItem[];
43
- url?: never;
44
- isActive?: never;
45
- isEnabled?: boolean;
46
- };
47
-
48
- export type SidebarItem = SidebarLink | SidebarGroupBase;
49
-
50
- const LOCKED_TOOLTIP_CONTENT = "Contact the Turtle team to unlock.";
51
-
52
- export function TurtleSidebarLayout({
53
- children,
54
- sidebarSlot,
55
- sidebarFooter,
56
- topSlot,
57
- items,
58
- linkComponent,
59
- }: {
60
- children: React.ReactNode;
61
- sidebarSlot?: React.ReactNode;
62
- sidebarFooter?: React.ReactNode;
63
- topSlot?: React.ReactNode;
64
- items: SidebarItem[];
65
- linkComponent: any;
66
- }) {
67
- return (
68
- <SidebarProvider>
69
- <TurtleSidebar
70
- items={items}
71
- sidebarFooter={sidebarFooter}
72
- sidebarSlot={sidebarSlot}
73
- linkComponent={linkComponent}
74
- />
75
- <TurtleContainer topSlot={topSlot} children={children} />
76
- </SidebarProvider>
77
- );
78
- }
79
-
80
- export function TurtleSidebar({
81
- items,
82
- sidebarSlot,
83
- sidebarFooter,
84
- linkComponent: Comp = "a",
85
- }: {
86
- items: SidebarItem[];
87
- sidebarSlot?: React.ReactNode;
88
- sidebarFooter?: React.ReactNode;
89
- linkComponent: any;
90
- }) {
91
- return (
92
- <Sidebar>
93
- <SidebarHeader>
94
- <div className="border-gradient-white border-opacity-20 relative h-[72px] w-full rounded-full shadow">
95
- <TurtleIcon className="absolute -top-2 -left-2 aspect-square h-[86px]" />
96
-
97
- <div className="text-primary mt-2 -space-y-1.5 pl-20">
98
- <div className="text-3xl leading-tight font-bold">Turtle</div>
99
- <div className="pl-1 text-sm font-medium">Partner Portal</div>
100
- </div>
101
- </div>
102
- </SidebarHeader>
103
- <SidebarContent>
104
- <SidebarGroup>
105
- <SidebarGroupContent>
106
- <SidebarMenu>
107
- {items.map((item) => {
108
- if (item?.children?.length) {
109
- const isEnabled = item.isEnabled !== false;
110
-
111
- return (
112
- <Collapsible
113
- key={item.title}
114
- className="group/collapsible"
115
- open={isEnabled ? undefined : false}
116
- >
117
- <SidebarMenuItem>
118
- {isEnabled ? (
119
- <CollapsibleTrigger asChild>
120
- <SidebarMenuButton>
121
- {item.icon && <item.icon />}
122
- <span className="grow">{item.title}</span>
123
- <ChevronRight className="transition-all group-data-[state=open]/collapsible:rotate-90" />
124
- </SidebarMenuButton>
125
- </CollapsibleTrigger>
126
- ) : (
127
- <TurtleTooltip
128
- asChild
129
- className="w-full"
130
- content={LOCKED_TOOLTIP_CONTENT}
131
- trigger={
132
- <div className="w-full">
133
- <SidebarMenuButton
134
- disabled
135
- className="opacity-70"
136
- >
137
- {item.icon && <item.icon />}
138
- <span className="grow">{item.title}</span>
139
- <Lock className="text-muted-foreground size-4 shrink-0" />
140
- </SidebarMenuButton>
141
- </div>
142
- }
143
- />
144
- )}
145
-
146
- {isEnabled && (
147
- <CollapsibleContent>
148
- <SidebarMenuSub>
149
- {item.children.map((child) => {
150
- const isChildEnabled =
151
- child.isEnabled !== false;
152
-
153
- return (
154
- <SidebarMenuSubItem key={child.title}>
155
- {isChildEnabled ? (
156
- <SidebarMenuSubButton
157
- asChild
158
- isActive={child.isActive}
159
- >
160
- <Comp href={child.url}>
161
- {child.icon && <child.icon />}
162
- <span className="grow">
163
- {child.title}
164
- </span>
165
-
166
- <div className="relative size-[18px] shrink-0 group-data-[active=false]/menu-sub-button:hidden">
167
- <DotIcon className="text-primary absolute top-[-15px] left-[-15px] size-12" />
168
- </div>
169
- </Comp>
170
- </SidebarMenuSubButton>
171
- ) : (
172
- <TurtleTooltip
173
- asChild
174
- className="w-full"
175
- content={LOCKED_TOOLTIP_CONTENT}
176
- trigger={
177
- <div className="w-full">
178
- <SidebarMenuSubButton
179
- className="opacity-70"
180
- aria-disabled="true"
181
- >
182
- {child.icon && <child.icon />}
183
- <span className="grow">
184
- {child.title}
185
- </span>
186
- <Lock className="text-muted-foreground size-4 shrink-0" />
187
- </SidebarMenuSubButton>
188
- </div>
189
- }
190
- />
191
- )}
192
- </SidebarMenuSubItem>
193
- );
194
- })}
195
- </SidebarMenuSub>
196
- </CollapsibleContent>
197
- )}
198
- </SidebarMenuItem>
199
- </Collapsible>
200
- );
201
- }
202
-
203
- const isEnabled = item.isEnabled !== false;
204
-
205
- return (
206
- <SidebarMenuItem key={item.title}>
207
- {isEnabled ? (
208
- <SidebarMenuButton asChild isActive={item.isActive}>
209
- <Comp href={item.url}>
210
- {item.icon && <item.icon />}
211
- <span className="grow">{item.title}</span>
212
- <div className="relative size-[18px] shrink-0 group-data-[active=false]/menu-button:hidden">
213
- <DotIcon className="text-primary absolute top-[-15px] left-[-15px] size-12" />
214
- </div>
215
- </Comp>
216
- </SidebarMenuButton>
217
- ) : (
218
- <TurtleTooltip
219
- asChild
220
- className="w-full"
221
- content={LOCKED_TOOLTIP_CONTENT}
222
- trigger={
223
- <div className="w-full">
224
- <SidebarMenuButton
225
- aria-disabled="true"
226
- className="opacity-70"
227
- >
228
- {item.icon && <item.icon />}
229
- <span className="grow">{item.title}</span>
230
- <Lock className="text-muted-foreground size-4 shrink-0" />
231
- </SidebarMenuButton>
232
- </div>
233
- }
234
- />
235
- )}
236
- </SidebarMenuItem>
237
- );
238
- })}
239
- </SidebarMenu>
240
- </SidebarGroupContent>
241
- </SidebarGroup>
242
- <span className="grow" />
243
- <SidebarGroup>{sidebarSlot}</SidebarGroup>
244
- </SidebarContent>
245
- <SidebarFooter>{sidebarFooter}</SidebarFooter>
246
- </Sidebar>
247
- );
248
- }
249
-
250
- export function TurtleContainer({
251
- children,
252
- topSlot,
253
- }: {
254
- children: React.ReactNode;
255
- topSlot?: React.ReactNode;
256
- }) {
257
- const { state, isMobile } = useSidebar();
258
- return (
259
- <div
260
- className={cn(
261
- "fixed inset-0 flex h-svh flex-col items-stretch gap-1 py-2 pr-2",
262
- state === "collapsed" || isMobile ? "pl-2" : "left-64",
263
- )}
264
- >
265
- <div className="flex gap-1">
266
- <SidebarTrigger />
267
- {topSlot}
268
- </div>
269
-
270
- <main
271
- className={cn(
272
- "bg-background border-border max-h-[94svh] grow overflow-y-auto rounded-lg border p-6",
273
- )}
274
- >
275
- {children}
276
- </main>
277
- </div>
278
- );
279
- }
@@ -1,67 +0,0 @@
1
- import type { MouseEvent, ReactNode } from "react";
2
- import { useIsMobile } from "@/hooks/useIsMobile";
3
- import {
4
- Tooltip,
5
- TooltipContent,
6
- TooltipTrigger,
7
- } from "@/components/ui/tooltip";
8
- import {
9
- Popover,
10
- PopoverContent,
11
- PopoverTrigger,
12
- } from "@/components/ui/popover";
13
- import { TooltipPortal } from "@radix-ui/react-tooltip";
14
-
15
- interface TooltipProps {
16
- trigger: ReactNode;
17
- content: ReactNode;
18
- className?: string;
19
- contentClassName?: string;
20
- maxWidth?: string;
21
- href?: string;
22
- side?: "top" | "bottom" | "left" | "right";
23
- asChild?: boolean;
24
- }
25
-
26
- export function TurtleTooltip({
27
- trigger,
28
- content,
29
- className,
30
- side,
31
- asChild,
32
- }: TooltipProps) {
33
- const { isMobile } = useIsMobile();
34
-
35
- const handleClick = (e: MouseEvent<HTMLDivElement>) => {
36
- e.stopPropagation();
37
- e.preventDefault();
38
- };
39
-
40
- return (
41
- <div className={className} onClick={handleClick}>
42
- {isMobile ? (
43
- <Popover>
44
- <PopoverTrigger
45
- className="flex items-center justify-center"
46
- asChild={asChild}
47
- >
48
- {trigger}
49
- </PopoverTrigger>
50
- <PopoverContent side={side}>{content}</PopoverContent>
51
- </Popover>
52
- ) : (
53
- <Tooltip>
54
- <TooltipTrigger
55
- className="flex items-center justify-center"
56
- asChild={asChild}
57
- >
58
- {trigger}
59
- </TooltipTrigger>
60
- <TooltipPortal>
61
- <TooltipContent side={side}>{content}</TooltipContent>
62
- </TooltipPortal>
63
- </Tooltip>
64
- )}
65
- </div>
66
- );
67
- }
@@ -1,23 +0,0 @@
1
- export const ArrowIcon = ({ className }: { className?: string }) => (
2
- <svg
3
- xmlns="http://www.w3.org/2000/svg"
4
- width="13"
5
- height="14"
6
- viewBox="0 0 13 14"
7
- fill="none"
8
- className={className}
9
- >
10
- <path
11
- d="M3.65174 10.4506L3.05176 9.85059L9.05161 3.85073L9.6516 4.45072L3.65174 10.4506Z"
12
- fill="currentColor"
13
- />
14
- <path
15
- d="M9.68168 4.66626L3.31787 4.66626V3.81775L9.68168 3.81775V4.66626Z"
16
- fill="currentColor"
17
- />
18
- <path
19
- d="M9.68249 10.1821H8.83398L8.83398 3.81832H9.68249L9.68249 10.1821Z"
20
- fill="currentColor"
21
- />
22
- </svg>
23
- );