@lessly/ui 0.17.0 → 0.19.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 +120 -3
- package/dist/index.js +279 -10
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1262,13 +1262,24 @@ interface CreateProductWindowProduct {
|
|
|
1262
1262
|
type CreateProductSubmit = {
|
|
1263
1263
|
name: string;
|
|
1264
1264
|
organizationId: string;
|
|
1265
|
-
}
|
|
1265
|
+
}
|
|
1266
|
+
/** @deprecated Emitted only by the deprecated create-new-org mode — see
|
|
1267
|
+
* `CreateProductWindowProps.selectedOrgId`. Use `OrganizationCreateScreen` instead. */
|
|
1268
|
+
| {
|
|
1266
1269
|
name: string;
|
|
1267
1270
|
organizationName: string;
|
|
1268
1271
|
};
|
|
1269
1272
|
interface CreateProductWindowProps {
|
|
1270
1273
|
organizations: CreateProductWindowOrganization[];
|
|
1271
|
-
/**
|
|
1274
|
+
/**
|
|
1275
|
+
* null => create-new-org mode.
|
|
1276
|
+
*
|
|
1277
|
+
* @deprecated The create-new-org mode is deprecated. Organization creation now goes
|
|
1278
|
+
* through `OrganizationCreateScreen`, which collects the legal details the API needs
|
|
1279
|
+
* (legal name, country of incorporation, beneficial owners) — this window only ever
|
|
1280
|
+
* sends a bare `organizationName`. Pass a real org id and let the onboarding screens
|
|
1281
|
+
* handle the org-first flow. Selecting an existing org here is unaffected.
|
|
1282
|
+
*/
|
|
1272
1283
|
selectedOrgId: string | null;
|
|
1273
1284
|
/** products of the selected org */
|
|
1274
1285
|
products: CreateProductWindowProduct[];
|
|
@@ -1280,6 +1291,13 @@ interface CreateProductWindowProps {
|
|
|
1280
1291
|
onEnterProduct: (product: CreateProductWindowProduct) => void;
|
|
1281
1292
|
onSubmit: (data: CreateProductSubmit) => void;
|
|
1282
1293
|
}
|
|
1294
|
+
/**
|
|
1295
|
+
* The legacy first-run window: pick an organization and name a product, in one panel.
|
|
1296
|
+
*
|
|
1297
|
+
* Still supported for picking an existing organization. Its **create-new-org mode**
|
|
1298
|
+
* (`selectedOrgId: null`, or an empty `organizations` list) is deprecated — org creation
|
|
1299
|
+
* now goes through `OrganizationCreateScreen`, followed by `ProductCreateScreen`.
|
|
1300
|
+
*/
|
|
1283
1301
|
declare function CreateProductWindow({ organizations, selectedOrgId, products, productsLoading, submitting, error, onOrganizationChange, onEnterProduct, onSubmit, }: CreateProductWindowProps): React$1.JSX.Element;
|
|
1284
1302
|
|
|
1285
1303
|
/** FYI / Important / Critical — the one severity vocabulary. */
|
|
@@ -1535,4 +1553,103 @@ interface OrganizationOnboardingFormProps {
|
|
|
1535
1553
|
*/
|
|
1536
1554
|
declare function OrganizationOnboardingForm({ requireSanctionsFields, onSubmit, defaultValues, submitting, serverError, violations, countries, submitLabel, onCancel, className, }: OrganizationOnboardingFormProps): React$1.JSX.Element;
|
|
1537
1555
|
|
|
1538
|
-
|
|
1556
|
+
interface OrganizationCreateScreenProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'title' | 'onSubmit'> {
|
|
1557
|
+
/** Makes the country of incorporation — and the ownership confirmation, where it is
|
|
1558
|
+
* shown — mandatory. Mirrors the server-side requirement the consumer runs under. */
|
|
1559
|
+
requireSanctionsFields: boolean;
|
|
1560
|
+
onSubmit: (payload: OrganizationOnboardingPayload) => void;
|
|
1561
|
+
defaultValues?: OrganizationOnboardingDefaults;
|
|
1562
|
+
/** Disables the submit button and swaps its label while the caller's request is in flight. */
|
|
1563
|
+
submitting?: boolean;
|
|
1564
|
+
serverError?: string | null;
|
|
1565
|
+
/** Field-level messages returned alongside a server error. */
|
|
1566
|
+
violations?: string[];
|
|
1567
|
+
/** Defaults to the built-in ISO 3166-1 alpha-2 list. */
|
|
1568
|
+
countries?: SelectOption[];
|
|
1569
|
+
submitLabel?: string;
|
|
1570
|
+
/** Renders a Cancel button in the form when provided. */
|
|
1571
|
+
onCancel?: () => void;
|
|
1572
|
+
/** Brand mark above the headline. */
|
|
1573
|
+
logo?: React$1.ReactNode;
|
|
1574
|
+
/** Rendered top-right. Defaults to the kit's own `ThemeToggle`; pass your own node to
|
|
1575
|
+
* replace it, or `null` to drop it. */
|
|
1576
|
+
themeToggle?: React$1.ReactNode;
|
|
1577
|
+
title?: React$1.ReactNode;
|
|
1578
|
+
description?: React$1.ReactNode;
|
|
1579
|
+
/** Muted footer signature. Pass `null` to hide. */
|
|
1580
|
+
footer?: React$1.ReactNode;
|
|
1581
|
+
}
|
|
1582
|
+
/**
|
|
1583
|
+
* Full-page first step of the org-first onboarding flow: the screen a user lands on when
|
|
1584
|
+
* they have no organization yet. It is the screen wrapper around
|
|
1585
|
+
* `OrganizationOnboardingForm` — presentational and self-contained, it never calls an API
|
|
1586
|
+
* and never navigates; the caller handles the outcome of `onSubmit`.
|
|
1587
|
+
*/
|
|
1588
|
+
declare function OrganizationCreateScreen({ requireSanctionsFields, onSubmit, defaultValues, submitting, serverError, violations, countries, submitLabel, onCancel, logo, themeToggle, title, description, footer, ...props }: OrganizationCreateScreenProps): React$1.JSX.Element;
|
|
1589
|
+
|
|
1590
|
+
/** One organization the user can create the product in. */
|
|
1591
|
+
interface ProductCreateScreenOrganization {
|
|
1592
|
+
id: string;
|
|
1593
|
+
name: string;
|
|
1594
|
+
}
|
|
1595
|
+
/** One product already living in the target organization. */
|
|
1596
|
+
interface ProductCreateScreenProduct {
|
|
1597
|
+
id: string;
|
|
1598
|
+
name: string;
|
|
1599
|
+
slug?: string;
|
|
1600
|
+
}
|
|
1601
|
+
/** The submit payload. The organization is implied — the screen only ever creates inside
|
|
1602
|
+
* the organization it was given. */
|
|
1603
|
+
interface ProductCreateScreenSubmit {
|
|
1604
|
+
name: string;
|
|
1605
|
+
}
|
|
1606
|
+
interface ProductCreateScreenProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'title' | 'onSubmit'> {
|
|
1607
|
+
/**
|
|
1608
|
+
* @deprecated No longer rendered. The first-product screen shows no organization
|
|
1609
|
+
* context at all, and where the user does have a choice the screen renders the
|
|
1610
|
+
* `organizations` select instead. Kept so existing callers still type-check.
|
|
1611
|
+
*/
|
|
1612
|
+
organizationName?: string;
|
|
1613
|
+
/** The organizations the user can pick between. Omit (or pass an empty list) for the
|
|
1614
|
+
* first-product screen, which shows no organization UI. Passing organizations switches
|
|
1615
|
+
* the screen to the picker layout: select on top, that org's products, then the name. */
|
|
1616
|
+
organizations?: ProductCreateScreenOrganization[];
|
|
1617
|
+
/** The organization currently selected in the picker layout. */
|
|
1618
|
+
selectedOrganizationId?: string;
|
|
1619
|
+
/** Fires with the picked organization id. Without it the select is read-only. */
|
|
1620
|
+
onOrganizationChange?: (organizationId: string) => void;
|
|
1621
|
+
/** Shows a loading note in place of the products list while the caller fetches them. */
|
|
1622
|
+
productsLoading?: boolean;
|
|
1623
|
+
onSubmit: (data: ProductCreateScreenSubmit) => void;
|
|
1624
|
+
defaultName?: string;
|
|
1625
|
+
/** Disables the submit button and swaps its label while the caller's request is in flight. */
|
|
1626
|
+
submitting?: boolean;
|
|
1627
|
+
serverError?: string | null;
|
|
1628
|
+
/** Products the organization already has. Omit (or pass an empty list) to hide the
|
|
1629
|
+
* "Your products" section entirely. */
|
|
1630
|
+
existingProducts?: ProductCreateScreenProduct[];
|
|
1631
|
+
/** Makes each existing product a button. Without it the list is read-only. */
|
|
1632
|
+
onOpenProduct?: (product: ProductCreateScreenProduct) => void;
|
|
1633
|
+
/** Heading above the existing-products list. */
|
|
1634
|
+
existingProductsLabel?: React$1.ReactNode;
|
|
1635
|
+
submitLabel?: React$1.ReactNode;
|
|
1636
|
+
/** Renders a Cancel button when provided. */
|
|
1637
|
+
onCancel?: () => void;
|
|
1638
|
+
/** Brand mark above the headline. */
|
|
1639
|
+
logo?: React$1.ReactNode;
|
|
1640
|
+
/** Rendered top-right. Defaults to the kit's own `ThemeToggle`; pass your own node to
|
|
1641
|
+
* replace it, or `null` to drop it. */
|
|
1642
|
+
themeToggle?: React$1.ReactNode;
|
|
1643
|
+
title?: React$1.ReactNode;
|
|
1644
|
+
description?: React$1.ReactNode;
|
|
1645
|
+
/** Muted footer signature. Pass `null` to hide. */
|
|
1646
|
+
footer?: React$1.ReactNode;
|
|
1647
|
+
}
|
|
1648
|
+
/**
|
|
1649
|
+
* Full-page second step of the org-first onboarding flow: create the first product inside
|
|
1650
|
+
* an organization that already exists. Presentational and self-contained — it never calls
|
|
1651
|
+
* an API and never navigates; the caller handles the outcome of `onSubmit`.
|
|
1652
|
+
*/
|
|
1653
|
+
declare function ProductCreateScreen({ organizationName: _organizationName, organizations, selectedOrganizationId, onOrganizationChange, productsLoading, onSubmit, defaultName, submitting, serverError, existingProducts, onOpenProduct, existingProductsLabel, submitLabel, onCancel, logo, themeToggle, title, description, footer, ...props }: ProductCreateScreenProps): React$1.JSX.Element;
|
|
1654
|
+
|
|
1655
|
+
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, type BeneficialOwnerPayload, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, type ButtonProps, COUNTRY_OPTIONS, 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, Code, CodeBlock, type CodeBlockProps, type CodeLang, type CodeProps, 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, type NotifClass, type NotificationAction, NotificationBell, type NotificationBellProps, NotificationCenter, type NotificationCenterProps, type NotificationClass, type NotificationDeepLink, type NotificationItem, type NotificationMute, type NotificationPreferences, type NotificationProduct, NotificationSettings, type NotificationSettingsProps, type NotificationSeverity, type NotificationSubscription, type NotificationThreshold, NotificationToast, type NotificationToastDwell, type NotificationToastProps, NotificationToaster, type NotificationToasterPosition, type NotificationToasterProps, OrgProductSwitcher, type OrgProductSwitcherAction, type OrgProductSwitcherItem, type OrgProductSwitcherProps, OrganizationCreateScreen, type OrganizationCreateScreenProps, type OrganizationOnboardingDefaults, OrganizationOnboardingForm, type OrganizationOnboardingFormProps, type OrganizationOnboardingPayload, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, type PaginationLinkProps, PaginationNext, PaginationPrevious, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, ProductCreateScreen, type ProductCreateScreenOrganization, type ProductCreateScreenProduct, type ProductCreateScreenProps, type ProductCreateScreenSubmit, 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, type Severity, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, SidebarBackHeader, type SidebarBackHeaderProps, SidebarNav, SidebarNavLink, type SidebarNavLinkProps, type SidebarNavProps, SidebarProductHeader, type SidebarProductHeaderProps, SignInScreen, type SignInScreenProps, type SignInScreenState, Skeleton, Slider, StatCard, type StatCardProps, StatusDot, type StatusDotProps, Switch, type SwitchProps, TOAST_DWELL, 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, formatRelativeAge, isKnownExtensionIcon, isNotificationSettled, navigationMenuTriggerStyle, segmentChipVariants, severityBadgeVariant, severityLabels, statusDotVariants, toggleVariants, useCarousel, useFormField, useIsMobile, useSidebar, useTheme };
|
package/dist/index.js
CHANGED
|
@@ -2446,8 +2446,15 @@ EmptyState.displayName = "EmptyState";
|
|
|
2446
2446
|
|
|
2447
2447
|
// src/components/sign-in-screen.tsx
|
|
2448
2448
|
import * as React43 from "react";
|
|
2449
|
+
|
|
2450
|
+
// src/lib/auth-surface.ts
|
|
2451
|
+
var AUTH_GLOW_BG = "radial-gradient(560px 320px at 28% 16%, var(--auth-glow-a), transparent 68%),radial-gradient(520px 340px at 78% 90%, var(--auth-glow-b), transparent 66%),var(--bg-sunken)";
|
|
2452
|
+
var AUTH_FILLED_BUTTON = "flex h-[46px] w-full items-center justify-center gap-[11px] rounded-[10px] border border-transparent bg-text-primary px-[14px] text-[14.5px] font-semibold tracking-[-0.005em] text-bg-sunken transition-opacity hover:opacity-[0.92] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-text-brand active:translate-y-px disabled:cursor-not-allowed disabled:opacity-[0.55]";
|
|
2453
|
+
var AUTH_QUIET_BUTTON = "flex h-[46px] w-full items-center justify-center gap-[11px] rounded-[10px] border border-border-default bg-transparent px-[14px] text-[14.5px] font-medium tracking-[-0.005em] text-text-secondary transition-colors hover:bg-bg-secondary focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-text-brand";
|
|
2454
|
+
var AUTH_BUTTON_SHADOW = "var(--auth-btn-shadow)";
|
|
2455
|
+
|
|
2456
|
+
// src/components/sign-in-screen.tsx
|
|
2449
2457
|
import { Fragment, jsx as jsx49, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
2450
|
-
var GLOW_BG = "radial-gradient(560px 320px at 28% 16%, var(--auth-glow-a), transparent 68%),radial-gradient(520px 340px at 78% 90%, var(--auth-glow-b), transparent 66%),var(--bg-sunken)";
|
|
2451
2458
|
var DEFAULT_TITLE = {
|
|
2452
2459
|
login: "Sign in",
|
|
2453
2460
|
forbidden: "Access restricted",
|
|
@@ -2495,7 +2502,6 @@ var RetryIcon = (props) => /* @__PURE__ */ jsxs23("svg", { width: "16", height:
|
|
|
2495
2502
|
/* @__PURE__ */ jsx49("path", { d: "M23 4v6h-6" }),
|
|
2496
2503
|
/* @__PURE__ */ jsx49("path", { d: "M20.49 15a9 9 0 1 1-2.12-9.36L23 10" })
|
|
2497
2504
|
] });
|
|
2498
|
-
var filledBtn = "flex h-[46px] w-full items-center justify-center gap-[11px] rounded-[10px] border border-transparent bg-text-primary px-[14px] text-[14.5px] font-semibold tracking-[-0.005em] text-bg-sunken transition-opacity hover:opacity-[0.92] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-text-brand active:translate-y-px disabled:cursor-not-allowed disabled:opacity-[0.55]";
|
|
2499
2505
|
var calloutBase = "mb-[22px] flex gap-[10px] rounded-[10px] border px-[13px] py-[12px] text-left text-[13px] leading-[1.5] text-text-secondary [&_code]:font-mono [&_code]:text-[12px] [&_code]:text-text-primary [&_strong]:font-semibold [&_strong]:text-text-primary";
|
|
2500
2506
|
function LockNote({ children }) {
|
|
2501
2507
|
return /* @__PURE__ */ jsxs23("div", { className: "mx-auto mt-[20px] flex flex-wrap items-center justify-center gap-[7px] text-[12px] leading-[1.4] text-text-secondary [&_code]:rounded-[5px] [&_code]:bg-bg-secondary [&_code]:px-[6px] [&_code]:py-[2px] [&_code]:font-mono [&_code]:text-[11.5px] [&_code]:text-text-secondary", children: [
|
|
@@ -2532,7 +2538,7 @@ var SignInScreen = React43.forwardRef(
|
|
|
2532
2538
|
"relative flex min-h-screen w-full items-center justify-center overflow-hidden px-6 py-12 text-text-primary",
|
|
2533
2539
|
className
|
|
2534
2540
|
),
|
|
2535
|
-
style: { background:
|
|
2541
|
+
style: { background: AUTH_GLOW_BG },
|
|
2536
2542
|
...props,
|
|
2537
2543
|
children
|
|
2538
2544
|
}
|
|
@@ -2570,8 +2576,8 @@ var SignInScreen = React43.forwardRef(
|
|
|
2570
2576
|
onClick: onGoogle,
|
|
2571
2577
|
disabled: signingIn,
|
|
2572
2578
|
"aria-busy": signingIn || void 0,
|
|
2573
|
-
className:
|
|
2574
|
-
style: { boxShadow:
|
|
2579
|
+
className: AUTH_FILLED_BUTTON,
|
|
2580
|
+
style: { boxShadow: AUTH_BUTTON_SHADOW },
|
|
2575
2581
|
children: signingIn ? /* @__PURE__ */ jsxs23(Fragment, { children: [
|
|
2576
2582
|
/* @__PURE__ */ jsx49(Spinner, { className: "size-[17px] opacity-50" }),
|
|
2577
2583
|
/* @__PURE__ */ jsx49("span", { children: signingInLabel })
|
|
@@ -2595,8 +2601,8 @@ var SignInScreen = React43.forwardRef(
|
|
|
2595
2601
|
{
|
|
2596
2602
|
type: "button",
|
|
2597
2603
|
onClick: onRetry,
|
|
2598
|
-
className:
|
|
2599
|
-
style: { boxShadow:
|
|
2604
|
+
className: AUTH_FILLED_BUTTON,
|
|
2605
|
+
style: { boxShadow: AUTH_BUTTON_SHADOW },
|
|
2600
2606
|
children: [
|
|
2601
2607
|
/* @__PURE__ */ jsx49(RetryIcon, {}),
|
|
2602
2608
|
/* @__PURE__ */ jsx49("span", { children: retryLabel })
|
|
@@ -5634,12 +5640,273 @@ function OrganizationOnboardingForm({
|
|
|
5634
5640
|
serverError,
|
|
5635
5641
|
violations && violations.length > 0 && /* @__PURE__ */ jsx79("ul", { "data-testid": "create-org-violations", className: "mt-1 list-disc pl-4", children: violations.map((violation) => /* @__PURE__ */ jsx79("li", { children: violation }, violation)) })
|
|
5636
5642
|
] }),
|
|
5637
|
-
/* @__PURE__ */ jsxs45("div", { className: "
|
|
5638
|
-
|
|
5639
|
-
|
|
5643
|
+
/* @__PURE__ */ jsxs45("div", { className: "space-y-2 pt-1", children: [
|
|
5644
|
+
/* @__PURE__ */ jsx79(
|
|
5645
|
+
"button",
|
|
5646
|
+
{
|
|
5647
|
+
type: "submit",
|
|
5648
|
+
"data-testid": "submit-create-org",
|
|
5649
|
+
disabled: !canSubmit,
|
|
5650
|
+
className: AUTH_FILLED_BUTTON,
|
|
5651
|
+
style: { boxShadow: AUTH_BUTTON_SHADOW },
|
|
5652
|
+
children: submitting ? "Creating\u2026" : submitLabel
|
|
5653
|
+
}
|
|
5654
|
+
),
|
|
5655
|
+
onCancel && /* @__PURE__ */ jsx79("button", { type: "button", onClick: onCancel, className: AUTH_QUIET_BUTTON, children: "Cancel" })
|
|
5640
5656
|
] })
|
|
5641
5657
|
] });
|
|
5642
5658
|
}
|
|
5659
|
+
|
|
5660
|
+
// src/components/onboarding-screen-shell.tsx
|
|
5661
|
+
import { jsx as jsx80, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
5662
|
+
var CARD_WIDTH = {
|
|
5663
|
+
md: "max-w-[440px]",
|
|
5664
|
+
lg: "max-w-[560px]"
|
|
5665
|
+
};
|
|
5666
|
+
function OnboardingScreenShell({
|
|
5667
|
+
logo,
|
|
5668
|
+
themeToggle = /* @__PURE__ */ jsx80(ThemeToggle, {}),
|
|
5669
|
+
title,
|
|
5670
|
+
description,
|
|
5671
|
+
footer = "Supercharged by Lessly",
|
|
5672
|
+
width = "md",
|
|
5673
|
+
children,
|
|
5674
|
+
className,
|
|
5675
|
+
...props
|
|
5676
|
+
}) {
|
|
5677
|
+
return /* @__PURE__ */ jsxs46(
|
|
5678
|
+
"div",
|
|
5679
|
+
{
|
|
5680
|
+
className: cn(
|
|
5681
|
+
"relative flex min-h-screen w-full flex-col items-center justify-center overflow-hidden px-6 py-12 text-text-primary",
|
|
5682
|
+
className
|
|
5683
|
+
),
|
|
5684
|
+
style: { background: AUTH_GLOW_BG },
|
|
5685
|
+
...props,
|
|
5686
|
+
children: [
|
|
5687
|
+
themeToggle && /* @__PURE__ */ jsx80("div", { className: "absolute right-6 top-6", children: themeToggle }),
|
|
5688
|
+
/* @__PURE__ */ jsxs46(
|
|
5689
|
+
"div",
|
|
5690
|
+
{
|
|
5691
|
+
className: cn(
|
|
5692
|
+
"relative w-full rounded-2xl bg-bg-surface px-[34px] pb-[30px] pt-[38px] text-center",
|
|
5693
|
+
CARD_WIDTH[width]
|
|
5694
|
+
),
|
|
5695
|
+
style: {
|
|
5696
|
+
border: "1px solid var(--auth-card-border)",
|
|
5697
|
+
boxShadow: "var(--auth-card-shadow)"
|
|
5698
|
+
},
|
|
5699
|
+
children: [
|
|
5700
|
+
logo && /* @__PURE__ */ jsx80("div", { className: "mb-[22px] flex items-center justify-center text-[24px] font-bold leading-none tracking-[-0.02em] text-text-primary", children: logo }),
|
|
5701
|
+
/* @__PURE__ */ jsx80(
|
|
5702
|
+
"h1",
|
|
5703
|
+
{
|
|
5704
|
+
className: cn(
|
|
5705
|
+
"text-[20px] font-semibold leading-[1.25] tracking-[-0.015em] text-text-primary",
|
|
5706
|
+
// Without a description the headline itself carries the gap to the form.
|
|
5707
|
+
description ? "mb-[8px]" : "mb-[24px]"
|
|
5708
|
+
),
|
|
5709
|
+
children: title
|
|
5710
|
+
}
|
|
5711
|
+
),
|
|
5712
|
+
description && /* @__PURE__ */ jsx80("p", { className: "mx-auto mb-[24px] max-w-[320px] text-[13.5px] leading-[1.5] text-text-secondary", children: description }),
|
|
5713
|
+
/* @__PURE__ */ jsx80("div", { className: "text-left", children }),
|
|
5714
|
+
footer != null && /* @__PURE__ */ jsx80("div", { className: "mt-[24px] text-[11px] tracking-[0.005em] text-text-tertiary", children: footer })
|
|
5715
|
+
]
|
|
5716
|
+
}
|
|
5717
|
+
)
|
|
5718
|
+
]
|
|
5719
|
+
}
|
|
5720
|
+
);
|
|
5721
|
+
}
|
|
5722
|
+
|
|
5723
|
+
// src/components/organization-create-screen.tsx
|
|
5724
|
+
import { jsx as jsx81 } from "react/jsx-runtime";
|
|
5725
|
+
function OrganizationCreateScreen({
|
|
5726
|
+
requireSanctionsFields,
|
|
5727
|
+
onSubmit,
|
|
5728
|
+
defaultValues,
|
|
5729
|
+
submitting,
|
|
5730
|
+
serverError,
|
|
5731
|
+
violations,
|
|
5732
|
+
countries,
|
|
5733
|
+
submitLabel,
|
|
5734
|
+
onCancel,
|
|
5735
|
+
logo,
|
|
5736
|
+
themeToggle,
|
|
5737
|
+
title = "Create your organization",
|
|
5738
|
+
description = "An organization is the home for your team and products",
|
|
5739
|
+
footer,
|
|
5740
|
+
...props
|
|
5741
|
+
}) {
|
|
5742
|
+
return /* @__PURE__ */ jsx81(
|
|
5743
|
+
OnboardingScreenShell,
|
|
5744
|
+
{
|
|
5745
|
+
logo,
|
|
5746
|
+
themeToggle,
|
|
5747
|
+
title,
|
|
5748
|
+
description,
|
|
5749
|
+
footer,
|
|
5750
|
+
width: "lg",
|
|
5751
|
+
...props,
|
|
5752
|
+
children: /* @__PURE__ */ jsx81(
|
|
5753
|
+
OrganizationOnboardingForm,
|
|
5754
|
+
{
|
|
5755
|
+
requireSanctionsFields,
|
|
5756
|
+
onSubmit,
|
|
5757
|
+
defaultValues,
|
|
5758
|
+
submitting,
|
|
5759
|
+
serverError,
|
|
5760
|
+
violations,
|
|
5761
|
+
countries,
|
|
5762
|
+
submitLabel,
|
|
5763
|
+
onCancel
|
|
5764
|
+
}
|
|
5765
|
+
)
|
|
5766
|
+
}
|
|
5767
|
+
);
|
|
5768
|
+
}
|
|
5769
|
+
|
|
5770
|
+
// src/components/product-create-screen.tsx
|
|
5771
|
+
import * as React67 from "react";
|
|
5772
|
+
import { jsx as jsx82, jsxs as jsxs47 } from "react/jsx-runtime";
|
|
5773
|
+
var productRow = "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";
|
|
5774
|
+
function ProductCreateScreen({
|
|
5775
|
+
// Destructured only to keep it out of `...props`, which is spread onto a <div>.
|
|
5776
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
5777
|
+
organizationName: _organizationName,
|
|
5778
|
+
organizations,
|
|
5779
|
+
selectedOrganizationId,
|
|
5780
|
+
onOrganizationChange,
|
|
5781
|
+
productsLoading,
|
|
5782
|
+
onSubmit,
|
|
5783
|
+
defaultName = "",
|
|
5784
|
+
submitting,
|
|
5785
|
+
serverError,
|
|
5786
|
+
existingProducts,
|
|
5787
|
+
onOpenProduct,
|
|
5788
|
+
existingProductsLabel = "Your products",
|
|
5789
|
+
submitLabel = "Create product",
|
|
5790
|
+
onCancel,
|
|
5791
|
+
logo,
|
|
5792
|
+
themeToggle,
|
|
5793
|
+
title = "Create your product",
|
|
5794
|
+
description = "A product is where your data, extensions and team access live",
|
|
5795
|
+
footer,
|
|
5796
|
+
...props
|
|
5797
|
+
}) {
|
|
5798
|
+
const [name, setName] = React67.useState(defaultName);
|
|
5799
|
+
const submittingRef = React67.useRef(false);
|
|
5800
|
+
const trimmed = name.trim();
|
|
5801
|
+
const canSubmit = trimmed !== "" && !submitting;
|
|
5802
|
+
React67.useEffect(() => {
|
|
5803
|
+
submittingRef.current = false;
|
|
5804
|
+
}, [name, submitting, serverError]);
|
|
5805
|
+
const handleSubmit = (event) => {
|
|
5806
|
+
event.preventDefault();
|
|
5807
|
+
if (!canSubmit || submittingRef.current) return;
|
|
5808
|
+
submittingRef.current = true;
|
|
5809
|
+
onSubmit({ name: trimmed });
|
|
5810
|
+
};
|
|
5811
|
+
const products = existingProducts ?? [];
|
|
5812
|
+
const orgs = organizations ?? [];
|
|
5813
|
+
const pickerLayout = orgs.length > 0;
|
|
5814
|
+
const productList = /* @__PURE__ */ jsx82("ul", { className: "flex flex-col gap-1", children: products.map((product) => /* @__PURE__ */ jsx82("li", { children: onOpenProduct ? /* @__PURE__ */ jsxs47(
|
|
5815
|
+
"button",
|
|
5816
|
+
{
|
|
5817
|
+
type: "button",
|
|
5818
|
+
"data-testid": `existing-product-${product.id}`,
|
|
5819
|
+
onClick: () => onOpenProduct(product),
|
|
5820
|
+
className: cn(
|
|
5821
|
+
productRow,
|
|
5822
|
+
"hover:bg-bg-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus"
|
|
5823
|
+
),
|
|
5824
|
+
children: [
|
|
5825
|
+
/* @__PURE__ */ jsx82("span", { className: "truncate", children: product.name }),
|
|
5826
|
+
product.slug && /* @__PURE__ */ jsx82("span", { className: "ml-2 truncate text-text-tertiary", children: product.slug })
|
|
5827
|
+
]
|
|
5828
|
+
}
|
|
5829
|
+
) : /* @__PURE__ */ jsxs47("div", { className: productRow, children: [
|
|
5830
|
+
/* @__PURE__ */ jsx82("span", { className: "truncate", children: product.name }),
|
|
5831
|
+
product.slug && /* @__PURE__ */ jsx82("span", { className: "ml-2 truncate text-text-tertiary", children: product.slug })
|
|
5832
|
+
] }) }, product.id)) });
|
|
5833
|
+
return /* @__PURE__ */ jsxs47(
|
|
5834
|
+
OnboardingScreenShell,
|
|
5835
|
+
{
|
|
5836
|
+
logo,
|
|
5837
|
+
themeToggle,
|
|
5838
|
+
title,
|
|
5839
|
+
description,
|
|
5840
|
+
footer,
|
|
5841
|
+
...props,
|
|
5842
|
+
children: [
|
|
5843
|
+
pickerLayout && /* @__PURE__ */ jsxs47("div", { className: "mb-4 space-y-4", children: [
|
|
5844
|
+
/* @__PURE__ */ jsxs47("div", { className: "space-y-1.5", children: [
|
|
5845
|
+
/* @__PURE__ */ jsx82(Label2, { htmlFor: "create-product-org-select", children: "Organization" }),
|
|
5846
|
+
/* @__PURE__ */ jsx82(
|
|
5847
|
+
Select,
|
|
5848
|
+
{
|
|
5849
|
+
id: "create-product-org-select",
|
|
5850
|
+
"data-testid": "create-product-org-select",
|
|
5851
|
+
"aria-label": "Organization",
|
|
5852
|
+
value: selectedOrganizationId,
|
|
5853
|
+
onValueChange: (value) => onOrganizationChange?.(value),
|
|
5854
|
+
options: orgs.map((org) => ({ value: org.id, label: org.name })),
|
|
5855
|
+
optionTestId: (value) => `create-product-org-option-${value}`,
|
|
5856
|
+
placeholder: "Select an organization\u2026"
|
|
5857
|
+
}
|
|
5858
|
+
)
|
|
5859
|
+
] }),
|
|
5860
|
+
/* @__PURE__ */ jsxs47("div", { "data-testid": "existing-products", className: "space-y-1.5", children: [
|
|
5861
|
+
/* @__PURE__ */ jsx82(Label2, { children: existingProductsLabel }),
|
|
5862
|
+
productsLoading ? /* @__PURE__ */ jsx82("p", { className: "text-sm text-text-tertiary", children: "Loading products\u2026" }) : products.length === 0 ? /* @__PURE__ */ jsx82("p", { className: "text-sm text-text-tertiary", children: "No products yet." }) : productList
|
|
5863
|
+
] })
|
|
5864
|
+
] }),
|
|
5865
|
+
/* @__PURE__ */ jsxs47("form", { onSubmit: handleSubmit, className: "space-y-4", noValidate: true, children: [
|
|
5866
|
+
/* @__PURE__ */ jsxs47("div", { className: "space-y-1.5", children: [
|
|
5867
|
+
/* @__PURE__ */ jsx82(Label2, { htmlFor: "create-product-name", children: "Product name" }),
|
|
5868
|
+
/* @__PURE__ */ jsx82(
|
|
5869
|
+
Input,
|
|
5870
|
+
{
|
|
5871
|
+
id: "create-product-name",
|
|
5872
|
+
"data-testid": "create-product-input",
|
|
5873
|
+
value: name,
|
|
5874
|
+
onChange: (event) => setName(event.target.value),
|
|
5875
|
+
placeholder: "My product"
|
|
5876
|
+
}
|
|
5877
|
+
)
|
|
5878
|
+
] }),
|
|
5879
|
+
serverError && /* @__PURE__ */ jsx82(InlineError, { children: serverError }),
|
|
5880
|
+
/* @__PURE__ */ jsxs47("div", { className: "space-y-2 pt-1", children: [
|
|
5881
|
+
/* @__PURE__ */ jsx82(
|
|
5882
|
+
"button",
|
|
5883
|
+
{
|
|
5884
|
+
type: "submit",
|
|
5885
|
+
"data-testid": "submit-create-product",
|
|
5886
|
+
disabled: !canSubmit,
|
|
5887
|
+
className: AUTH_FILLED_BUTTON,
|
|
5888
|
+
style: { boxShadow: AUTH_BUTTON_SHADOW },
|
|
5889
|
+
children: submitting ? "Creating\u2026" : submitLabel
|
|
5890
|
+
}
|
|
5891
|
+
),
|
|
5892
|
+
onCancel && /* @__PURE__ */ jsx82("button", { type: "button", onClick: onCancel, className: AUTH_QUIET_BUTTON, children: "Cancel" })
|
|
5893
|
+
] })
|
|
5894
|
+
] }),
|
|
5895
|
+
!pickerLayout && products.length > 0 && /* @__PURE__ */ jsxs47(
|
|
5896
|
+
"div",
|
|
5897
|
+
{
|
|
5898
|
+
"data-testid": "existing-products",
|
|
5899
|
+
className: "mt-6 space-y-2 border-t border-border-default pt-5",
|
|
5900
|
+
children: [
|
|
5901
|
+
/* @__PURE__ */ jsx82(Label2, { children: existingProductsLabel }),
|
|
5902
|
+
productList
|
|
5903
|
+
]
|
|
5904
|
+
}
|
|
5905
|
+
)
|
|
5906
|
+
]
|
|
5907
|
+
}
|
|
5908
|
+
);
|
|
5909
|
+
}
|
|
5643
5910
|
export {
|
|
5644
5911
|
Accordion,
|
|
5645
5912
|
AccordionContent,
|
|
@@ -5817,6 +6084,7 @@ export {
|
|
|
5817
6084
|
NotificationToast,
|
|
5818
6085
|
NotificationToaster,
|
|
5819
6086
|
OrgProductSwitcher,
|
|
6087
|
+
OrganizationCreateScreen,
|
|
5820
6088
|
OrganizationOnboardingForm,
|
|
5821
6089
|
Pagination,
|
|
5822
6090
|
PaginationContent,
|
|
@@ -5829,6 +6097,7 @@ export {
|
|
|
5829
6097
|
PopoverAnchor,
|
|
5830
6098
|
PopoverContent,
|
|
5831
6099
|
PopoverTrigger,
|
|
6100
|
+
ProductCreateScreen,
|
|
5832
6101
|
Progress,
|
|
5833
6102
|
RadioGroup2 as RadioGroup,
|
|
5834
6103
|
RadioGroupItem,
|