@lessly/ui 0.18.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 CHANGED
@@ -1587,6 +1587,11 @@ interface OrganizationCreateScreenProps extends Omit<React$1.HTMLAttributes<HTML
1587
1587
  */
1588
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
1589
 
1590
+ /** One organization the user can create the product in. */
1591
+ interface ProductCreateScreenOrganization {
1592
+ id: string;
1593
+ name: string;
1594
+ }
1590
1595
  /** One product already living in the target organization. */
1591
1596
  interface ProductCreateScreenProduct {
1592
1597
  id: string;
@@ -1599,8 +1604,22 @@ interface ProductCreateScreenSubmit {
1599
1604
  name: string;
1600
1605
  }
1601
1606
  interface ProductCreateScreenProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'title' | 'onSubmit'> {
1602
- /** The organization the new product lands in. Shown so the user can see where they are. */
1603
- organizationName: string;
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;
1604
1623
  onSubmit: (data: ProductCreateScreenSubmit) => void;
1605
1624
  defaultName?: string;
1606
1625
  /** Disables the submit button and swaps its label while the caller's request is in flight. */
@@ -1631,6 +1650,6 @@ interface ProductCreateScreenProps extends Omit<React$1.HTMLAttributes<HTMLDivEl
1631
1650
  * an organization that already exists. Presentational and self-contained — it never calls
1632
1651
  * an API and never navigates; the caller handles the outcome of `onSubmit`.
1633
1652
  */
1634
- declare function ProductCreateScreen({ organizationName, onSubmit, defaultName, submitting, serverError, existingProducts, onOpenProduct, existingProductsLabel, submitLabel, onCancel, logo, themeToggle, title, description, footer, ...props }: ProductCreateScreenProps): React$1.JSX.Element;
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;
1635
1654
 
1636
- 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 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 };
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: GLOW_BG },
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: filledBtn,
2574
- style: { boxShadow: "var(--auth-btn-shadow)" },
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: filledBtn,
2599
- style: { boxShadow: "var(--auth-btn-shadow)" },
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,16 +5640,25 @@ 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: "flex justify-end gap-2", children: [
5638
- onCancel && /* @__PURE__ */ jsx79(Button, { type: "button", variant: "outline", onClick: onCancel, children: "Cancel" }),
5639
- /* @__PURE__ */ jsx79(Button, { type: "submit", "data-testid": "submit-create-org", disabled: !canSubmit, children: submitting ? "Creating\u2026" : submitLabel })
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
  }
5643
5659
 
5644
5660
  // src/components/onboarding-screen-shell.tsx
5645
5661
  import { jsx as jsx80, jsxs as jsxs46 } from "react/jsx-runtime";
5646
- var GLOW_BG2 = "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)";
5647
5662
  var CARD_WIDTH = {
5648
5663
  md: "max-w-[440px]",
5649
5664
  lg: "max-w-[560px]"
@@ -5666,29 +5681,40 @@ function OnboardingScreenShell({
5666
5681
  "relative flex min-h-screen w-full flex-col items-center justify-center overflow-hidden px-6 py-12 text-text-primary",
5667
5682
  className
5668
5683
  ),
5669
- style: { background: GLOW_BG2 },
5684
+ style: { background: AUTH_GLOW_BG },
5670
5685
  ...props,
5671
5686
  children: [
5672
5687
  themeToggle && /* @__PURE__ */ jsx80("div", { className: "absolute right-6 top-6", children: themeToggle }),
5673
- /* @__PURE__ */ jsxs46("div", { className: cn("w-full", CARD_WIDTH[width]), children: [
5674
- /* @__PURE__ */ jsxs46("div", { className: "mb-[26px] text-center", children: [
5675
- logo && /* @__PURE__ */ jsx80("div", { className: "mb-[20px] text-[24px] font-bold leading-none tracking-[-0.02em] text-text-primary", children: logo }),
5676
- /* @__PURE__ */ jsx80("h1", { className: "mb-[8px] text-[22px] font-semibold leading-[1.25] tracking-[-0.015em] text-text-primary", children: title }),
5677
- description && /* @__PURE__ */ jsx80("p", { className: "mx-auto max-w-[380px] text-[13.5px] leading-[1.5] text-text-secondary", children: description })
5678
- ] }),
5679
- /* @__PURE__ */ jsx80(
5680
- "div",
5681
- {
5682
- className: "rounded-2xl bg-bg-surface px-[30px] pb-[28px] pt-[28px]",
5683
- style: {
5684
- border: "1px solid var(--auth-card-border)",
5685
- boxShadow: "var(--auth-card-shadow)"
5686
- },
5687
- children
5688
- }
5689
- ),
5690
- footer != null && /* @__PURE__ */ jsx80("div", { className: "mt-[24px] text-center text-[11px] tracking-[0.005em] text-text-tertiary", children: footer })
5691
- ] })
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
+ )
5692
5718
  ]
5693
5719
  }
5694
5720
  );
@@ -5746,7 +5772,13 @@ import * as React67 from "react";
5746
5772
  import { jsx as jsx82, jsxs as jsxs47 } from "react/jsx-runtime";
5747
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";
5748
5774
  function ProductCreateScreen({
5749
- organizationName,
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,
5750
5782
  onSubmit,
5751
5783
  defaultName = "",
5752
5784
  submitting,
@@ -5777,6 +5809,27 @@ function ProductCreateScreen({
5777
5809
  onSubmit({ name: trimmed });
5778
5810
  };
5779
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)) });
5780
5833
  return /* @__PURE__ */ jsxs47(
5781
5834
  OnboardingScreenShell,
5782
5835
  {
@@ -5787,18 +5840,29 @@ function ProductCreateScreen({
5787
5840
  footer,
5788
5841
  ...props,
5789
5842
  children: [
5790
- /* @__PURE__ */ jsxs47("form", { onSubmit: handleSubmit, className: "space-y-4", noValidate: true, children: [
5843
+ pickerLayout && /* @__PURE__ */ jsxs47("div", { className: "mb-4 space-y-4", children: [
5791
5844
  /* @__PURE__ */ jsxs47("div", { className: "space-y-1.5", children: [
5792
- /* @__PURE__ */ jsx82("span", { className: "text-sm font-medium leading-none text-text-primary", children: "Organization" }),
5845
+ /* @__PURE__ */ jsx82(Label2, { htmlFor: "create-product-org-select", children: "Organization" }),
5793
5846
  /* @__PURE__ */ jsx82(
5794
- "p",
5847
+ Select,
5795
5848
  {
5796
- "data-testid": "create-product-organization",
5797
- className: "truncate rounded-md border border-border-default bg-bg-secondary px-3 py-2 text-sm text-text-secondary",
5798
- children: organizationName
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"
5799
5857
  }
5800
5858
  )
5801
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: [
5802
5866
  /* @__PURE__ */ jsxs47("div", { className: "space-y-1.5", children: [
5803
5867
  /* @__PURE__ */ jsx82(Label2, { htmlFor: "create-product-name", children: "Product name" }),
5804
5868
  /* @__PURE__ */ jsx82(
@@ -5813,33 +5877,32 @@ function ProductCreateScreen({
5813
5877
  )
5814
5878
  ] }),
5815
5879
  serverError && /* @__PURE__ */ jsx82(InlineError, { children: serverError }),
5816
- /* @__PURE__ */ jsxs47("div", { className: "flex justify-end gap-2", children: [
5817
- onCancel && /* @__PURE__ */ jsx82(Button, { type: "button", variant: "outline", onClick: onCancel, children: "Cancel" }),
5818
- /* @__PURE__ */ jsx82(Button, { type: "submit", "data-testid": "submit-create-product", disabled: !canSubmit, children: submitting ? "Creating\u2026" : submitLabel })
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" })
5819
5893
  ] })
5820
5894
  ] }),
5821
- products.length > 0 && /* @__PURE__ */ jsxs47("div", { "data-testid": "existing-products", className: "mt-6 space-y-2 border-t border-border-default pt-5", children: [
5822
- /* @__PURE__ */ jsx82(Label2, { children: existingProductsLabel }),
5823
- /* @__PURE__ */ jsx82("ul", { className: "flex flex-col gap-1", children: products.map((product) => /* @__PURE__ */ jsx82("li", { children: onOpenProduct ? /* @__PURE__ */ jsxs47(
5824
- "button",
5825
- {
5826
- type: "button",
5827
- "data-testid": `existing-product-${product.id}`,
5828
- onClick: () => onOpenProduct(product),
5829
- className: cn(
5830
- productRow,
5831
- "hover:bg-bg-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus"
5832
- ),
5833
- children: [
5834
- /* @__PURE__ */ jsx82("span", { className: "truncate", children: product.name }),
5835
- product.slug && /* @__PURE__ */ jsx82("span", { className: "ml-2 truncate text-text-tertiary", children: product.slug })
5836
- ]
5837
- }
5838
- ) : /* @__PURE__ */ jsxs47("div", { className: productRow, children: [
5839
- /* @__PURE__ */ jsx82("span", { className: "truncate", children: product.name }),
5840
- product.slug && /* @__PURE__ */ jsx82("span", { className: "ml-2 truncate text-text-tertiary", children: product.slug })
5841
- ] }) }, product.id)) })
5842
- ] })
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
+ )
5843
5906
  ]
5844
5907
  }
5845
5908
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lessly/ui",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "description": "Lessly design system — shared UI primitives, tokens, and theme",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.30.3",