@ceebee/ui 0.3.3 → 0.4.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/client.d.ts CHANGED
@@ -596,15 +596,25 @@ interface MenuItem {
596
596
  checked?: boolean;
597
597
  onSelect?: () => void;
598
598
  }
599
- interface DropdownMenuProps {
600
- trigger: ReactElement;
599
+ interface MenuSection {
600
+ label?: ReactNode;
601
601
  items: MenuItem[];
602
+ }
603
+ interface DropdownMenuBaseProps {
604
+ trigger: ReactElement;
602
605
  align?: 'start' | 'center' | 'end';
603
606
  side?: 'top' | 'right' | 'bottom' | 'left';
604
607
  className?: string;
605
608
  }
609
+ type DropdownMenuProps = DropdownMenuBaseProps & ({
610
+ items: MenuItem[];
611
+ sections?: never;
612
+ } | {
613
+ items?: never;
614
+ sections: MenuSection[];
615
+ });
606
616
  /** Typeahead, roving focus, and dismissal are Base UI's; the surface and the rhythm are ours. */
607
- declare function DropdownMenu({ trigger, items, align, side, className }: DropdownMenuProps): react.JSX.Element;
617
+ declare function DropdownMenu({ trigger, items, sections, align, side, className }: DropdownMenuProps): react.JSX.Element;
608
618
 
609
619
  interface NavItem {
610
620
  label: ReactNode;
@@ -929,4 +939,4 @@ interface StaggerProps {
929
939
  /** Wraps each child in a Reveal with an increasing delay — the list arrives, it does not pop. */
930
940
  declare function Stagger({ children, step, from, onView, className }: StaggerProps): react.JSX.Element;
931
941
 
932
- export { Alert, type AlertProps, type Align, type AutoplayConditions, Button, type ButtonProps, Carousel, type CarouselProps, type CarouselSkeletonProps, type CarouselSlideProps, Checkbox, type CheckboxProps, Checklist, type ChecklistProps, type ChecklistTask, Coachmark, type CoachmarkProps, type Column, Combobox, type ComboboxOption, type ComboboxProps, type Command, CommandPalette, type CommandPaletteProps, DEFAULT_LABELS, DataTable, type DataTableProps, type DataTableSkeletonProps, DateInput, type DateInputProps, type DayCell, Dialog, DialogClose, type DialogProps, DropdownMenu, type DropdownMenuProps, type DurationToken, Field, type FieldProps, FileDrop, type FileDropProps, type FileRules, Image, type ImageProps, type Labels, LabelsProvider, type LabelsProviderProps, type MenuItem, type MotionHelpers, MotionProvider, type MotionProviderProps, type MotionSettings, type NavItem, type NavSection, type NumberBounds, NumberInput, type NumberInputProps, type PageRange, Pagination, type PaginationProps, type PaletteCommand, Popover, type PopoverProps, RadioGroup, type RadioGroupProps, type RadioOption, type RankedCommand, type Rejection, Reveal, type RevealProps, type SeenStore, Select, type SelectOption, type SelectProps, type Side, Sidebar, type SidebarProps, type SortDirection, type SortState, type SpringPreset, Stagger, type StaggerProps, type StepTarget, Switch, type SwitchProps, type TabItem, Tabs, type TabsProps, TextInput, type TextInputProps, Textarea, type TextareaProps, type ThemeChoice, ThemeProvider, TimeInput, type TimeInputProps, type TimeValue, type ToastOptions, type ToastPosition, ToastProvider, type ToastProviderProps, Tooltip, type TooltipProps, TopBar, type TopBarProps, Tour, type TourAction, type TourProps, type TourState, type TourStatus, type TourStep, ariaSortFor, canStep, clamp, decimalPlaces, describeAccept, filterCommands, formatISO, formatTime, groupCommands, hasEnded, initialTourState, isOutOfRange, isSameDay, isTimeOutOfRange, matchesAccept, monthMatrix, nextSort, pageRange, parseDateInput, parseNumber, parseTime, partitionFiles, rankCommand, resolveTarget, shouldAutoplay, startOfDay, stepBy, timeOptions, timeToMinutes, tourReducer, useFieldWiring, useLabels, useMotionSettings, useTheme, useToast };
942
+ export { Alert, type AlertProps, type Align, type AutoplayConditions, Button, type ButtonProps, Carousel, type CarouselProps, type CarouselSkeletonProps, type CarouselSlideProps, Checkbox, type CheckboxProps, Checklist, type ChecklistProps, type ChecklistTask, Coachmark, type CoachmarkProps, type Column, Combobox, type ComboboxOption, type ComboboxProps, type Command, CommandPalette, type CommandPaletteProps, DEFAULT_LABELS, DataTable, type DataTableProps, type DataTableSkeletonProps, DateInput, type DateInputProps, type DayCell, Dialog, DialogClose, type DialogProps, DropdownMenu, type DropdownMenuProps, type DurationToken, Field, type FieldProps, FileDrop, type FileDropProps, type FileRules, Image, type ImageProps, type Labels, LabelsProvider, type LabelsProviderProps, type MenuItem, type MenuSection, type MotionHelpers, MotionProvider, type MotionProviderProps, type MotionSettings, type NavItem, type NavSection, type NumberBounds, NumberInput, type NumberInputProps, type PageRange, Pagination, type PaginationProps, type PaletteCommand, Popover, type PopoverProps, RadioGroup, type RadioGroupProps, type RadioOption, type RankedCommand, type Rejection, Reveal, type RevealProps, type SeenStore, Select, type SelectOption, type SelectProps, type Side, Sidebar, type SidebarProps, type SortDirection, type SortState, type SpringPreset, Stagger, type StaggerProps, type StepTarget, Switch, type SwitchProps, type TabItem, Tabs, type TabsProps, TextInput, type TextInputProps, Textarea, type TextareaProps, type ThemeChoice, ThemeProvider, TimeInput, type TimeInputProps, type TimeValue, type ToastOptions, type ToastPosition, ToastProvider, type ToastProviderProps, Tooltip, type TooltipProps, TopBar, type TopBarProps, Tour, type TourAction, type TourProps, type TourState, type TourStatus, type TourStep, ariaSortFor, canStep, clamp, decimalPlaces, describeAccept, filterCommands, formatISO, formatTime, groupCommands, hasEnded, initialTourState, isOutOfRange, isSameDay, isTimeOutOfRange, matchesAccept, monthMatrix, nextSort, pageRange, parseDateInput, parseNumber, parseTime, partitionFiles, rankCommand, resolveTarget, shouldAutoplay, startOfDay, stepBy, timeOptions, timeToMinutes, tourReducer, useFieldWiring, useLabels, useMotionSettings, useTheme, useToast };
package/dist/client.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { createContext, forwardRef, useContext, useMemo, useState, useRef, useEffect, useCallback, useId, useReducer, Children } from 'react';
3
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
+ import { createContext, forwardRef, useContext, useMemo, useState, useRef, useEffect, useCallback, useId, Fragment, useReducer, Children } from 'react';
3
+ import { jsxs, jsx, Fragment as Fragment$1 } from 'react/jsx-runtime';
4
4
  import { motion } from 'motion/react';
5
5
  import { Select as Select$1 } from '@base-ui/react/select';
6
6
  import { ChevronLeft, ChevronRight, ChevronsUpDown, Check, Minus, X, CalendarDays, Clock, Upload, Plus, Search, PanelLeftOpen, PanelLeftClose, ArrowUp, ArrowDown, XCircle, AlertTriangle, CheckCircle2, Info } from 'lucide-react';
@@ -1371,26 +1371,33 @@ function Tabs({ items, value, defaultValue, onValueChange, variant = "underline"
1371
1371
  }
1372
1372
  );
1373
1373
  }
1374
- function DropdownMenu({ trigger, items, align = "end", side = "bottom", className }) {
1374
+ function DropdownMenu({ trigger, items, sections, align = "end", side = "bottom", className }) {
1375
+ const groups = sections ?? [{ items }];
1375
1376
  return /* @__PURE__ */ jsxs(Menu.Root, { children: [
1376
1377
  /* @__PURE__ */ jsx(Menu.Trigger, { render: trigger }),
1377
- /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, { side, align, sideOffset: 6, children: /* @__PURE__ */ jsx(Menu.Popup, { className: cn("cb-menu", className), children: items.map(
1378
- (item, index) => item.separator ? /* @__PURE__ */ jsx(Menu.Separator, { className: "cb-menu__separator" }, `separator-${index}`) : /* @__PURE__ */ jsxs(
1379
- Menu.Item,
1380
- {
1381
- className: "cb-menu__item",
1382
- "data-tone": item.tone,
1383
- disabled: item.disabled,
1384
- onClick: item.onSelect,
1385
- children: [
1386
- /* @__PURE__ */ jsx("span", { className: "cb-menu__icon", children: item.checked ? /* @__PURE__ */ jsx(Check, { size: 14 }) : item.icon }),
1387
- /* @__PURE__ */ jsx("span", { className: "cb-menu__label", children: item.label }),
1388
- item.shortcut ? /* @__PURE__ */ jsx("kbd", { className: "cb-menu__shortcut", children: item.shortcut }) : null
1389
- ]
1390
- },
1391
- `${String(item.label)}-${index}`
1392
- )
1393
- ) }) }) })
1378
+ /* @__PURE__ */ jsx(Menu.Portal, { children: /* @__PURE__ */ jsx(Menu.Positioner, { side, align, sideOffset: 6, children: /* @__PURE__ */ jsx(Menu.Popup, { className: cn("cb-menu", className), children: groups.map((section, sectionIndex) => /* @__PURE__ */ jsxs(Fragment, { children: [
1379
+ sectionIndex > 0 ? /* @__PURE__ */ jsx(Menu.Separator, { className: "cb-menu__separator" }) : null,
1380
+ /* @__PURE__ */ jsxs(Menu.Group, { className: "cb-menu__group", children: [
1381
+ section.label ? /* @__PURE__ */ jsx(Menu.GroupLabel, { className: "cb-menu__group-label", children: section.label }) : null,
1382
+ section.items.map(
1383
+ (item, itemIndex) => item.separator ? /* @__PURE__ */ jsx(Menu.Separator, { className: "cb-menu__separator" }, `separator-${itemIndex}`) : /* @__PURE__ */ jsxs(
1384
+ Menu.Item,
1385
+ {
1386
+ className: "cb-menu__item",
1387
+ "data-tone": item.tone,
1388
+ disabled: item.disabled,
1389
+ onClick: item.onSelect,
1390
+ children: [
1391
+ /* @__PURE__ */ jsx("span", { className: "cb-menu__icon", children: item.checked ? /* @__PURE__ */ jsx(Check, { size: 14 }) : item.icon }),
1392
+ /* @__PURE__ */ jsx("span", { className: "cb-menu__label", children: item.label }),
1393
+ item.shortcut ? /* @__PURE__ */ jsx("kbd", { className: "cb-menu__shortcut", children: item.shortcut }) : null
1394
+ ]
1395
+ },
1396
+ `${String(item.label)}-${itemIndex}`
1397
+ )
1398
+ )
1399
+ ] })
1400
+ ] }, `section-${sectionIndex}`)) }) }) })
1394
1401
  ] });
1395
1402
  }
1396
1403
  var hasActiveChild = (item) => Boolean(item.items?.some((child) => child.active));
@@ -1434,7 +1441,7 @@ function SidebarEntry({ item, collapsed }) {
1434
1441
  if (collapsed) {
1435
1442
  return /* @__PURE__ */ jsx(Flyout, { label: item.label, items: children, children: /* @__PURE__ */ jsx(SidebarRow, { item: { ...item, active: item.active || hasActiveChild(item) }, collapsed: true }) });
1436
1443
  }
1437
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1444
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
1438
1445
  /* @__PURE__ */ jsxs(
1439
1446
  "button",
1440
1447
  {
@@ -1455,7 +1462,7 @@ function SidebarEntry({ item, collapsed }) {
1455
1462
  ] });
1456
1463
  }
1457
1464
  function SidebarRow({ item, collapsed, nested }) {
1458
- const content = /* @__PURE__ */ jsxs(Fragment, { children: [
1465
+ const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
1459
1466
  item.icon ? /* @__PURE__ */ jsx("span", { className: "cb-sidebar__icon", children: item.icon }) : null,
1460
1467
  /* @__PURE__ */ jsx("span", { className: "cb-sidebar__label", children: item.label }),
1461
1468
  item.adornment && !collapsed ? /* @__PURE__ */ jsx("span", { className: "cb-sidebar__adornment", children: item.adornment }) : null
@@ -1883,7 +1890,7 @@ function Coachmark({
1883
1890
  const labels = useLabels();
1884
1891
  const rect = useAnchorRect(anchor, open && spotlight !== false);
1885
1892
  const padding = typeof spotlight === "number" ? spotlight : 8;
1886
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1893
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [
1887
1894
  rect ? /* @__PURE__ */ jsx(
1888
1895
  "div",
1889
1896
  {
@@ -2058,7 +2065,7 @@ function Tour({ id, steps, open = false, onOpenChange, seenStore, onFinish, onSk
2058
2065
  spotlight: step.spotlight,
2059
2066
  progress: { current: state.index + 1, total: steps.length },
2060
2067
  onDismiss: skip,
2061
- actions: /* @__PURE__ */ jsxs(Fragment, { children: [
2068
+ actions: /* @__PURE__ */ jsxs(Fragment$1, { children: [
2062
2069
  state.index > 0 ? /* @__PURE__ */ jsx(Button, { size: "sm", variant: "ghost", tone: "neutral", onClick: () => rawDispatch({ type: "prev" }), children: text2.back }) : /* @__PURE__ */ jsx(Button, { size: "sm", variant: "ghost", tone: "neutral", onClick: skip, children: text2.skip }),
2063
2070
  /* @__PURE__ */ jsx(Button, { size: "sm", onClick: () => rawDispatch({ type: "next" }), children: isLast ? text2.done : text2.next })
2064
2071
  ] }),
package/dist/styles.css CHANGED
@@ -2106,7 +2106,7 @@ html, body { background: var(--cb-bg); color: var(--cb-fg); }
2106
2106
  /* nav/nav.css */
2107
2107
  .cb-menu {
2108
2108
  box-sizing: border-box;
2109
- min-width: 12rem;
2109
+ min-width: 14rem;
2110
2110
  padding: var(--cb-space-1);
2111
2111
  background: var(--cb-surface-raised);
2112
2112
  border: var(--cb-border-width) solid var(--cb-border);
@@ -2118,6 +2118,14 @@ html, body { background: var(--cb-bg); color: var(--cb-fg); }
2118
2118
  transition: opacity var(--cb-duration-fast) var(--cb-ease-entrance),
2119
2119
  transform var(--cb-duration-fast) var(--cb-ease-entrance);
2120
2120
  }
2121
+ .cb-menu__group-label {
2122
+ padding: var(--cb-space-2) var(--cb-space-2) var(--cb-space-1);
2123
+ color: var(--cb-fg-subtle);
2124
+ font-size: var(--cb-text-xs);
2125
+ font-weight: var(--cb-weight-semibold);
2126
+ letter-spacing: 0.06em;
2127
+ text-transform: uppercase;
2128
+ }
2121
2129
  .cb-menu[data-starting-style],
2122
2130
  .cb-menu[data-ending-style] { opacity: 0; transform: scale(0.97); }
2123
2131
  @media (prefers-reduced-motion: reduce) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ceebee/ui",
3
- "version": "0.3.3",
3
+ "version": "0.4.0",
4
4
  "description": "Ceebee's design system: tokens, themed primitives, motion, and onboarding.",
5
5
  "license": "MIT",
6
6
  "repository": {