@lessly/ui 0.8.0 → 0.10.0
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/dist/index.d.ts +71 -1
- package/dist/index.js +237 -64
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -885,6 +885,43 @@ type SidebarProductHeaderProps = SidebarProductHeaderOwnProps & Omit<React$1.Com
|
|
|
885
885
|
* which anchors a `MenuPopup` at left:12 with the default sideOffset, no alignOffset. */
|
|
886
886
|
declare const SidebarProductHeader: React$1.ForwardRefExoticComponent<SidebarProductHeaderProps & React$1.RefAttributes<HTMLButtonElement>>;
|
|
887
887
|
|
|
888
|
+
/** A slot's native attributes plus an explicit `data-*` index, so an object literal like
|
|
889
|
+
* `{ 'data-testid': 'drill-back' }` passes excess-property checking — plain
|
|
890
|
+
* `React.HTMLAttributes` does not declare `data-*` as a named property. */
|
|
891
|
+
type SidebarBackHeaderSlotProps = React$1.HTMLAttributes<HTMLElement> & {
|
|
892
|
+
[attr: `data-${string}`]: string | number | boolean | undefined;
|
|
893
|
+
};
|
|
894
|
+
interface SidebarBackHeaderProps extends Omit<React$1.HTMLAttributes<HTMLElement>, 'title'> {
|
|
895
|
+
/** Title text/node beside the arrow. In single mode it is also the row's accessible name. */
|
|
896
|
+
title: React$1.ReactNode;
|
|
897
|
+
/** Back action — the arrow in split mode, the whole row in single mode. */
|
|
898
|
+
onBack: () => void;
|
|
899
|
+
/** Title action. Its presence switches the row into split mode (arrow + title are two
|
|
900
|
+
* separate controls). Omit it for single mode (the whole row is one back button). */
|
|
901
|
+
onTitleClick?: () => void;
|
|
902
|
+
/** Accessible name for the back control in split mode. Defaults to `"Back"`. Unused in
|
|
903
|
+
* single mode, where the row's accessible name is the title text. */
|
|
904
|
+
backLabel?: string;
|
|
905
|
+
/** Attributes for the arrow control — the arrow `<button>` in split mode, the arrow-plate
|
|
906
|
+
* `<span>` in single mode. Lets a consumer attach e.g. `data-testid`. */
|
|
907
|
+
arrowProps?: SidebarBackHeaderSlotProps;
|
|
908
|
+
/** Attributes for the title control — the title `<button>` in split mode, the title
|
|
909
|
+
* `<span>` in single mode. */
|
|
910
|
+
titleProps?: SidebarBackHeaderSlotProps;
|
|
911
|
+
}
|
|
912
|
+
/** Accessible sidebar back-header (`← Title`) reproducing `lessly-workspace` DrillPanel's
|
|
913
|
+
* back-row one-to-one, with a flexible action model:
|
|
914
|
+
*
|
|
915
|
+
* - **Split mode** (`onTitleClick` given): two native buttons — arrow (`onBack`) and title
|
|
916
|
+
* (`onTitleClick`).
|
|
917
|
+
* - **Single mode** (`onTitleClick` omitted): the whole row is one native button (`onBack`).
|
|
918
|
+
*
|
|
919
|
+
* The row adds NO horizontal padding of its own — the parent pane owns horizontal inset. */
|
|
920
|
+
declare function SidebarBackHeader({ title, onBack, onTitleClick, backLabel, arrowProps, titleProps, className, ...rowProps }: SidebarBackHeaderProps): React$1.JSX.Element;
|
|
921
|
+
declare namespace SidebarBackHeader {
|
|
922
|
+
var displayName: string;
|
|
923
|
+
}
|
|
924
|
+
|
|
888
925
|
interface AppShellProps {
|
|
889
926
|
/** The sidebar, typically an <AppSidebar/>. Rendered in the desktop rail and,
|
|
890
927
|
* on mobile, inside a Sheet (force-expanded via cloneElement collapsed=false). */
|
|
@@ -1057,4 +1094,37 @@ interface RequestRowProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, '
|
|
|
1057
1094
|
}
|
|
1058
1095
|
declare const RequestRow: React$1.ForwardRefExoticComponent<RequestRowProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
1059
1096
|
|
|
1060
|
-
|
|
1097
|
+
interface FeedbackWidgetLabels {
|
|
1098
|
+
/** Floating trigger button + its aria-label. */
|
|
1099
|
+
trigger: string;
|
|
1100
|
+
/** Heading shown above the form. */
|
|
1101
|
+
title: string;
|
|
1102
|
+
/** Label for the Title input. */
|
|
1103
|
+
titleField: string;
|
|
1104
|
+
/** Label for the Details textarea. */
|
|
1105
|
+
detailsField: string;
|
|
1106
|
+
/** Submit button. */
|
|
1107
|
+
submit: string;
|
|
1108
|
+
/** Message shown after a successful submit. */
|
|
1109
|
+
success: string;
|
|
1110
|
+
/** Message shown after a failed submit. */
|
|
1111
|
+
error: string;
|
|
1112
|
+
}
|
|
1113
|
+
interface FeedbackWidgetProps {
|
|
1114
|
+
/**
|
|
1115
|
+
* Called with the entered feedback when the form is submitted. The widget is
|
|
1116
|
+
* presentational: it knows nothing about APIs, auth, or routing — the parent
|
|
1117
|
+
* decides what to do with the data. Rejecting shows the error state.
|
|
1118
|
+
*/
|
|
1119
|
+
onSubmit: (data: {
|
|
1120
|
+
title: string;
|
|
1121
|
+
details: string;
|
|
1122
|
+
}) => Promise<void>;
|
|
1123
|
+
/** Override any of the default copy. */
|
|
1124
|
+
labels?: Partial<FeedbackWidgetLabels>;
|
|
1125
|
+
/** Merged onto the fixed positioning wrapper (e.g. to reposition the button). */
|
|
1126
|
+
className?: string;
|
|
1127
|
+
}
|
|
1128
|
+
declare function FeedbackWidget({ onSubmit, labels, className }: FeedbackWidgetProps): React$1.JSX.Element;
|
|
1129
|
+
|
|
1130
|
+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppShell, type AppShellProps, AppSidebar, type AppSidebarProps, AspectRatio, AuthenticatedLayout, Avatar, AvatarFallback, AvatarImage, Badge, type BadgeProps, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, type ButtonProps, Calendar, type CalendarProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, type CarouselApi, CarouselContent, type CarouselContextProps, CarouselItem, CarouselNext, type CarouselOptions, type CarouselPlugin, CarouselPrevious, type CarouselProps, Checkbox, Col, type ColProps, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ConfirmDialog, type ConfirmDialogProps, type ConnectionAuth, ConnectionCard, type ConnectionCardProps, type ConnectionScope, type ConnectionStatus, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, CopyButton, type CopyButtonProps, DatePicker, type DatePickerProps, type DeltaDirection, type DeltaTone, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DocsLink, type DocsLinkProps, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, type EmptyStateProps, ExtensionIcon, type ExtensionIconProps, ExtensionLink, type ExtensionLinkProps, type ExtensionLinkUiMode, FeedbackWidget, type FeedbackWidgetLabels, type FeedbackWidgetProps, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Grid, GridOverlay, type GridOverlayProps, type GridProps, HoverCard, HoverCardContent, HoverCardTrigger, InlineError, type InlineErrorProps, Input, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, type InputProps, Label, MenuDivider, MenuPopup, type MenuPopupProps, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, type NavItem, type NavLinkComponent, NavRow, type NavRowProps, type NavRowVariant, NavSectionLabel, type NavSectionLabelProps, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, type PaginationLinkProps, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, RadioGroup, RadioGroupItem, RequestRow, type RequestRowProps, type RequestState, type RequestSurface, type ResolvedTheme, type Responsive, ScrollArea, ScrollBar, SectionIntro, type SectionIntroProps, SegmentChip, type SegmentChipProps, Select, type SelectOption, type SelectProps, Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, SidebarBackHeader, type SidebarBackHeaderProps, SidebarNav, SidebarNavLink, type SidebarNavLinkProps, type SidebarNavProps, SidebarProductHeader, type SidebarProductHeaderProps, Skeleton, Slider, StatCard, type StatCardProps, StatusDot, type StatusDotProps, Switch, type SwitchProps, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, type TextareaProps, type Theme, ThemeToggle, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, type UseSidebarOptions, type UseSidebarResult, UserMenu, type UserMenuItem, type UserMenuProps, type UserMenuUser, alertVariants, badgeVariants, buttonVariants, cn, isKnownExtensionIcon, navigationMenuTriggerStyle, segmentChipVariants, statusDotVariants, toggleVariants, useCarousel, useFormField, useIsMobile, useSidebar, useTheme };
|
package/dist/index.js
CHANGED
|
@@ -3108,11 +3108,72 @@ var SidebarProductHeader = React50.forwardRef(
|
|
|
3108
3108
|
);
|
|
3109
3109
|
SidebarProductHeader.displayName = "SidebarProductHeader";
|
|
3110
3110
|
|
|
3111
|
+
// src/components/sidebar-back-header.tsx
|
|
3112
|
+
import { ArrowLeft as ArrowLeft2 } from "lucide-react";
|
|
3113
|
+
import { jsx as jsx61, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
3114
|
+
var focusRing = "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus";
|
|
3115
|
+
var arrowPlate = "flex size-5 items-center justify-center rounded-md transition-colors hover:bg-[color-mix(in_srgb,var(--text-primary)_12%,transparent)] hover:text-text-primary";
|
|
3116
|
+
var arrowBox = "flex shrink-0 cursor-pointer items-center rounded-xl py-2 pr-0 pl-2.5 text-text-secondary";
|
|
3117
|
+
var titleBox = "min-w-0 flex-1 cursor-pointer truncate rounded-xl py-2 pr-2.5 pl-[14px] text-left text-sm font-semibold text-text-primary";
|
|
3118
|
+
var Arrow = () => /* @__PURE__ */ jsx61(ArrowLeft2, { size: 16, "aria-hidden": "true" });
|
|
3119
|
+
function SidebarBackHeader({
|
|
3120
|
+
title,
|
|
3121
|
+
onBack,
|
|
3122
|
+
onTitleClick,
|
|
3123
|
+
backLabel = "Back",
|
|
3124
|
+
arrowProps,
|
|
3125
|
+
titleProps,
|
|
3126
|
+
className,
|
|
3127
|
+
...rowProps
|
|
3128
|
+
}) {
|
|
3129
|
+
const { className: arrowClassName, ...arrowRest } = arrowProps ?? {};
|
|
3130
|
+
const { className: titleClassName, ...titleRest } = titleProps ?? {};
|
|
3131
|
+
if (!onTitleClick) {
|
|
3132
|
+
return /* @__PURE__ */ jsxs31(
|
|
3133
|
+
"button",
|
|
3134
|
+
{
|
|
3135
|
+
type: "button",
|
|
3136
|
+
onClick: onBack,
|
|
3137
|
+
className: cn("flex items-center rounded-xl", focusRing, className),
|
|
3138
|
+
...rowProps,
|
|
3139
|
+
children: [
|
|
3140
|
+
/* @__PURE__ */ jsx61("span", { className: arrowBox, children: /* @__PURE__ */ jsx61("span", { className: cn(arrowPlate, arrowClassName), ...arrowRest, children: /* @__PURE__ */ jsx61(Arrow, {}) }) }),
|
|
3141
|
+
/* @__PURE__ */ jsx61("span", { className: cn(titleBox, titleClassName), ...titleRest, children: title })
|
|
3142
|
+
]
|
|
3143
|
+
}
|
|
3144
|
+
);
|
|
3145
|
+
}
|
|
3146
|
+
return /* @__PURE__ */ jsxs31("div", { className: cn("flex items-center", className), ...rowProps, children: [
|
|
3147
|
+
/* @__PURE__ */ jsx61(
|
|
3148
|
+
"button",
|
|
3149
|
+
{
|
|
3150
|
+
type: "button",
|
|
3151
|
+
"aria-label": backLabel,
|
|
3152
|
+
onClick: onBack,
|
|
3153
|
+
className: cn(arrowBox, focusRing, arrowClassName),
|
|
3154
|
+
...arrowRest,
|
|
3155
|
+
children: /* @__PURE__ */ jsx61("span", { className: arrowPlate, children: /* @__PURE__ */ jsx61(Arrow, {}) })
|
|
3156
|
+
}
|
|
3157
|
+
),
|
|
3158
|
+
/* @__PURE__ */ jsx61(
|
|
3159
|
+
"button",
|
|
3160
|
+
{
|
|
3161
|
+
type: "button",
|
|
3162
|
+
onClick: onTitleClick,
|
|
3163
|
+
className: cn(titleBox, focusRing, titleClassName),
|
|
3164
|
+
...titleRest,
|
|
3165
|
+
children: title
|
|
3166
|
+
}
|
|
3167
|
+
)
|
|
3168
|
+
] });
|
|
3169
|
+
}
|
|
3170
|
+
SidebarBackHeader.displayName = "SidebarBackHeader";
|
|
3171
|
+
|
|
3111
3172
|
// src/components/app-shell.tsx
|
|
3112
3173
|
import * as React51 from "react";
|
|
3113
3174
|
import { Menu as Menu2 } from "lucide-react";
|
|
3114
3175
|
import { useLocation as useLocation2 } from "react-router";
|
|
3115
|
-
import { jsx as
|
|
3176
|
+
import { jsx as jsx62, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
3116
3177
|
function expandedSidebar(sidebar) {
|
|
3117
3178
|
return React51.isValidElement(sidebar) ? React51.cloneElement(sidebar, { collapsed: false }) : sidebar;
|
|
3118
3179
|
}
|
|
@@ -3124,26 +3185,26 @@ function AppShell({ sidebar, topBar, children, className }) {
|
|
|
3124
3185
|
}, [pathname]);
|
|
3125
3186
|
const isMobile = useIsMobile();
|
|
3126
3187
|
if (isMobile) {
|
|
3127
|
-
return /* @__PURE__ */
|
|
3128
|
-
/* @__PURE__ */
|
|
3129
|
-
/* @__PURE__ */
|
|
3130
|
-
/* @__PURE__ */
|
|
3131
|
-
/* @__PURE__ */
|
|
3132
|
-
/* @__PURE__ */
|
|
3133
|
-
/* @__PURE__ */
|
|
3188
|
+
return /* @__PURE__ */ jsx62(TooltipProvider, { children: /* @__PURE__ */ jsxs32("div", { className: cn("flex min-h-screen flex-col bg-bg-surface", className), children: [
|
|
3189
|
+
/* @__PURE__ */ jsxs32("header", { className: "flex shrink-0 items-center justify-between border-b border-border-subtle bg-bg-surface px-4 py-3", children: [
|
|
3190
|
+
/* @__PURE__ */ jsxs32(Sheet, { open: mobileOpen, onOpenChange: setMobileOpen, children: [
|
|
3191
|
+
/* @__PURE__ */ jsx62(SheetTrigger, { asChild: true, children: /* @__PURE__ */ jsx62(Button, { variant: "ghost", size: "icon", className: "size-8 text-text-secondary", "aria-label": "Open navigation", children: /* @__PURE__ */ jsx62(Menu2, { className: "size-5" }) }) }),
|
|
3192
|
+
/* @__PURE__ */ jsxs32(SheetContent, { side: "left", className: "w-[248px] bg-bg-surface p-0", children: [
|
|
3193
|
+
/* @__PURE__ */ jsx62(SheetTitle, { className: "sr-only", children: "Navigation" }),
|
|
3194
|
+
/* @__PURE__ */ jsx62(SheetDescription, { className: "sr-only", children: "Application navigation menu" }),
|
|
3134
3195
|
expandedSidebar(sidebar)
|
|
3135
3196
|
] })
|
|
3136
3197
|
] }),
|
|
3137
|
-
/* @__PURE__ */
|
|
3198
|
+
/* @__PURE__ */ jsx62("div", { className: "flex items-center gap-2", children: topBar })
|
|
3138
3199
|
] }),
|
|
3139
|
-
/* @__PURE__ */
|
|
3200
|
+
/* @__PURE__ */ jsx62("main", { className: "flex-1 overflow-auto", children })
|
|
3140
3201
|
] }) });
|
|
3141
3202
|
}
|
|
3142
|
-
return /* @__PURE__ */
|
|
3143
|
-
/* @__PURE__ */
|
|
3144
|
-
/* @__PURE__ */
|
|
3145
|
-
topBar && /* @__PURE__ */
|
|
3146
|
-
/* @__PURE__ */
|
|
3203
|
+
return /* @__PURE__ */ jsx62(TooltipProvider, { children: /* @__PURE__ */ jsxs32("div", { className: cn("flex min-h-screen gap-3 bg-bg-surface p-4", className), children: [
|
|
3204
|
+
/* @__PURE__ */ jsx62("div", { className: "sticky top-4 h-[calc(100vh-32px)] shrink-0", children: sidebar }),
|
|
3205
|
+
/* @__PURE__ */ jsxs32("div", { className: "flex min-w-0 flex-1 flex-col overflow-hidden", children: [
|
|
3206
|
+
topBar && /* @__PURE__ */ jsx62("div", { className: "flex shrink-0 items-center justify-end gap-2", children: topBar }),
|
|
3207
|
+
/* @__PURE__ */ jsx62("main", { className: "flex-1 overflow-y-auto", children })
|
|
3147
3208
|
] })
|
|
3148
3209
|
] }) });
|
|
3149
3210
|
}
|
|
@@ -3152,11 +3213,11 @@ var AuthenticatedLayout = AppShell;
|
|
|
3152
3213
|
// src/components/grid.tsx
|
|
3153
3214
|
import * as React52 from "react";
|
|
3154
3215
|
import { Slot as Slot6 } from "@radix-ui/react-slot";
|
|
3155
|
-
import { jsx as
|
|
3216
|
+
import { jsx as jsx63 } from "react/jsx-runtime";
|
|
3156
3217
|
var Grid = React52.forwardRef(
|
|
3157
3218
|
({ fluid = false, asChild = false, className, ...props }, ref) => {
|
|
3158
3219
|
const Comp = asChild ? Slot6 : "div";
|
|
3159
|
-
return /* @__PURE__ */
|
|
3220
|
+
return /* @__PURE__ */ jsx63(
|
|
3160
3221
|
Comp,
|
|
3161
3222
|
{
|
|
3162
3223
|
ref,
|
|
@@ -3176,7 +3237,7 @@ Grid.displayName = "Grid";
|
|
|
3176
3237
|
// src/components/col.tsx
|
|
3177
3238
|
import * as React53 from "react";
|
|
3178
3239
|
import { Slot as Slot7 } from "@radix-ui/react-slot";
|
|
3179
|
-
import { jsx as
|
|
3240
|
+
import { jsx as jsx64 } from "react/jsx-runtime";
|
|
3180
3241
|
var TIER_MAX = { base: 4, md: 8, xl: 12 };
|
|
3181
3242
|
var SPAN = {
|
|
3182
3243
|
base: { 1: "col-span-1", 2: "col-span-2", 3: "col-span-3", 4: "col-span-4" },
|
|
@@ -3299,19 +3360,19 @@ function responsiveClasses(span, offset) {
|
|
|
3299
3360
|
var Col = React53.forwardRef(
|
|
3300
3361
|
({ span, offset, asChild = false, className, ...props }, ref) => {
|
|
3301
3362
|
const Comp = asChild ? Slot7 : "div";
|
|
3302
|
-
return /* @__PURE__ */
|
|
3363
|
+
return /* @__PURE__ */ jsx64(Comp, { ref, className: cn(responsiveClasses(span, offset), className), ...props });
|
|
3303
3364
|
}
|
|
3304
3365
|
);
|
|
3305
3366
|
Col.displayName = "Col";
|
|
3306
3367
|
|
|
3307
3368
|
// src/components/grid-overlay.tsx
|
|
3308
3369
|
import * as React54 from "react";
|
|
3309
|
-
import { jsx as
|
|
3370
|
+
import { jsx as jsx65 } from "react/jsx-runtime";
|
|
3310
3371
|
var BASELINE = "var(--grid-gutter) / 2";
|
|
3311
3372
|
var GridOverlay = React54.forwardRef(
|
|
3312
3373
|
({ columns, baseline = false, className, style, ...props }, ref) => {
|
|
3313
3374
|
const count = Number.isFinite(columns) ? Math.max(1, Math.floor(columns)) : 1;
|
|
3314
|
-
return /* @__PURE__ */
|
|
3375
|
+
return /* @__PURE__ */ jsx65(
|
|
3315
3376
|
"div",
|
|
3316
3377
|
{
|
|
3317
3378
|
ref,
|
|
@@ -3328,7 +3389,7 @@ var GridOverlay = React54.forwardRef(
|
|
|
3328
3389
|
...style
|
|
3329
3390
|
},
|
|
3330
3391
|
...props,
|
|
3331
|
-
children: Array.from({ length: count }).map((_, i) => /* @__PURE__ */
|
|
3392
|
+
children: Array.from({ length: count }).map((_, i) => /* @__PURE__ */ jsx65("span", { style: { backgroundColor: "var(--bg-brand)", opacity: 0.1 } }, i))
|
|
3332
3393
|
}
|
|
3333
3394
|
);
|
|
3334
3395
|
}
|
|
@@ -3339,7 +3400,7 @@ GridOverlay.displayName = "GridOverlay";
|
|
|
3339
3400
|
import * as React55 from "react";
|
|
3340
3401
|
import { cva as cva9 } from "class-variance-authority";
|
|
3341
3402
|
import { Link2 as Link22, KeyRound, Clock, Plus } from "lucide-react";
|
|
3342
|
-
import { jsx as
|
|
3403
|
+
import { jsx as jsx66, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
3343
3404
|
var segmentChipVariants = cva9(
|
|
3344
3405
|
"inline-flex items-center gap-1.5 rounded-lg border px-2.5 py-1 text-sm font-medium leading-tight",
|
|
3345
3406
|
{
|
|
@@ -3363,8 +3424,8 @@ var kindIcons = {
|
|
|
3363
3424
|
var SegmentChip = React55.forwardRef(
|
|
3364
3425
|
({ kind, resource, icon, hideIcon = false, className, ...props }, ref) => {
|
|
3365
3426
|
const Icon = icon ?? kindIcons[kind ?? "granted"];
|
|
3366
|
-
return /* @__PURE__ */
|
|
3367
|
-
!hideIcon && /* @__PURE__ */
|
|
3427
|
+
return /* @__PURE__ */ jsxs33("span", { ref, className: cn(segmentChipVariants({ kind }), className), ...props, children: [
|
|
3428
|
+
!hideIcon && /* @__PURE__ */ jsx66(Icon, { className: "size-3.5 shrink-0 opacity-90", "aria-hidden": "true" }),
|
|
3368
3429
|
resource
|
|
3369
3430
|
] });
|
|
3370
3431
|
}
|
|
@@ -3374,7 +3435,7 @@ SegmentChip.displayName = "SegmentChip";
|
|
|
3374
3435
|
// src/components/connection-card.tsx
|
|
3375
3436
|
import * as React56 from "react";
|
|
3376
3437
|
import { AlertTriangle, ChevronDown as ChevronDown4 } from "lucide-react";
|
|
3377
|
-
import { Fragment as Fragment5, jsx as
|
|
3438
|
+
import { Fragment as Fragment5, jsx as jsx67, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
3378
3439
|
var authLabels = { app: "App", oauth: "OAuth", token: "token" };
|
|
3379
3440
|
var statusMeta = {
|
|
3380
3441
|
connected: { label: "Connected", badge: "success", dot: "success" },
|
|
@@ -3405,7 +3466,7 @@ var ConnectionCard = React56.forwardRef(
|
|
|
3405
3466
|
}, ref) => {
|
|
3406
3467
|
const meta = statusMeta[status];
|
|
3407
3468
|
const connected = status !== "disconnected";
|
|
3408
|
-
const glyphBox = /* @__PURE__ */
|
|
3469
|
+
const glyphBox = /* @__PURE__ */ jsx67(
|
|
3409
3470
|
"div",
|
|
3410
3471
|
{
|
|
3411
3472
|
"aria-hidden": "true",
|
|
@@ -3413,51 +3474,51 @@ var ConnectionCard = React56.forwardRef(
|
|
|
3413
3474
|
children: glyph ?? monogram(name)
|
|
3414
3475
|
}
|
|
3415
3476
|
);
|
|
3416
|
-
const identity = /* @__PURE__ */
|
|
3417
|
-
/* @__PURE__ */
|
|
3418
|
-
/* @__PURE__ */
|
|
3419
|
-
/* @__PURE__ */
|
|
3420
|
-
/* @__PURE__ */
|
|
3477
|
+
const identity = /* @__PURE__ */ jsxs34("div", { className: "min-w-0", children: [
|
|
3478
|
+
/* @__PURE__ */ jsx67("p", { className: "truncate text-sm font-semibold text-text-primary", children: name }),
|
|
3479
|
+
/* @__PURE__ */ jsxs34("div", { className: "mt-0.5 flex flex-wrap gap-1", children: [
|
|
3480
|
+
/* @__PURE__ */ jsx67(Badge, { variant: "secondary", children: scope }),
|
|
3481
|
+
/* @__PURE__ */ jsx67(Badge, { variant: "secondary", children: authLabels[auth] })
|
|
3421
3482
|
] })
|
|
3422
3483
|
] });
|
|
3423
|
-
const statusBadge = /* @__PURE__ */
|
|
3424
|
-
/* @__PURE__ */
|
|
3484
|
+
const statusBadge = /* @__PURE__ */ jsxs34(Badge, { variant: meta.badge, className: "gap-1.5", children: [
|
|
3485
|
+
/* @__PURE__ */ jsx67(StatusDot, { status: meta.dot, size: "sm" }),
|
|
3425
3486
|
statusLabel ?? meta.label
|
|
3426
3487
|
] });
|
|
3427
|
-
const accessNote = access ? /* @__PURE__ */
|
|
3488
|
+
const accessNote = access ? /* @__PURE__ */ jsxs34(
|
|
3428
3489
|
"div",
|
|
3429
3490
|
{
|
|
3430
3491
|
role: "note",
|
|
3431
3492
|
className: "flex items-start gap-2 border-t border-border-subtle bg-bg-warning-subtle px-4 py-2.5 text-xs font-medium text-text-warning",
|
|
3432
3493
|
children: [
|
|
3433
|
-
/* @__PURE__ */
|
|
3434
|
-
/* @__PURE__ */
|
|
3494
|
+
/* @__PURE__ */ jsx67(AlertTriangle, { className: "mt-0.5 size-3.5 shrink-0", "aria-hidden": "true" }),
|
|
3495
|
+
/* @__PURE__ */ jsx67("span", { children: access })
|
|
3435
3496
|
]
|
|
3436
3497
|
}
|
|
3437
3498
|
) : null;
|
|
3438
3499
|
const footerAction = collapsible ? action : connected && action;
|
|
3439
|
-
const footer = grantedCount !== void 0 || footerAction ? /* @__PURE__ */
|
|
3440
|
-
/* @__PURE__ */
|
|
3500
|
+
const footer = grantedCount !== void 0 || footerAction ? /* @__PURE__ */ jsxs34("div", { className: "flex items-center justify-between border-t border-border-subtle px-4 py-3", children: [
|
|
3501
|
+
/* @__PURE__ */ jsx67("span", { className: "text-sm text-text-secondary", children: grantedCount !== void 0 ? /* @__PURE__ */ jsxs34(Fragment5, { children: [
|
|
3441
3502
|
"Granted to ",
|
|
3442
|
-
/* @__PURE__ */
|
|
3503
|
+
/* @__PURE__ */ jsx67("span", { className: "font-semibold text-text-primary", children: grantedCount }),
|
|
3443
3504
|
" ",
|
|
3444
3505
|
grantedCount === 1 ? "product" : "products"
|
|
3445
|
-
] }) : /* @__PURE__ */
|
|
3506
|
+
] }) : /* @__PURE__ */ jsx67("span", { className: "text-text-tertiary", children: "Not granted to any product yet" }) }),
|
|
3446
3507
|
footerAction
|
|
3447
3508
|
] }) : null;
|
|
3448
|
-
const drawer = children ? /* @__PURE__ */
|
|
3509
|
+
const drawer = children ? /* @__PURE__ */ jsx67("div", { "data-slot": "drawer", className: "border-t border-border-subtle", children }) : null;
|
|
3449
3510
|
if (!collapsible) {
|
|
3450
|
-
return /* @__PURE__ */
|
|
3511
|
+
return /* @__PURE__ */ jsxs34(
|
|
3451
3512
|
Card,
|
|
3452
3513
|
{
|
|
3453
3514
|
ref,
|
|
3454
3515
|
className: cn(status === "disconnected" && "border-dashed border-border-default", className),
|
|
3455
3516
|
...props,
|
|
3456
3517
|
children: [
|
|
3457
|
-
/* @__PURE__ */
|
|
3518
|
+
/* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-3 p-4", children: [
|
|
3458
3519
|
glyphBox,
|
|
3459
3520
|
identity,
|
|
3460
|
-
/* @__PURE__ */
|
|
3521
|
+
/* @__PURE__ */ jsx67("div", { className: "ml-auto shrink-0", children: connected ? statusBadge : action })
|
|
3461
3522
|
] }),
|
|
3462
3523
|
accessNote,
|
|
3463
3524
|
footer,
|
|
@@ -3466,7 +3527,7 @@ var ConnectionCard = React56.forwardRef(
|
|
|
3466
3527
|
}
|
|
3467
3528
|
);
|
|
3468
3529
|
}
|
|
3469
|
-
return /* @__PURE__ */
|
|
3530
|
+
return /* @__PURE__ */ jsx67(Collapsible, { defaultOpen, open, onOpenChange, children: /* @__PURE__ */ jsxs34(
|
|
3470
3531
|
Card,
|
|
3471
3532
|
{
|
|
3472
3533
|
ref,
|
|
@@ -3477,7 +3538,7 @@ var ConnectionCard = React56.forwardRef(
|
|
|
3477
3538
|
),
|
|
3478
3539
|
...props,
|
|
3479
3540
|
children: [
|
|
3480
|
-
/* @__PURE__ */
|
|
3541
|
+
/* @__PURE__ */ jsx67(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs34(
|
|
3481
3542
|
"button",
|
|
3482
3543
|
{
|
|
3483
3544
|
type: "button",
|
|
@@ -3485,9 +3546,9 @@ var ConnectionCard = React56.forwardRef(
|
|
|
3485
3546
|
children: [
|
|
3486
3547
|
glyphBox,
|
|
3487
3548
|
identity,
|
|
3488
|
-
/* @__PURE__ */
|
|
3549
|
+
/* @__PURE__ */ jsxs34("div", { className: "ml-auto flex shrink-0 items-center gap-2", children: [
|
|
3489
3550
|
statusBadge,
|
|
3490
|
-
/* @__PURE__ */
|
|
3551
|
+
/* @__PURE__ */ jsx67(
|
|
3491
3552
|
ChevronDown4,
|
|
3492
3553
|
{
|
|
3493
3554
|
"aria-hidden": "true",
|
|
@@ -3498,7 +3559,7 @@ var ConnectionCard = React56.forwardRef(
|
|
|
3498
3559
|
]
|
|
3499
3560
|
}
|
|
3500
3561
|
) }),
|
|
3501
|
-
/* @__PURE__ */
|
|
3562
|
+
/* @__PURE__ */ jsxs34(CollapsibleContent2, { children: [
|
|
3502
3563
|
accessNote,
|
|
3503
3564
|
footer,
|
|
3504
3565
|
drawer
|
|
@@ -3512,7 +3573,7 @@ ConnectionCard.displayName = "ConnectionCard";
|
|
|
3512
3573
|
|
|
3513
3574
|
// src/components/request-row.tsx
|
|
3514
3575
|
import * as React57 from "react";
|
|
3515
|
-
import { Fragment as Fragment6, jsx as
|
|
3576
|
+
import { Fragment as Fragment6, jsx as jsx68, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
3516
3577
|
function monogram2(name) {
|
|
3517
3578
|
return name.replace(/[^a-zA-Z0-9 ]/g, " ").split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0].toUpperCase()).join("");
|
|
3518
3579
|
}
|
|
@@ -3521,22 +3582,22 @@ var RequestRow = React57.forwardRef(
|
|
|
3521
3582
|
let controls = action;
|
|
3522
3583
|
if (controls === void 0) {
|
|
3523
3584
|
if (surface === "org" && state2 === "pending") {
|
|
3524
|
-
controls = /* @__PURE__ */
|
|
3525
|
-
/* @__PURE__ */
|
|
3526
|
-
/* @__PURE__ */
|
|
3585
|
+
controls = /* @__PURE__ */ jsxs35(Fragment6, { children: [
|
|
3586
|
+
/* @__PURE__ */ jsx68(Button, { variant: "outline", size: "sm", onClick: onDeny, children: "Deny" }),
|
|
3587
|
+
/* @__PURE__ */ jsx68(Button, { size: "sm", onClick: onApprove, children: "Approve" })
|
|
3527
3588
|
] });
|
|
3528
3589
|
} else if (state2 === "available") {
|
|
3529
|
-
controls = /* @__PURE__ */
|
|
3590
|
+
controls = /* @__PURE__ */ jsx68(Button, { size: "sm", onClick: onRequest, children: "Request" });
|
|
3530
3591
|
} else if (state2 === "pending") {
|
|
3531
|
-
controls = /* @__PURE__ */
|
|
3532
|
-
/* @__PURE__ */
|
|
3592
|
+
controls = /* @__PURE__ */ jsxs35(Badge, { variant: "secondary", className: "gap-1.5", children: [
|
|
3593
|
+
/* @__PURE__ */ jsx68(StatusDot, { status: "neutral", size: "sm" }),
|
|
3533
3594
|
"Pending"
|
|
3534
3595
|
] });
|
|
3535
3596
|
} else if (state2 === "granted") {
|
|
3536
|
-
controls = /* @__PURE__ */
|
|
3597
|
+
controls = /* @__PURE__ */ jsx68(SegmentChip, { kind: "granted", resource: grantedResource ?? "a segment" });
|
|
3537
3598
|
}
|
|
3538
3599
|
}
|
|
3539
|
-
return /* @__PURE__ */
|
|
3600
|
+
return /* @__PURE__ */ jsxs35(
|
|
3540
3601
|
"div",
|
|
3541
3602
|
{
|
|
3542
3603
|
ref,
|
|
@@ -3546,7 +3607,7 @@ var RequestRow = React57.forwardRef(
|
|
|
3546
3607
|
),
|
|
3547
3608
|
...props,
|
|
3548
3609
|
children: [
|
|
3549
|
-
/* @__PURE__ */
|
|
3610
|
+
/* @__PURE__ */ jsx68(
|
|
3550
3611
|
"div",
|
|
3551
3612
|
{
|
|
3552
3613
|
"aria-hidden": "true",
|
|
@@ -3554,17 +3615,127 @@ var RequestRow = React57.forwardRef(
|
|
|
3554
3615
|
children: glyph ?? monogram2(name)
|
|
3555
3616
|
}
|
|
3556
3617
|
),
|
|
3557
|
-
/* @__PURE__ */
|
|
3558
|
-
/* @__PURE__ */
|
|
3559
|
-
subtitle && /* @__PURE__ */
|
|
3618
|
+
/* @__PURE__ */ jsxs35("div", { className: "min-w-0", children: [
|
|
3619
|
+
/* @__PURE__ */ jsx68("p", { className: "truncate text-sm font-semibold text-text-primary", children: name }),
|
|
3620
|
+
subtitle && /* @__PURE__ */ jsx68("p", { className: "truncate text-xs text-text-tertiary", children: subtitle })
|
|
3560
3621
|
] }),
|
|
3561
|
-
/* @__PURE__ */
|
|
3622
|
+
/* @__PURE__ */ jsx68("div", { className: "ml-auto flex shrink-0 items-center gap-2", children: controls })
|
|
3562
3623
|
]
|
|
3563
3624
|
}
|
|
3564
3625
|
);
|
|
3565
3626
|
}
|
|
3566
3627
|
);
|
|
3567
3628
|
RequestRow.displayName = "RequestRow";
|
|
3629
|
+
|
|
3630
|
+
// src/components/feedback-widget.tsx
|
|
3631
|
+
import * as React58 from "react";
|
|
3632
|
+
import { MessageSquare, Loader2 as Loader22, CheckCircle2 } from "lucide-react";
|
|
3633
|
+
import { jsx as jsx69, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
3634
|
+
var TITLE_MAX = 256;
|
|
3635
|
+
var DETAILS_MAX = 65536;
|
|
3636
|
+
var DEFAULT_LABELS = {
|
|
3637
|
+
trigger: "Feedback",
|
|
3638
|
+
title: "Send feedback",
|
|
3639
|
+
titleField: "Title",
|
|
3640
|
+
detailsField: "Details",
|
|
3641
|
+
submit: "Send feedback",
|
|
3642
|
+
success: "Thanks! Your feedback was sent.",
|
|
3643
|
+
error: "Couldn't send feedback. Please try again."
|
|
3644
|
+
};
|
|
3645
|
+
function FeedbackWidget({ onSubmit, labels, className }) {
|
|
3646
|
+
const l = { ...DEFAULT_LABELS, ...labels };
|
|
3647
|
+
const uid = React58.useId();
|
|
3648
|
+
const titleId = `${uid}-title`;
|
|
3649
|
+
const detailsId = `${uid}-details`;
|
|
3650
|
+
const titleErrId = `${uid}-title-error`;
|
|
3651
|
+
const detailsErrId = `${uid}-details-error`;
|
|
3652
|
+
const [open, setOpen] = React58.useState(false);
|
|
3653
|
+
const [status, setStatus] = React58.useState("idle");
|
|
3654
|
+
const [title, setTitle] = React58.useState("");
|
|
3655
|
+
const [details, setDetails] = React58.useState("");
|
|
3656
|
+
const titleTooLong = title.length > TITLE_MAX;
|
|
3657
|
+
const detailsTooLong = details.length > DETAILS_MAX;
|
|
3658
|
+
const titleEmpty = title.trim().length === 0;
|
|
3659
|
+
const detailsEmpty = details.trim().length === 0;
|
|
3660
|
+
const valid = !titleEmpty && !detailsEmpty && !titleTooLong && !detailsTooLong;
|
|
3661
|
+
const submitting = status === "submitting";
|
|
3662
|
+
const changeOpen = (next) => {
|
|
3663
|
+
if (submitting) return;
|
|
3664
|
+
setOpen(next);
|
|
3665
|
+
if (!next) setStatus("idle");
|
|
3666
|
+
};
|
|
3667
|
+
const handleSubmit = async (e) => {
|
|
3668
|
+
e.preventDefault();
|
|
3669
|
+
if (!valid || submitting) return;
|
|
3670
|
+
setStatus("submitting");
|
|
3671
|
+
try {
|
|
3672
|
+
await onSubmit({ title, details });
|
|
3673
|
+
setStatus("success");
|
|
3674
|
+
setTitle("");
|
|
3675
|
+
setDetails("");
|
|
3676
|
+
} catch {
|
|
3677
|
+
setStatus("error");
|
|
3678
|
+
}
|
|
3679
|
+
};
|
|
3680
|
+
return /* @__PURE__ */ jsxs36(Popover, { open, onOpenChange: changeOpen, children: [
|
|
3681
|
+
/* @__PURE__ */ jsx69("div", { className: cn("fixed bottom-4 right-4 z-50", className), children: /* @__PURE__ */ jsx69(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs36(Button, { "aria-label": l.trigger, children: [
|
|
3682
|
+
/* @__PURE__ */ jsx69(MessageSquare, { className: "size-4", "aria-hidden": "true" }),
|
|
3683
|
+
l.trigger
|
|
3684
|
+
] }) }) }),
|
|
3685
|
+
/* @__PURE__ */ jsx69(PopoverContent, { align: "end", side: "top", className: "w-80", children: status === "success" ? /* @__PURE__ */ jsxs36("div", { className: "flex flex-col items-center gap-3 py-2 text-center", children: [
|
|
3686
|
+
/* @__PURE__ */ jsx69(CheckCircle2, { className: "size-8 text-text-success", "aria-hidden": "true" }),
|
|
3687
|
+
/* @__PURE__ */ jsx69("p", { role: "status", className: "text-sm text-text-primary", children: l.success }),
|
|
3688
|
+
/* @__PURE__ */ jsx69(Button, { variant: "outline", size: "sm", onClick: () => changeOpen(false), children: "Close" })
|
|
3689
|
+
] }) : /* @__PURE__ */ jsxs36("form", { onSubmit: handleSubmit, className: "flex flex-col gap-3", children: [
|
|
3690
|
+
/* @__PURE__ */ jsx69("p", { className: "text-sm font-medium text-text-primary", children: l.title }),
|
|
3691
|
+
/* @__PURE__ */ jsxs36("div", { className: "flex flex-col gap-1.5", children: [
|
|
3692
|
+
/* @__PURE__ */ jsx69(Label2, { htmlFor: titleId, children: l.titleField }),
|
|
3693
|
+
/* @__PURE__ */ jsx69(
|
|
3694
|
+
Input,
|
|
3695
|
+
{
|
|
3696
|
+
id: titleId,
|
|
3697
|
+
value: title,
|
|
3698
|
+
onChange: (e) => setTitle(e.target.value),
|
|
3699
|
+
disabled: submitting,
|
|
3700
|
+
"aria-invalid": titleTooLong || void 0,
|
|
3701
|
+
"aria-describedby": titleTooLong ? titleErrId : void 0
|
|
3702
|
+
}
|
|
3703
|
+
),
|
|
3704
|
+
titleTooLong && /* @__PURE__ */ jsxs36("p", { id: titleErrId, className: "text-xs text-text-danger", children: [
|
|
3705
|
+
l.titleField,
|
|
3706
|
+
" must be ",
|
|
3707
|
+
TITLE_MAX,
|
|
3708
|
+
" characters or fewer."
|
|
3709
|
+
] })
|
|
3710
|
+
] }),
|
|
3711
|
+
/* @__PURE__ */ jsxs36("div", { className: "flex flex-col gap-1.5", children: [
|
|
3712
|
+
/* @__PURE__ */ jsx69(Label2, { htmlFor: detailsId, children: l.detailsField }),
|
|
3713
|
+
/* @__PURE__ */ jsx69(
|
|
3714
|
+
Textarea,
|
|
3715
|
+
{
|
|
3716
|
+
id: detailsId,
|
|
3717
|
+
value: details,
|
|
3718
|
+
onChange: (e) => setDetails(e.target.value),
|
|
3719
|
+
disabled: submitting,
|
|
3720
|
+
"aria-invalid": detailsTooLong || void 0,
|
|
3721
|
+
"aria-describedby": detailsTooLong ? detailsErrId : void 0
|
|
3722
|
+
}
|
|
3723
|
+
),
|
|
3724
|
+
detailsTooLong && /* @__PURE__ */ jsxs36("p", { id: detailsErrId, className: "text-xs text-text-danger", children: [
|
|
3725
|
+
l.detailsField,
|
|
3726
|
+
" must be ",
|
|
3727
|
+
DETAILS_MAX,
|
|
3728
|
+
" characters or fewer."
|
|
3729
|
+
] })
|
|
3730
|
+
] }),
|
|
3731
|
+
status === "error" && /* @__PURE__ */ jsx69(InlineError, { children: l.error }),
|
|
3732
|
+
/* @__PURE__ */ jsxs36(Button, { type: "submit", disabled: !valid || submitting, children: [
|
|
3733
|
+
submitting && /* @__PURE__ */ jsx69(Loader22, { className: "size-4 animate-spin", "aria-hidden": "true" }),
|
|
3734
|
+
l.submit
|
|
3735
|
+
] })
|
|
3736
|
+
] }) })
|
|
3737
|
+
] });
|
|
3738
|
+
}
|
|
3568
3739
|
export {
|
|
3569
3740
|
Accordion,
|
|
3570
3741
|
AccordionContent,
|
|
@@ -3684,6 +3855,7 @@ export {
|
|
|
3684
3855
|
EmptyState,
|
|
3685
3856
|
ExtensionIcon,
|
|
3686
3857
|
ExtensionLink,
|
|
3858
|
+
FeedbackWidget,
|
|
3687
3859
|
Form,
|
|
3688
3860
|
FormControl,
|
|
3689
3861
|
FormDescription,
|
|
@@ -3762,6 +3934,7 @@ export {
|
|
|
3762
3934
|
SheetPortal,
|
|
3763
3935
|
SheetTitle,
|
|
3764
3936
|
SheetTrigger,
|
|
3937
|
+
SidebarBackHeader,
|
|
3765
3938
|
SidebarNav,
|
|
3766
3939
|
SidebarNavLink,
|
|
3767
3940
|
SidebarProductHeader,
|