atlas-react-kit 1.2.4 → 1.2.5

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/combobox.js CHANGED
@@ -6,6 +6,7 @@ import { Button } from "./button.js";
6
6
  import { Input } from "./input.js";
7
7
  import { formControlTriggerClassName } from "./internal/form-control.js";
8
8
  import { handleListboxKey } from "./internal/listbox-navigation.js";
9
+ import { clamp } from "./internal/math.js";
9
10
  import { Listbox, ListboxEmptyStatus, listboxInputAria, PickerOption, } from "./internal/listbox-option.js";
10
11
  import { createSearchIndex, filterSearchIndex, foldSearchText, normalizeSearchQuery, } from "./internal/search.js";
11
12
  import { emptyValueText } from "./internal/styles.js";
@@ -53,7 +54,7 @@ function resolveCreateValue(query, existingValues, normalize) {
53
54
  export function Combobox({ options, value, onValueChange, placeholder = "Select", searchPlaceholder = "Search", emptyText, disabled, id, className, listClassName, contentClassName, "aria-invalid": ariaInvalid, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, creatable = false, normalizeCreateValue = defaultNormalizeCreateValue, createLabel = defaultCreateLabel, ...props }) {
54
55
  const [open, setOpen] = React.useState(false);
55
56
  const [query, setQuery] = React.useState("");
56
- const [highlight, setHighlight] = React.useState(0);
57
+ const [highlightIndex, setHighlight] = React.useState(0);
57
58
  const listId = React.useId();
58
59
  const generatedId = React.useId();
59
60
  const triggerId = id ?? generatedId;
@@ -84,6 +85,7 @@ export function Combobox({ options, value, onValueChange, placeholder = "Select"
84
85
  : null;
85
86
  }, [creatable, query, existingValues, normalizeCreateValue, createLabel]);
86
87
  const list = createOption ? [...filtered, createOption] : filtered;
88
+ const highlight = clamp(highlightIndex, 0, Math.max(0, list.length - 1));
87
89
  const onOpenChange = (next) => {
88
90
  setOpen(next);
89
91
  if (!next) {
@@ -10,9 +10,7 @@ type ErrorFallbackProps = {
10
10
  className?: string;
11
11
  };
12
12
  /**
13
- * Presentational recovery UI used by `ErrorBoundary`: a large `EmptyPanel`
14
- * with the message and recovery buttons. Exported so the markup can be
15
- * tested without throwing during render.
13
+ * Recovery UI used by `ErrorBoundary`: a large `EmptyPanel` with recovery buttons.
16
14
  */
17
15
  export declare function ErrorFallback({ message, onRetry, onReload, className, }: ErrorFallbackProps): import("react").JSX.Element;
18
16
  type ErrorBoundaryProps = {
@@ -24,15 +22,14 @@ type ErrorBoundaryProps = {
24
22
  onError?: (error: Error, info: ErrorInfo) => void;
25
23
  };
26
24
  type ErrorBoundaryState = {
27
- error: Error | null;
25
+ hasError: boolean;
28
26
  };
29
27
  /**
30
28
  * Generic React error boundary with retry (reset) and full-page reload.
31
- * Not tied to any data library.
32
29
  */
33
30
  export declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
34
31
  state: ErrorBoundaryState;
35
- static getDerivedStateFromError(error: Error): ErrorBoundaryState;
32
+ static getDerivedStateFromError(): ErrorBoundaryState;
36
33
  componentDidCatch(error: Error, info: ErrorInfo): void;
37
34
  retry: () => void;
38
35
  reload: () => void;
@@ -5,9 +5,7 @@ import { Button } from "./button.js";
5
5
  import { EmptyPanel } from "./empty-panel.js";
6
6
  import { cn } from "./utils.js";
7
7
  /**
8
- * Presentational recovery UI used by `ErrorBoundary`: a large `EmptyPanel`
9
- * with the message and recovery buttons. Exported so the markup can be
10
- * tested without throwing during render.
8
+ * Recovery UI used by `ErrorBoundary`: a large `EmptyPanel` with recovery buttons.
11
9
  */
12
10
  export function ErrorFallback({ message = "Something went wrong.", onRetry, onReload, className, }) {
13
11
  return (_jsxs(EmptyPanel, { role: "alert", "data-slot": "error-boundary", size: "lg",
@@ -16,24 +14,23 @@ export function ErrorFallback({ message = "Something went wrong.", onRetry, onRe
16
14
  }
17
15
  /**
18
16
  * Generic React error boundary with retry (reset) and full-page reload.
19
- * Not tied to any data library.
20
17
  */
21
18
  export class ErrorBoundary extends Component {
22
- state = { error: null };
23
- static getDerivedStateFromError(error) {
24
- return { error };
19
+ state = { hasError: false };
20
+ static getDerivedStateFromError() {
21
+ return { hasError: true };
25
22
  }
26
23
  componentDidCatch(error, info) {
27
24
  this.props.onError?.(error, info);
28
25
  }
29
26
  retry = () => {
30
- this.setState({ error: null });
27
+ this.setState({ hasError: false });
31
28
  };
32
29
  reload = () => {
33
30
  window.location.reload();
34
31
  };
35
32
  render() {
36
- if (!this.state.error)
33
+ if (!this.state.hasError)
37
34
  return this.props.children;
38
35
  return (_jsx(ErrorFallback, { message: this.props.message, onRetry: this.retry, onReload: this.reload }));
39
36
  }
package/dist/kanban.js CHANGED
@@ -7,7 +7,7 @@ import { CheckCircle2, ChevronLeft, ChevronRight, GripVertical, Trash2, } from "
7
7
  import { Button } from "./button.js";
8
8
  import { KANBAN_COMPLETE_ID, KANBAN_DELETE_ID, buildKanbanGroups, kanbanOverflowEdges, kanbanScrollBy, resolveKanbanDrop, } from "./internal/kanban-layout.js";
9
9
  import { configureCardSortablePlugins, configureKanbanPlugins, } from "./internal/kanban-plugins.js";
10
- import { focusRingWithin } from "./internal/styles.js";
10
+ import { focusRing } from "./internal/styles.js";
11
11
  import { revealInline } from "./internal/use-horizontal-overflow.js";
12
12
  import { Skeleton } from "./skeleton.js";
13
13
  import { cn } from "./utils.js";
@@ -134,6 +134,7 @@ function KanbanColumnView({ column, count, emptyLabel, loading, className, child
134
134
  }
135
135
  const cardChrome = cn("flex border border-border bg-card text-card-foreground");
136
136
  const handleChrome = cn("flex shrink-0 items-center self-stretch border-r border-border", "bg-muted/30 px-1.5 text-muted-foreground");
137
+ const stopFocus = cn(focusRing, "relative focus-visible:z-10");
137
138
  function stopClick(event) {
138
139
  event.stopPropagation();
139
140
  }
@@ -150,9 +151,7 @@ function KanbanCardViewImpl({ item, index, column, onCardClick, className, rende
150
151
  });
151
152
  return (_jsxs("div", { ref: ref, "data-slot": "kanban-card", "data-dragging": isDragging || undefined, className: cn(cardChrome, "shadow-sm transition-[box-shadow,opacity,border-color]",
152
153
  // The overlay moves; the source keeps its slot.
153
- "data-dragging:pointer-events-none data-dragging:invisible",
154
- // One ring on the card for the grip and the body alike.
155
- focusRingWithin, onCardClick && "hover:border-foreground/15", className), children: [_jsx("button", { type: "button", ref: handleRef, "data-slot": "kanban-card-handle", "aria-label": "Drag to move", onClick: stopClick, className: cn(handleChrome, "cursor-grab outline-none hover:bg-muted/50 active:cursor-grabbing"), children: _jsx(GripVertical, { className: "size-4", "aria-hidden": true }) }), onCardClick ? (_jsx("button", { type: "button", "data-slot": "kanban-card-body", onClick: () => onCardClick(item), className: "min-w-0 flex-1 cursor-pointer p-3 text-left outline-none hover:bg-muted/20", children: children })) : (_jsx("div", { "data-slot": "kanban-card-body", className: "min-w-0 flex-1 p-3", children: children }))] }));
154
+ "data-dragging:pointer-events-none data-dragging:invisible", onCardClick && "hover:border-foreground/15", className), children: [_jsx("button", { type: "button", ref: handleRef, "data-slot": "kanban-card-handle", "aria-label": "Drag to move", onClick: stopClick, className: cn(handleChrome, stopFocus, "cursor-grab hover:bg-muted/50 active:cursor-grabbing"), children: _jsx(GripVertical, { className: "size-4", "aria-hidden": true }) }), onCardClick ? (_jsx("button", { type: "button", "data-slot": "kanban-card-body", onClick: () => onCardClick(item), className: cn("min-w-0 flex-1 cursor-pointer p-3 text-left hover:bg-muted/20", stopFocus), children: children })) : (_jsx("div", { "data-slot": "kanban-card-body", className: "min-w-0 flex-1 p-3", children: children }))] }));
156
155
  }
157
156
  /**
158
157
  * Memoized so a board update re-renders only the cards whose item, index or
package/dist/markdown.js CHANGED
@@ -35,7 +35,7 @@ const markdownComponents = {
35
35
  h3: ({ children }) => (_jsx("h3", { className: headingClass("text-base"), children: children })),
36
36
  p: ({ children }) => _jsx("p", { className: "text-sm leading-relaxed", children: children }),
37
37
  ul: ({ children }) => (_jsx("ul", { className: "list-disc space-y-1 pl-5 text-sm", children: children })),
38
- ol: ({ children }) => (_jsx("ol", { className: "list-decimal space-y-1 pl-5 text-sm", children: children })),
38
+ ol: ({ children, start }) => (_jsx("ol", { start: start, className: "list-decimal space-y-1 pl-5 text-sm", children: children })),
39
39
  li: ({ children }) => _jsx("li", { className: "leading-relaxed", children: children }),
40
40
  blockquote: ({ children }) => (_jsx("blockquote", { className: "border-l-2 border-input pl-3 text-sm text-muted-foreground", children: children })),
41
41
  a: ({ href, children }) => href ? (_jsx("a", { href: href, className: "text-selected-foreground underline underline-offset-2", ...(href.startsWith("http")
@@ -4,6 +4,7 @@ import * as React from "react";
4
4
  import { Input } from "./input.js";
5
5
  import { Label } from "./label.js";
6
6
  import { handleListboxKey } from "./internal/listbox-navigation.js";
7
+ import { clamp } from "./internal/math.js";
7
8
  import { Listbox, ListboxEmptyStatus, listboxInputAria, PickerOption, } from "./internal/listbox-option.js";
8
9
  import { createSearchIndex, filterSearchIndex, foldSearchText, normalizeSearchQuery, } from "./internal/search.js";
9
10
  import { cn, onInputChange } from "./utils.js";
@@ -42,10 +43,9 @@ function SearchPicker({ items, getValue, getLabel, filter = defaultSearchFilter,
42
43
  return index >= 0 ? index : 0;
43
44
  }, [filtered, getValue, value]);
44
45
  const rows = React.useMemo(() => filtered.map((item) => ({ item, value: getValue(item) })), [filtered, getValue]);
45
- const [highlight, setHighlight] = React.useState(selectedIndex);
46
- // Reset the highlight while rendering, not in an effect, when the query or
47
- // the selected row changes: an effect commits every keystroke twice, once
48
- // with the stale highlight and again with the reset.
46
+ const [highlightIndex, setHighlight] = React.useState(selectedIndex);
47
+ const highlight = clamp(highlightIndex, 0, Math.max(0, filtered.length - 1));
48
+ // Reset during render so a query or selection change commits only once.
49
49
  const [highlightFor, setHighlightFor] = React.useState({
50
50
  query,
51
51
  selectedIndex,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atlas-react-kit",
3
- "version": "1.2.4",
3
+ "version": "1.2.5",
4
4
  "description": "Shared React components and Tailwind theme for Atlas",
5
5
  "type": "module",
6
6
  "license": "MIT",