@estiva-app/ui 0.56.0 → 0.57.1

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.
Files changed (46) hide show
  1. package/dist/ChipInput.d.ts.map +1 -1
  2. package/dist/CollapsibleSection.d.ts +1 -1
  3. package/dist/CollapsibleSection.d.ts.map +1 -1
  4. package/dist/CommandPalette.d.ts.map +1 -1
  5. package/dist/ComposerTriggers.d.ts +2 -0
  6. package/dist/ComposerTriggers.d.ts.map +1 -1
  7. package/dist/NavItem.d.ts.map +1 -1
  8. package/dist/NavTree.d.ts +2 -2
  9. package/dist/NavTree.d.ts.map +1 -1
  10. package/dist/SectionHeader.d.ts +4 -4
  11. package/dist/SectionHeader.d.ts.map +1 -1
  12. package/dist/Select.d.ts.map +1 -1
  13. package/dist/SuggestionMenu.d.ts.map +1 -1
  14. package/dist/editor.js +2 -2
  15. package/dist/editor.js.map +2 -2
  16. package/dist/index.js +33 -36
  17. package/dist/index.js.map +3 -3
  18. package/dist/looks.d.ts +2 -2
  19. package/dist/looks.d.ts.map +1 -1
  20. package/package.json +1 -1
  21. package/registry.json +8 -7
  22. package/src/ChipInput.test.tsx +8 -0
  23. package/src/ChipInput.tsx +4 -2
  24. package/src/CollapsibleSection.mdx +1 -1
  25. package/src/CollapsibleSection.test.tsx +24 -0
  26. package/src/CollapsibleSection.tsx +1 -1
  27. package/src/CommandPalette.test.tsx +6 -0
  28. package/src/CommandPalette.tsx +3 -2
  29. package/src/ComposerTriggers.mdx +1 -1
  30. package/src/ComposerTriggers.test.tsx +6 -0
  31. package/src/ComposerTriggers.tsx +4 -2
  32. package/src/ListColumn.test.tsx +8 -0
  33. package/src/NavItem.mdx +3 -1
  34. package/src/NavItem.test.tsx +30 -0
  35. package/src/NavItem.tsx +10 -3
  36. package/src/NavTree.test.tsx +21 -0
  37. package/src/NavTree.tsx +7 -3
  38. package/src/SectionHeader.mdx +4 -3
  39. package/src/SectionHeader.test.tsx +68 -5
  40. package/src/SectionHeader.tsx +37 -25
  41. package/src/Select.test.tsx +8 -0
  42. package/src/Select.tsx +5 -2
  43. package/src/SuggestionMenu.stories.tsx +15 -0
  44. package/src/SuggestionMenu.test.tsx +8 -0
  45. package/src/SuggestionMenu.tsx +4 -2
  46. package/src/looks.ts +3 -3
package/dist/index.js CHANGED
@@ -289,10 +289,10 @@ var FIELD_SHELL_CLASSES = "bg-bg-field border border-border-field shadow-field h
289
289
  var FLOATING_SURFACE_CLASSES = "rounded-lg border border-border-default bg-bg-elevated shadow-lg";
290
290
  var CHIP_TEXT_CLASSES = "text-chip signal:font-mono signal:text-small signal:font-semibold signal:tabular-nums";
291
291
  var BARE_INPUT_CLASSES = "bg-transparent text-text-primary placeholder:text-text-muted outline-none";
292
- var MUTED_CONTROL_CLASSES = "text-text-secondary hover:bg-bg-hover hover:text-text-primary";
293
- var MENU_TRIGGER_CLASSES = "cursor-pointer rounded-md transition-colors hover:bg-bg-hover data-[popup-open]:bg-bg-hover";
294
292
  var SIDEBAR_ROW_CLASSES = "rounded-lg transition-colors";
295
293
  var SIDEBAR_ROW_TEXT_CLASSES = "text-text-secondary hover:text-text-primary";
294
+ var MUTED_CONTROL_CLASSES = "text-text-secondary hover:bg-bg-hover hover:text-text-primary";
295
+ var MENU_TRIGGER_CLASSES = "cursor-pointer rounded-md transition-colors hover:bg-bg-hover data-[popup-open]:bg-bg-hover";
296
296
  var COLLAPSIBLE_PANEL_CLASSES = "h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-150 ease-out motion-reduce:transition-none data-[starting-style]:h-0 data-[ending-style]:h-0";
297
297
 
298
298
  // src/formBusy.ts
@@ -1603,7 +1603,7 @@ function ChipInput({
1603
1603
  sideOffset: GAP3,
1604
1604
  collisionPadding: VIEWPORT_PAD3,
1605
1605
  className: "z-50 data-[anchor-hidden]:hidden",
1606
- children: /* @__PURE__ */ jsx22(Combobox.Popup, { className: "w-[var(--anchor-width)] p-0", render: /* @__PURE__ */ jsx22(MenuPanel, {}), children: /* @__PURE__ */ jsx22(ScrollArea, { viewportClassName: "max-h-[240px]", contentClassName: "flex flex-col p-2", children: /* @__PURE__ */ jsx22(Combobox.List, { children: (option) => /* @__PURE__ */ jsx22(
1606
+ children: /* @__PURE__ */ jsx22(Combobox.Popup, { className: "w-[var(--anchor-width)] p-0", render: /* @__PURE__ */ jsx22(MenuPanel, {}), children: /* @__PURE__ */ jsx22(ScrollArea, { viewportClassName: "max-h-[240px]", contentClassName: "flex flex-col p-2", children: /* @__PURE__ */ jsx22(Combobox.List, { className: "flex flex-col gap-0.5", children: (option) => /* @__PURE__ */ jsx22(
1607
1607
  Combobox.Item,
1608
1608
  {
1609
1609
  value: option,
@@ -1959,7 +1959,7 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
1959
1959
  ] }),
1960
1960
  /* @__PURE__ */ jsxs19(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col p-2", children: [
1961
1961
  children != null && /* @__PURE__ */ jsx27("div", { className: "flex flex-col gap-2 px-3 pb-2 pt-3", children }),
1962
- /* @__PURE__ */ jsx27(Autocomplete.List, { className: "flex flex-col", children: (group) => /* @__PURE__ */ jsxs19(Autocomplete.Group, { items: group.items, className: "flex flex-col", children: [
1962
+ /* @__PURE__ */ jsx27(Autocomplete.List, { className: "flex flex-col", children: (group) => /* @__PURE__ */ jsxs19(Autocomplete.Group, { items: group.items, className: "flex flex-col gap-0.5", children: [
1963
1963
  /* @__PURE__ */ jsx27(Autocomplete.GroupLabel, { className: "flex h-7 shrink-0 items-center px-3", children: /* @__PURE__ */ jsx27(SectionLabel, { tone: "secondary", children: group.value }) }),
1964
1964
  /* @__PURE__ */ jsx27(Autocomplete.Collection, { children: (row) => (
1965
1965
  /* The menu row, as the list's own option — the way Select
@@ -2526,7 +2526,7 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
2526
2526
  {
2527
2527
  render: /* @__PURE__ */ jsx34(MenuPanel, {}),
2528
2528
  className: "min-w-[var(--anchor-width)] p-0",
2529
- children: /* @__PURE__ */ jsx34(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col p-2", children: options.map((option) => /* @__PURE__ */ jsxs25(
2529
+ children: /* @__PURE__ */ jsx34(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col gap-0.5 p-2", children: options.map((option) => /* @__PURE__ */ jsxs25(
2530
2530
  BaseSelect.Item,
2531
2531
  {
2532
2532
  value: option.value,
@@ -2999,7 +2999,7 @@ function NavItem({
2999
2999
  };
3000
3000
  const besides = menu != null || hasRows;
3001
3001
  const mark = unread ? urgent ? /* @__PURE__ */ jsx45(UrgentMark, {}) : /* @__PURE__ */ jsx45(UnreadDot, {}) : null;
3002
- const stepsAside = menu != null && "transition-opacity group-hover/nav:opacity-0 group-has-[:focus-visible]/nav:opacity-0 group-has-[[data-nav-menu]_[aria-expanded=true]]/nav:opacity-0";
3002
+ const stepsAside = menu != null && "transition-opacity group-hover/nav:opacity-0 group-has-[:focus-visible]/nav:opacity-0 group-has-[[data-nav-menu]_[aria-expanded=true]]/nav:opacity-0 [@media(hover:none)]:opacity-0";
3003
3003
  const row = /* @__PURE__ */ jsxs30(
3004
3004
  "a",
3005
3005
  {
@@ -3055,7 +3055,10 @@ function NavItem({
3055
3055
  // Nothing at the right, but a menu: no room is kept at rest, so the
3056
3056
  // label has the row's whole width; while the ⋮ shows, its 24px slot
3057
3057
  // is kept, so a long label ends before it instead of running under it.
3058
- /* @__PURE__ */ jsx45("span", { "aria-hidden": "true", className: "hidden w-6 shrink-0 group-hover/nav:block group-has-[:focus-visible]/nav:block group-has-[[data-nav-menu]_[aria-expanded=true]]/nav:block" })
3058
+ // `-mr-1`: the ⋮ sits at `right-1`, 4px into the row's padding, so the
3059
+ // slot does too — at the padding's edge it kept 4px the ⋮ never
3060
+ // covers, and the label stopped 12px short of the button, not 8.
3061
+ /* @__PURE__ */ jsx45("span", { "aria-hidden": "true", className: "-mr-1 hidden w-6 shrink-0 group-hover/nav:block group-has-[:focus-visible]/nav:block group-has-[[data-nav-menu]_[aria-expanded=true]]/nav:block [@media(hover:none)]:block" })
3059
3062
  ) : null
3060
3063
  ]
3061
3064
  }
@@ -3083,7 +3086,9 @@ function NavItem({
3083
3086
  // (Katerina, 5 October: the rows move to the heading, not the
3084
3087
  // heading to the rows). Over a dot or the empty slot it sits 4px
3085
3088
  // right of the slot's centre.
3086
- /* @__PURE__ */ jsx45("div", { "data-nav-menu": true, className: cn("absolute inset-y-0 right-1 flex items-center", "opacity-0 transition-opacity group-hover/nav:opacity-100 group-has-[:focus-visible]/nav:opacity-100 has-[[aria-expanded=true]]:opacity-100"), children: /* @__PURE__ */ jsx45(
3089
+ // On a screen with no hover it always shows: nothing there can point
3090
+ // at the row, and the menu has no other way in.
3091
+ /* @__PURE__ */ jsx45("div", { "data-nav-menu": true, className: cn("absolute inset-y-0 right-1 flex items-center", "opacity-0 transition-opacity group-hover/nav:opacity-100 group-has-[:focus-visible]/nav:opacity-100 has-[[aria-expanded=true]]:opacity-100 [@media(hover:none)]:opacity-100"), children: /* @__PURE__ */ jsx45(
3087
3092
  Menu,
3088
3093
  {
3089
3094
  align: "right",
@@ -3118,16 +3123,14 @@ import { useState as useState9 } from "react";
3118
3123
  import { Collapsible as Collapsible2 } from "@base-ui/react/collapsible";
3119
3124
 
3120
3125
  // src/SectionHeader.tsx
3121
- import { isValidElement as isValidElement2 } from "react";
3122
3126
  import { IconChevronRight as IconChevronRight3, IconDotsVertical as IconDotsVertical2 } from "@tabler/icons-react";
3123
3127
  import { useRender } from "@base-ui/react/use-render";
3124
3128
  import { Fragment as Fragment11, jsx as jsx46, jsxs as jsxs31 } from "react/jsx-runtime";
3125
3129
  function SectionHeader({ title, chevron = false, icon, isExpanded = true, onToggle, trailing, actions, menu, menuLabel, showActions = "hover", hover = "fill", look = "heading", render, className }) {
3126
3130
  const row = look === "row";
3127
3131
  const acts = actions && actions.length > 0 || menu != null;
3128
- const dot = isValidElement2(trailing) && trailing.type === UnreadDot;
3129
- const shared = acts && showActions === "hover" && dot;
3130
- const reveal = showActions === "hover" && "opacity-0 transition-opacity group-hover:opacity-100 has-[:focus-visible]:opacity-100 has-[[aria-expanded=true]]:opacity-100";
3132
+ const trailingClasses = !acts ? "has-[[data-unread]]:-mr-1" : showActions === "hover" && "has-[[data-unread]]:pointer-events-none has-[[data-unread]]:absolute has-[[data-unread]]:inset-y-0 has-[[data-unread]]:right-1 has-[[data-unread]]:w-6 has-[[data-unread]]:justify-center has-[[data-unread]]:transition-opacity group-hover:has-[[data-unread]]:opacity-0 group-has-[:focus-visible]:has-[[data-unread]]:opacity-0 group-has-[[data-section-menu]_[aria-expanded=true]]:has-[[data-unread]]:opacity-0 [@media(hover:none)]:has-[[data-unread]]:opacity-0";
3133
+ const reveal = showActions === "hover" && "opacity-0 transition-opacity group-hover:opacity-100 group-has-[:focus-visible]:opacity-100 has-[[aria-expanded=true]]:opacity-100 [@media(hover:none)]:opacity-100";
3131
3134
  const titleElement = useRender({
3132
3135
  render: render ?? (chevron ? /* @__PURE__ */ jsx46("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx46("span", {})),
3133
3136
  props: {
@@ -3166,7 +3169,8 @@ function SectionHeader({ title, chevron = false, icon, isExpanded = true, onTogg
3166
3169
  "div",
3167
3170
  {
3168
3171
  className: cn(
3169
- "group flex h-[32px] shrink-0 items-center gap-1 px-2",
3172
+ // `relative`: a dot in the last button's place is placed against the row.
3173
+ "group relative flex h-[32px] shrink-0 items-center gap-1 px-2",
3170
3174
  !row && "transition-colors",
3171
3175
  // A row is NavItem's shape and colour: 6px corners, secondary words that brighten on hover.
3172
3176
  row ? cn(SIDEBAR_ROW_CLASSES, SIDEBAR_ROW_TEXT_CLASSES) : "rounded-lg",
@@ -3182,29 +3186,22 @@ function SectionHeader({ title, chevron = false, icon, isExpanded = true, onTogg
3182
3186
  ),
3183
3187
  children: [
3184
3188
  titleElement,
3185
- trailing != null && !shared && // A dot with no buttons to share a place with still sits on their
3186
- // axis — the rows' dots and ⋮ (`-mr-1`, as the buttons are pulled).
3187
- /* @__PURE__ */ jsx46("div", { className: cn("flex shrink-0 items-center", dot && !acts && "-mr-1"), children: trailing }),
3188
- acts && /* @__PURE__ */ jsxs31(
3189
+ trailing != null && /* @__PURE__ */ jsx46("div", { className: cn("flex shrink-0 items-center", trailingClasses), children: trailing }),
3190
+ acts && /* @__PURE__ */ jsx46(
3189
3191
  "div",
3190
3192
  {
3191
- className: "group/acts relative -mr-1 flex shrink-0 items-center",
3192
- children: [
3193
- /* @__PURE__ */ jsxs31("div", { className: cn("flex items-center gap-1", reveal), children: [
3194
- actions?.map((action) => /* @__PURE__ */ jsx46(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip)),
3195
- menu != null && /* @__PURE__ */ jsx46("div", { "data-section-menu": true, className: "flex items-center", children: /* @__PURE__ */ jsx46(
3196
- Menu,
3197
- {
3198
- align: "right",
3199
- trigger: /* @__PURE__ */ jsx46(IconButton, { tooltip: "More options", "aria-label": menuLabel ?? `More options for ${title}`, children: /* @__PURE__ */ jsx46(IconDotsVertical2, { size: 16, stroke: 1.5 }) }),
3200
- children: menu
3201
- }
3202
- ) })
3203
- ] }),
3204
- shared && // The dot in the last button's 24px place, on the axis of its icon;
3205
- // gone while the buttons show.
3206
- /* @__PURE__ */ jsx46("div", { className: "pointer-events-none absolute inset-y-0 right-0 flex w-6 items-center justify-center transition-opacity group-hover:opacity-0 group-has-[:focus-visible]/acts:opacity-0 group-has-[[aria-expanded=true]]/acts:opacity-0", children: trailing })
3207
- ]
3193
+ className: "-mr-1 flex shrink-0 items-center",
3194
+ children: /* @__PURE__ */ jsxs31("div", { className: cn("flex items-center gap-1", reveal), children: [
3195
+ actions?.map((action) => /* @__PURE__ */ jsx46(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip)),
3196
+ menu != null && /* @__PURE__ */ jsx46("div", { "data-section-menu": true, className: "flex items-center", children: /* @__PURE__ */ jsx46(
3197
+ Menu,
3198
+ {
3199
+ align: "right",
3200
+ trigger: /* @__PURE__ */ jsx46(IconButton, { tooltip: "More options", "aria-label": menuLabel ?? `More options for ${title}`, children: /* @__PURE__ */ jsx46(IconDotsVertical2, { size: 16, stroke: 1.5 }) }),
3201
+ children: menu
3202
+ }
3203
+ ) })
3204
+ ] })
3208
3205
  }
3209
3206
  )
3210
3207
  ]
@@ -3313,7 +3310,7 @@ function NavTreeSection({ id, title, message, loading = false, trailing, actions
3313
3310
  return /* @__PURE__ */ jsx48(
3314
3311
  "div",
3315
3312
  {
3316
- className: "mt-1 shrink-0 first:mt-0",
3313
+ className: "shrink-0 [&+&]:mt-1",
3317
3314
  "data-nav-group": id,
3318
3315
  onPointerEnter: intent ? () => {
3319
3316
  clearTimeout(timer.current);
@@ -3492,7 +3489,7 @@ function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sect
3492
3489
  )
3493
3490
  );
3494
3491
  };
3495
- return /* @__PURE__ */ jsx50(Popover, { anchor: rect, open: rect !== null, side: "top", align: "left", className: width, maxHeight, ariaLabel, children: /* @__PURE__ */ jsx50("div", { id: listboxId, role: "listbox", "aria-label": ariaLabel, className: "flex flex-col", children: shown.map((section, i) => /* @__PURE__ */ jsxs35("div", { className: "contents", children: [
3492
+ return /* @__PURE__ */ jsx50(Popover, { anchor: rect, open: rect !== null, side: "top", align: "left", className: width, maxHeight, ariaLabel, children: /* @__PURE__ */ jsx50("div", { id: listboxId, role: "listbox", "aria-label": ariaLabel, className: "flex flex-col gap-0.5", children: shown.map((section, i) => /* @__PURE__ */ jsxs35("div", { className: "contents", children: [
3496
3493
  i > 0 && /* @__PURE__ */ jsx50(MenuSeparator, {}),
3497
3494
  section.label ? /* @__PURE__ */ jsx50("div", { role: "group", "aria-label": section.label, children: /* @__PURE__ */ jsx50(MenuSection, { label: section.label, className: section.className, children: section.items.map(drawRow) }) }) : section.items.map(drawRow)
3498
3495
  ] }, section.label ?? i)) }) });