@rackbops/ui-react 0.2.33 → 0.2.35

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.
@@ -0,0 +1,38 @@
1
+ import { type ReactNode } from "react";
2
+ import { type CardProps } from "./Card.js";
3
+ export interface EmptyStateProps extends Omit<CardProps, "title"> {
4
+ /**
5
+ * A heading naming what is missing ("No cards yet", "Select a panel"), replacing the native
6
+ * HTML `title` tooltip attribute -- there's no way to set a real tooltip through this
7
+ * component (same trade-off as `Alert`/`Dialog`'s `title`). Required and typed
8
+ * `NonNullable<ReactNode>` (not plain `ReactNode`) so passing an optional value straight
9
+ * through (`title={label}` where `label?: string`) is a compile error rather than a silently
10
+ * empty, unlabelled heading inside the `role="status"` region -- the one thing this component
11
+ * exists to avoid. `NonNullable` only catches an explicit `null`/`undefined` reaching the prop
12
+ * directly: an explicit `false`/`""`/`0`, an empty array, or `undefined` laundered through a
13
+ * fragment (`title={<>{maybeLabel}</>}`) all still compile and still render an empty heading --
14
+ * each is the caller's responsibility, same as passing empty `children` anywhere else in this
15
+ * library.
16
+ */
17
+ title: NonNullable<ReactNode>;
18
+ /** Optional call to action -- a Button or a link -- rendered after the guidance. */
19
+ action?: ReactNode;
20
+ /** Heading level for `title`; default 3. Falls back to 3 for a value outside 2-4 reached
21
+ * through an untyped caller or a cast, so a bad value degrades to a real heading instead of an
22
+ * invalid tag name. */
23
+ level?: 2 | 3 | 4;
24
+ }
25
+ /**
26
+ * An empty-guidance surface: a Card with `role="status"` holding a heading, optional guidance
27
+ * (`children`) and an optional action. It never renders a spinner or progress indicator -- an
28
+ * empty state is a fact stated in words, so "still loading" and "genuinely empty" are never
29
+ * shown the same way as a stalled spinner. Composes `Card` and adds no class of its own (the
30
+ * LinksIndex precedent); first consumer Rackbops/artifact-console#45.
31
+ *
32
+ * `role="status"` is a live region: like any live region it does not announce on first paint
33
+ * (a page that renders straight into several empty panels announces nothing), and it is meant
34
+ * for a state that appears or changes after mount (content loading in, then coming back empty),
35
+ * not for text that changes on every keystroke -- reusing one instance for a live search query
36
+ * would re-announce the whole card, action button included, on every character.
37
+ */
38
+ export declare const EmptyState: import("react").ForwardRefExoticComponent<Omit<EmptyStateProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,24 @@
1
+ import { jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { createElement, forwardRef } from "react";
3
+ import { Card } from "./Card.js";
4
+ // Must stay in sync with the `level` union below -- a caller relying on this list to guard
5
+ // every valid level would silently stop doing so if the type widened without this following.
6
+ const VALID_LEVELS = [2, 3, 4];
7
+ /**
8
+ * An empty-guidance surface: a Card with `role="status"` holding a heading, optional guidance
9
+ * (`children`) and an optional action. It never renders a spinner or progress indicator -- an
10
+ * empty state is a fact stated in words, so "still loading" and "genuinely empty" are never
11
+ * shown the same way as a stalled spinner. Composes `Card` and adds no class of its own (the
12
+ * LinksIndex precedent); first consumer Rackbops/artifact-console#45.
13
+ *
14
+ * `role="status"` is a live region: like any live region it does not announce on first paint
15
+ * (a page that renders straight into several empty panels announces nothing), and it is meant
16
+ * for a state that appears or changes after mount (content loading in, then coming back empty),
17
+ * not for text that changes on every keystroke -- reusing one instance for a live search query
18
+ * would re-announce the whole card, action button included, on every character.
19
+ */
20
+ export const EmptyState = forwardRef(function EmptyState({ title, action, level = 3, children, ...rest }, ref) {
21
+ const heading = `h${VALID_LEVELS.includes(level) ? level : 3}`;
22
+ return (_jsxs(Card, { ref: ref, role: "status", ...rest, children: [createElement(heading, null, title), children, action] }));
23
+ });
24
+ EmptyState.displayName = "EmptyState";
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { Button, type ButtonProps } from "./Button.js";
2
2
  export { Card, type CardProps } from "./Card.js";
3
+ export { EmptyState, type EmptyStateProps } from "./EmptyState.js";
3
4
  export { NavLink, type NavLinkProps } from "./NavLink.js";
4
5
  export { NavRail, type NavRailProps, type NavRailItem } from "./NavRail.js";
5
6
  export { Input, Textarea, Select, Label, Field, Checkbox, Radio, Switch, type InputProps, type TextareaProps, type SelectProps, type LabelProps, type FieldProps, type ChoiceProps, } from "./form.js";
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { Button } from "./Button.js";
2
2
  export { Card } from "./Card.js";
3
+ export { EmptyState } from "./EmptyState.js";
3
4
  export { NavLink } from "./NavLink.js";
4
5
  export { NavRail } from "./NavRail.js";
5
6
  export { Input, Textarea, Select, Label, Field, Checkbox, Radio, Switch, } from "./form.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rackbops/ui-react",
3
- "version": "0.2.33",
3
+ "version": "0.2.35",
4
4
  "description": "React components styled by @rackbops/styles rackbops themes.",
5
5
  "license": "MIT",
6
6
  "repository": {