@lessly/ui 0.10.0 → 0.12.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 +40 -8
- package/dist/index.js +112 -6
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1094,8 +1094,8 @@ interface RequestRowProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, '
|
|
|
1094
1094
|
}
|
|
1095
1095
|
declare const RequestRow: React$1.ForwardRefExoticComponent<RequestRowProps & React$1.RefAttributes<HTMLDivElement>>;
|
|
1096
1096
|
|
|
1097
|
-
interface
|
|
1098
|
-
/**
|
|
1097
|
+
interface FeedbackButtonLabels {
|
|
1098
|
+
/** Inline trigger button label + its aria-label. */
|
|
1099
1099
|
trigger: string;
|
|
1100
1100
|
/** Heading shown above the form. */
|
|
1101
1101
|
title: string;
|
|
@@ -1110,9 +1110,9 @@ interface FeedbackWidgetLabels {
|
|
|
1110
1110
|
/** Message shown after a failed submit. */
|
|
1111
1111
|
error: string;
|
|
1112
1112
|
}
|
|
1113
|
-
interface
|
|
1113
|
+
interface FeedbackButtonProps {
|
|
1114
1114
|
/**
|
|
1115
|
-
* Called with the entered feedback when the form is submitted. The
|
|
1115
|
+
* Called with the entered feedback when the form is submitted. The button is
|
|
1116
1116
|
* presentational: it knows nothing about APIs, auth, or routing — the parent
|
|
1117
1117
|
* decides what to do with the data. Rejecting shows the error state.
|
|
1118
1118
|
*/
|
|
@@ -1121,10 +1121,42 @@ interface FeedbackWidgetProps {
|
|
|
1121
1121
|
details: string;
|
|
1122
1122
|
}) => Promise<void>;
|
|
1123
1123
|
/** Override any of the default copy. */
|
|
1124
|
-
labels?: Partial<
|
|
1125
|
-
/** Merged onto the
|
|
1124
|
+
labels?: Partial<FeedbackButtonLabels>;
|
|
1125
|
+
/** Merged onto the inline trigger button (e.g. to align it with neighbouring top-bar controls). */
|
|
1126
1126
|
className?: string;
|
|
1127
1127
|
}
|
|
1128
|
-
declare function
|
|
1128
|
+
declare function FeedbackButton({ onSubmit, labels, className }: FeedbackButtonProps): React$1.JSX.Element;
|
|
1129
1129
|
|
|
1130
|
-
|
|
1130
|
+
interface CreateProductWindowOrganization {
|
|
1131
|
+
id: string;
|
|
1132
|
+
name: string;
|
|
1133
|
+
}
|
|
1134
|
+
interface CreateProductWindowProduct {
|
|
1135
|
+
id: string;
|
|
1136
|
+
name: string;
|
|
1137
|
+
slug: string;
|
|
1138
|
+
}
|
|
1139
|
+
type CreateProductSubmit = {
|
|
1140
|
+
name: string;
|
|
1141
|
+
organizationId: string;
|
|
1142
|
+
} | {
|
|
1143
|
+
name: string;
|
|
1144
|
+
organizationName: string;
|
|
1145
|
+
};
|
|
1146
|
+
interface CreateProductWindowProps {
|
|
1147
|
+
organizations: CreateProductWindowOrganization[];
|
|
1148
|
+
/** null => create-new-org mode */
|
|
1149
|
+
selectedOrgId: string | null;
|
|
1150
|
+
/** products of the selected org */
|
|
1151
|
+
products: CreateProductWindowProduct[];
|
|
1152
|
+
productsLoading?: boolean;
|
|
1153
|
+
submitting?: boolean;
|
|
1154
|
+
error?: string | null;
|
|
1155
|
+
/** null when "+ Create new organization" chosen */
|
|
1156
|
+
onOrganizationChange: (orgId: string | null) => void;
|
|
1157
|
+
onEnterProduct: (product: CreateProductWindowProduct) => void;
|
|
1158
|
+
onSubmit: (data: CreateProductSubmit) => void;
|
|
1159
|
+
}
|
|
1160
|
+
declare function CreateProductWindow({ organizations, selectedOrgId, products, productsLoading, submitting, error, onOrganizationChange, onEnterProduct, onSubmit, }: CreateProductWindowProps): React$1.JSX.Element;
|
|
1161
|
+
|
|
1162
|
+
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, type CreateProductSubmit, CreateProductWindow, type CreateProductWindowOrganization, type CreateProductWindowProduct, type CreateProductWindowProps, 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, FeedbackButton, type FeedbackButtonLabels, type FeedbackButtonProps, 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
|
@@ -3627,7 +3627,7 @@ var RequestRow = React57.forwardRef(
|
|
|
3627
3627
|
);
|
|
3628
3628
|
RequestRow.displayName = "RequestRow";
|
|
3629
3629
|
|
|
3630
|
-
// src/components/feedback-
|
|
3630
|
+
// src/components/feedback-button.tsx
|
|
3631
3631
|
import * as React58 from "react";
|
|
3632
3632
|
import { MessageSquare, Loader2 as Loader22, CheckCircle2 } from "lucide-react";
|
|
3633
3633
|
import { jsx as jsx69, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
@@ -3642,7 +3642,7 @@ var DEFAULT_LABELS = {
|
|
|
3642
3642
|
success: "Thanks! Your feedback was sent.",
|
|
3643
3643
|
error: "Couldn't send feedback. Please try again."
|
|
3644
3644
|
};
|
|
3645
|
-
function
|
|
3645
|
+
function FeedbackButton({ onSubmit, labels, className }) {
|
|
3646
3646
|
const l = { ...DEFAULT_LABELS, ...labels };
|
|
3647
3647
|
const uid = React58.useId();
|
|
3648
3648
|
const titleId = `${uid}-title`;
|
|
@@ -3678,11 +3678,11 @@ function FeedbackWidget({ onSubmit, labels, className }) {
|
|
|
3678
3678
|
}
|
|
3679
3679
|
};
|
|
3680
3680
|
return /* @__PURE__ */ jsxs36(Popover, { open, onOpenChange: changeOpen, children: [
|
|
3681
|
-
/* @__PURE__ */ jsx69(
|
|
3681
|
+
/* @__PURE__ */ jsx69(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs36(Button, { variant: "ghost", size: "sm", "aria-label": l.trigger, className, children: [
|
|
3682
3682
|
/* @__PURE__ */ jsx69(MessageSquare, { className: "size-4", "aria-hidden": "true" }),
|
|
3683
3683
|
l.trigger
|
|
3684
|
-
] }) })
|
|
3685
|
-
/* @__PURE__ */ jsx69(PopoverContent, { align: "end", side: "
|
|
3684
|
+
] }) }),
|
|
3685
|
+
/* @__PURE__ */ jsx69(PopoverContent, { align: "end", side: "bottom", className: "w-80", children: status === "success" ? /* @__PURE__ */ jsxs36("div", { className: "flex flex-col items-center gap-3 py-2 text-center", children: [
|
|
3686
3686
|
/* @__PURE__ */ jsx69(CheckCircle2, { className: "size-8 text-text-success", "aria-hidden": "true" }),
|
|
3687
3687
|
/* @__PURE__ */ jsx69("p", { role: "status", className: "text-sm text-text-primary", children: l.success }),
|
|
3688
3688
|
/* @__PURE__ */ jsx69(Button, { variant: "outline", size: "sm", onClick: () => changeOpen(false), children: "Close" })
|
|
@@ -3736,6 +3736,111 @@ function FeedbackWidget({ onSubmit, labels, className }) {
|
|
|
3736
3736
|
] }) })
|
|
3737
3737
|
] });
|
|
3738
3738
|
}
|
|
3739
|
+
|
|
3740
|
+
// src/components/create-product-window.tsx
|
|
3741
|
+
import { useForm } from "react-hook-form";
|
|
3742
|
+
import { jsx as jsx70, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
3743
|
+
var CREATE_ORG_VALUE = "__create_new_org__";
|
|
3744
|
+
function CreateProductWindow({
|
|
3745
|
+
organizations,
|
|
3746
|
+
selectedOrgId,
|
|
3747
|
+
products,
|
|
3748
|
+
productsLoading,
|
|
3749
|
+
submitting,
|
|
3750
|
+
error,
|
|
3751
|
+
onOrganizationChange,
|
|
3752
|
+
onEnterProduct,
|
|
3753
|
+
onSubmit
|
|
3754
|
+
}) {
|
|
3755
|
+
const form = useForm({
|
|
3756
|
+
defaultValues: { productName: "", organizationName: "" }
|
|
3757
|
+
});
|
|
3758
|
+
const createOrgMode = selectedOrgId === null || organizations.length === 0;
|
|
3759
|
+
const options = [
|
|
3760
|
+
...organizations.map((org) => ({ value: org.id, label: org.name })),
|
|
3761
|
+
{ value: CREATE_ORG_VALUE, label: "+ Create new organization" }
|
|
3762
|
+
];
|
|
3763
|
+
function handleOrgChange(value) {
|
|
3764
|
+
onOrganizationChange(value === CREATE_ORG_VALUE ? null : value);
|
|
3765
|
+
}
|
|
3766
|
+
const handleSubmit = form.handleSubmit((values) => {
|
|
3767
|
+
const name = values.productName.trim();
|
|
3768
|
+
if (createOrgMode) {
|
|
3769
|
+
onSubmit({ name, organizationName: values.organizationName.trim() });
|
|
3770
|
+
} else {
|
|
3771
|
+
onSubmit({ name, organizationId: selectedOrgId });
|
|
3772
|
+
}
|
|
3773
|
+
});
|
|
3774
|
+
const showSelect = organizations.length > 0;
|
|
3775
|
+
return /* @__PURE__ */ jsxs37("div", { className: "flex w-full max-w-md flex-col gap-6", children: [
|
|
3776
|
+
showSelect && /* @__PURE__ */ jsxs37("div", { className: "space-y-2", children: [
|
|
3777
|
+
/* @__PURE__ */ jsx70("span", { className: "text-sm font-medium leading-none text-text-primary", children: "Organization" }),
|
|
3778
|
+
/* @__PURE__ */ jsx70(
|
|
3779
|
+
Select,
|
|
3780
|
+
{
|
|
3781
|
+
"data-testid": "create-product-org-select",
|
|
3782
|
+
"aria-label": "Organization",
|
|
3783
|
+
value: createOrgMode ? CREATE_ORG_VALUE : selectedOrgId,
|
|
3784
|
+
onValueChange: handleOrgChange,
|
|
3785
|
+
options,
|
|
3786
|
+
optionTestId: (value) => value === CREATE_ORG_VALUE ? "create-product-org-option-new" : `create-product-org-option-${value}`,
|
|
3787
|
+
placeholder: "Select an organization\u2026"
|
|
3788
|
+
}
|
|
3789
|
+
)
|
|
3790
|
+
] }),
|
|
3791
|
+
!createOrgMode && /* @__PURE__ */ jsxs37("div", { className: "space-y-2", children: [
|
|
3792
|
+
/* @__PURE__ */ jsx70("span", { className: "text-sm font-medium leading-none text-text-primary", children: "Products" }),
|
|
3793
|
+
productsLoading ? /* @__PURE__ */ jsx70("p", { className: "text-sm text-text-tertiary", children: "Loading products\u2026" }) : products.length === 0 ? /* @__PURE__ */ jsx70("p", { className: "text-sm text-text-tertiary", children: "No products yet." }) : /* @__PURE__ */ jsx70("ul", { className: "flex flex-col gap-1", children: products.map((product) => /* @__PURE__ */ jsx70("li", { children: /* @__PURE__ */ jsxs37(
|
|
3794
|
+
"button",
|
|
3795
|
+
{
|
|
3796
|
+
type: "button",
|
|
3797
|
+
onClick: () => onEnterProduct(product),
|
|
3798
|
+
className: cn(
|
|
3799
|
+
"flex w-full items-center justify-between rounded-md border border-border-default bg-bg-primary px-3 py-2 text-left text-sm text-text-primary hover:bg-bg-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus"
|
|
3800
|
+
),
|
|
3801
|
+
children: [
|
|
3802
|
+
/* @__PURE__ */ jsx70("span", { className: "truncate", children: product.name }),
|
|
3803
|
+
/* @__PURE__ */ jsx70("span", { className: "ml-2 truncate text-text-tertiary", children: product.slug })
|
|
3804
|
+
]
|
|
3805
|
+
}
|
|
3806
|
+
) }, product.id)) })
|
|
3807
|
+
] }),
|
|
3808
|
+
/* @__PURE__ */ jsx70(Form, { ...form, children: /* @__PURE__ */ jsxs37("form", { onSubmit: handleSubmit, className: "flex flex-col gap-4", noValidate: true, children: [
|
|
3809
|
+
createOrgMode && /* @__PURE__ */ jsx70(
|
|
3810
|
+
FormField,
|
|
3811
|
+
{
|
|
3812
|
+
control: form.control,
|
|
3813
|
+
name: "organizationName",
|
|
3814
|
+
rules: {
|
|
3815
|
+
validate: (value) => value.trim().length > 0 || "Organization name is required"
|
|
3816
|
+
},
|
|
3817
|
+
render: ({ field }) => /* @__PURE__ */ jsxs37(FormItem, { children: [
|
|
3818
|
+
/* @__PURE__ */ jsx70(FormLabel, { children: "Organization name" }),
|
|
3819
|
+
/* @__PURE__ */ jsx70(FormControl, { children: /* @__PURE__ */ jsx70(Input, { placeholder: "Acme Inc.", ...field }) }),
|
|
3820
|
+
/* @__PURE__ */ jsx70(FormMessage, {})
|
|
3821
|
+
] })
|
|
3822
|
+
}
|
|
3823
|
+
),
|
|
3824
|
+
/* @__PURE__ */ jsx70(
|
|
3825
|
+
FormField,
|
|
3826
|
+
{
|
|
3827
|
+
control: form.control,
|
|
3828
|
+
name: "productName",
|
|
3829
|
+
rules: {
|
|
3830
|
+
validate: (value) => value.trim().length > 0 || "Product name is required"
|
|
3831
|
+
},
|
|
3832
|
+
render: ({ field }) => /* @__PURE__ */ jsxs37(FormItem, { children: [
|
|
3833
|
+
/* @__PURE__ */ jsx70(FormLabel, { children: "Product name" }),
|
|
3834
|
+
/* @__PURE__ */ jsx70(FormControl, { children: /* @__PURE__ */ jsx70(Input, { placeholder: "My product", ...field }) }),
|
|
3835
|
+
/* @__PURE__ */ jsx70(FormMessage, {})
|
|
3836
|
+
] })
|
|
3837
|
+
}
|
|
3838
|
+
),
|
|
3839
|
+
error && /* @__PURE__ */ jsx70(InlineError, { children: error }),
|
|
3840
|
+
/* @__PURE__ */ jsx70(Button, { type: "submit", disabled: submitting, children: "Create product" })
|
|
3841
|
+
] }) })
|
|
3842
|
+
] });
|
|
3843
|
+
}
|
|
3739
3844
|
export {
|
|
3740
3845
|
Accordion,
|
|
3741
3846
|
AccordionContent,
|
|
@@ -3815,6 +3920,7 @@ export {
|
|
|
3815
3920
|
ContextMenuSubTrigger,
|
|
3816
3921
|
ContextMenuTrigger,
|
|
3817
3922
|
CopyButton,
|
|
3923
|
+
CreateProductWindow,
|
|
3818
3924
|
DatePicker,
|
|
3819
3925
|
Dialog,
|
|
3820
3926
|
DialogClose,
|
|
@@ -3855,7 +3961,7 @@ export {
|
|
|
3855
3961
|
EmptyState,
|
|
3856
3962
|
ExtensionIcon,
|
|
3857
3963
|
ExtensionLink,
|
|
3858
|
-
|
|
3964
|
+
FeedbackButton,
|
|
3859
3965
|
Form,
|
|
3860
3966
|
FormControl,
|
|
3861
3967
|
FormDescription,
|