@salemcobalt/ui 0.2.0-rc.24 → 0.2.0-rc.25

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/README.md CHANGED
@@ -53,7 +53,7 @@ Styles ship as one stylesheet inside `@layer sc`, so an app's unlayered CSS alwa
53
53
  | `SelectionBar` | Floating bulk-action bar on Toolbar, centred at the bottom of the viewport (content width up to 48rem, gutters and the safe area respected, full width between the gutters under 640px, fade and slide-up, none under reduced motion): `count` (hidden at 0), `onClear`, children are `Toolbar.Button`s, `aria-label` ("Bulk actions"), `countLabel`, `clearLabel`. Mount it at the end of the scrolling content: while open it leaves a spacer as tall as itself so the last rows scroll clear. A polite status region announces the count; focus returns to where it came from when the bar leaves. |
54
54
  | `Toast` | `Toast.Provider` (`timeout` 6000, `limit` 3) near the root, `useToast().add({ title, description, tone, action: { label, onClick }, timeout, priority })` below it; Base UI Toast: polite region, paused on hover and focus, F6 to reach it, bottom-end at `--sc-z-toast`. |
55
55
  | `PriorityNav` | Priority+ primary navigation (docs/adr/0005): required `aria-label`; `items` as `{ href, label, id?, current?, badge?, badgeLabel? }` in priority order; links that fit stay inline and the rest go into a "More" disclosure (APG disclosure navigation: a `button` with `aria-expanded`, not a menu; Esc, click outside and focus leaving close it). The `current` link is never collapsed. `moreLabel`, `moreCountLabel(n)` (announced only: "More, 3 links"), `renderLink={(props) => <Link {...props} />}` for a router. Server-renders every link on one clipped line (scrolls sideways without JS), measures widths once (again after web fonts load or when keys/string labels change) and re-renders only when the inline count changes. Takes the free space in a flex row (`flex: 1 1 0%`); in a grid use a `minmax(0, 1fr)` track. The open panel sits in the top layer (Popover API), anchored to the toggle with CSS anchor positioning (a JS fallback elsewhere) and capped to the viewport. `data-overflowing` + `onOverflowChange(boolean)` let a header make room, with `overflowHysteresis` (px) so it cannot oscillate. Under 400px wide (container query) More shows only an ellipsis. `badge` (a count, or `'dot'`; `0` shows nothing) draws an accent pill or dot after the label, decorative, with `badgeLabel` ("2 suggestions to review") appended to the link's name; while the item is collapsed, More shows the collapsed items' summed count (a dot when they only have dots) and adds their `badgeLabel`s to its name ("More, 3 links, 2 suggestions to review"). Icon-only, the badge sits on More's corner. No motion. |
56
- | `Popover` | Non-modal panel on Base UI Popover: `Root` (`open`, `defaultOpen`, `onOpenChange`, `modal` default false), `Trigger` (secondary Button, or `render={<IconButton label dot />}`), `Content` (`side`, `align`, `sideOffset`, `arrow`; Menu's surface, `--sc-z-dropdown`), `Title` (names the dialog), `Description`, `Close` (the × with no children, or wraps a Button). Esc and focus return come from Base UI. |
56
+ | `Popover` | Non-modal panel on Base UI Popover: `Root` (`open`, `defaultOpen`, `onOpenChange`, `modal` default false), `Trigger` (secondary Button, or `render={<IconButton label dot />}`), `Content` (`side`, `align`, `sideOffset`, `arrow`, `anchor` to position against another element than the Trigger, e.g. a row's action button with a controlled `Root`; portaled to `document.body`; Menu's surface, `--sc-z-dropdown`, dropping to the backdrop layer while a Dialog opened from inside it is open, so the Dialog covers it), `Title` (names the dialog), `Description`, `Close` (the × with no children, or wraps a Button). Esc and focus return come from Base UI. |
57
57
  | `BroomIcon` | Animated 24px-grid icon for "a sweep is running": `sweeping`, `size` (Icon sizes, default `lg`, or `display` 72px with a 1.75px stroke), `title`. Inline SVG; strokes stay 1.25px at any size; holds still with the dust shown under `prefers-reduced-motion`. Inside an IconButton it takes the next icon size up. |
58
58
  | `Score` | A number on a tinted tile or in a ring: required `value` (a number, or `null` for not scored yet: a muted dash on the neutral tile or in an empty ring, no tone, no arc, read as "Fit score: not scored"), `max` (100), `tone` neutral · accent (default) · success · warning · danger (no thresholds inside: map value to tone in the app), `variant` tile · ring (64px, decorative SVG, arc animates only on change, none under reduced motion), `size` sm 40 · md 48 (tile), `caption`, `label` ("Fit score"), `valueText`, `selected`. Assistive tech reads one visually hidden sentence, "Fit score 94 out of 100"; the visible number is `aria-hidden`, no `aria-label`. A tile turns solid when `selected` or inside `.sc-card[data-selected]`, `[aria-pressed="true"]` or `[aria-selected="true"]`. |
59
59
  | `ReasonList` | `ReasonList` (`ul`) + `ReasonList.Item` (`li`): required `tone` for (filled square) · against (bar) · gap (hollow circle), so the marker shape carries the meaning as well as the colour; `size` sm · md; `divider` (dashed rule above). Name it with a heading via `aria-labelledby`; `<strong>` inside picks out key words. |
package/dist/index.d.ts CHANGED
@@ -2737,10 +2737,16 @@ interface PopoverContentProps extends Omit<Popover$1.Popup.Props, 'className'> {
2737
2737
  sideOffset?: number | undefined;
2738
2738
  /** Draws a tip pointing at the trigger. */
2739
2739
  arrow?: boolean | undefined;
2740
+ /**
2741
+ * What to position against instead of the `Popover.Trigger`: an element, a ref to one, a virtual element or a
2742
+ * function returning either. For a popover opened from elsewhere (a menu item, a row action) with a controlled
2743
+ * `Popover.Root open`. The panel is still portaled to `document.body`.
2744
+ */
2745
+ anchor?: Popover$1.Positioner.Props['anchor'];
2740
2746
  className?: string | undefined;
2741
2747
  }
2742
2748
  /** Portal, positioner and the panel. Any content goes inside; name it with `Popover.Title`. */
2743
- declare function Content({ side, align, sideOffset, arrow, className, children, ...rest }: PopoverContentProps): react.JSX.Element;
2749
+ declare function Content({ side, align, sideOffset, arrow, anchor, className, children, ...rest }: PopoverContentProps): react.JSX.Element;
2744
2750
  interface PopoverTitleProps extends Omit<Popover$1.Title.Props, 'className'> {
2745
2751
  className?: string | undefined;
2746
2752
  }
package/dist/index.js CHANGED
@@ -3269,6 +3269,7 @@ function Content3({
3269
3269
  align = "center",
3270
3270
  sideOffset,
3271
3271
  arrow = false,
3272
+ anchor,
3272
3273
  className,
3273
3274
  children,
3274
3275
  ...rest
@@ -3279,6 +3280,7 @@ function Content3({
3279
3280
  side,
3280
3281
  align,
3281
3282
  sideOffset: sideOffset ?? (arrow ? 8 : 4),
3283
+ anchor,
3282
3284
  className: "sc-popover__positioner",
3283
3285
  children: /* @__PURE__ */ jsxs27(BasePopover.Popup, { className: cx("sc-popover", className), ...rest, children: [
3284
3286
  arrow ? /* @__PURE__ */ jsx32(BasePopover.Arrow, { className: "sc-popover__arrow" }) : null,