atlas-react-kit 0.6.1 → 0.8.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/COMPONENTS.md +54 -54
- package/README.md +2 -2
- package/dist/toast.d.ts +57 -0
- package/dist/toast.js +76 -0
- package/package.json +5 -5
- package/skills/atlas-react-kit/SKILL.md +4 -2
- package/dist/sonner.d.ts +0 -4
- package/dist/sonner.js +0 -15
package/COMPONENTS.md
CHANGED
|
@@ -5,60 +5,60 @@ underlying element or Radix props, including `className`, alongside their option
|
|
|
5
5
|
Form helpers and `TableBodySkeleton` accept only their documented props. There is
|
|
6
6
|
no root component barrel.
|
|
7
7
|
|
|
8
|
-
| Subpath | Main exports and options
|
|
9
|
-
| ----------------------------- |
|
|
10
|
-
| `accordion` | `Accordion`, `AccordionItem`, `AccordionTrigger`, `AccordionContent`; Radix `type` `single` (with `collapsible`) or `multiple`
|
|
11
|
-
| `alert` | `Alert`, `AlertTitle`, `AlertDescription`, `alertVariants`; `variant` `default`, `success`, `warning`, `destructive`; tone on title and icon, body stays muted; destructive is `role="alert"`
|
|
12
|
-
| `avatar` | `Avatar`, `AvatarImage`, `AvatarFallback`; `size` `sm`, `default`, `lg`; round by design
|
|
13
|
-
| `breadcrumb` | `Breadcrumb`, `BreadcrumbList`, `BreadcrumbItem`, `BreadcrumbLink` (`asChild` for router links), `BreadcrumbPage` (`aria-current`), `BreadcrumbSeparator`, `BreadcrumbEllipsis`
|
|
14
|
-
| `button` | `Button`, `buttonVariants`, `quietButtonInteraction`; `variant`, `size`, `asChild`; outline/ghost hover is brand purple + selected wash, not muted grey
|
|
15
|
-
| `badge` | `Badge`, `badgeVariants`; `variant`, `tone`, `asChild`
|
|
16
|
-
| `calendar` | `Calendar`, `CalendarDayButton`; React Day Picker props and `buttonVariant`
|
|
17
|
-
| `card` | `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardAction`, `CardContent`, `CardFooter`; `Card` supports `flush`; root uses `min-h-min shrink-0` so flex columns do not collapse it, and `min-w-0` so nested tables scroll; `CardContent className="px-0"` overrides padding without `!`
|
|
18
|
-
| `checkbox` | `Checkbox`
|
|
19
|
-
| `color-legend` | `ColorLegend`; `title`, `items` as `{ color, range?, label }[]`, optional `caption`, `children`, `aria-label`, `className` (overlay chrome). No attribution.
|
|
20
|
-
| `combobox` | `Combobox`; `options` as `{ value, label }[]`, `value`, `onValueChange`; optional placeholder, search, empty text; trigger matches Input/SelectTrigger chrome; keyboard highlight scrolls into view
|
|
21
|
-
| `date-picker` | `DatePickerButton`, `toDate`, `formatLocalDate`, `DateRange`; `mode` `"single"` (default) or `"range"`; single `value` is `Date` or `yyyy-MM-dd`; range `value` is `{ from, to }`; trigger matches Input chrome; optional `numberOfMonths` (range default 1 below `md`, 2 at `md+`) and `side`
|
|
22
|
-
| `date-time-picker` | `DateTimePickerButton`, `resolveTimeStep`, `DEFAULT_TIME_STEP`; controlled `value` is `Date` or `null`; `onChange` emits `Date \
|
|
23
|
-
| `dialog` | `Dialog`, trigger, portal, overlay, content, close, header, footer, title, description; `DialogContent` supports `showCloseButton`
|
|
24
|
-
| `dropdown-menu` | `DropdownMenu` family (trigger, content, item, checkbox/radio items, label, separator, shortcut, sub menus); item `variant="destructive"` and `inset`; for commands, not values
|
|
25
|
-
| `empty-panel` | `EmptyPanel`; required `children`; optional `size`, `muted`, `className`
|
|
26
|
-
| `error-boundary` | `ErrorBoundary`, `ErrorFallback`; optional `message`; retry resets, reload refreshes the page
|
|
27
|
-
| `field` | Field, label, legend, description, group, set, title, content, separator, error; `Field` supports `orientation`
|
|
28
|
-
| `info-tip` | `InfoTip`, `InlineTip`; required `label` (aria-label); `title`, `description`, `children`, `layout` `box` \| `inline`, `side`, `align`, `badge`, `icon`, `className`. Popover, 20px glyph, 44px hit. Hover opens only on a fine pointer. Not a Tooltip.
|
|
29
|
-
| `input`, `textarea`, `label` | `Input`, `Textarea`, `Label`
|
|
30
|
-
| `markdown` | `Markdown`, `MarkdownContent`; `content`, optional `className`. GFM via `react-markdown` + `remark-gfm` in this subpath only. Sanitized (no raw HTML; http/https/mailto/#/`/` URLs). Token styles, no typography plugin.
|
|
31
|
-
| `meter` | `Meter`; `value`, `max`, optional `min` (default 0), `fillClassName`, `markers` as `{ position, className? }[]`, required `aria-label`, `className`. `role="meter"`. Not `Progress`.
|
|
32
|
-
| `pagination` | `Pagination`, `PaginationContent`, `PaginationItem`, `PaginationLink` (`isActive` sets `aria-current`, the selected wash, and a selected border), `PaginationPrevious`, `PaginationNext`, `PaginationEllipsis`
|
|
33
|
-
| `popover` | `Popover`, trigger, anchor, content, header, title, description
|
|
34
|
-
| `progress` | `Progress`; Radix props, `value` 0–100; label it with `aria-label` or `aria-labelledby`. For a value against a scale with ticks, use `Meter`.
|
|
35
|
-
| `radio-group` | `RadioGroup`, `RadioGroupItem`; short visible lists; arrow keys move the selection; round dots
|
|
36
|
-
| `search-picker` | `SearchPicker<T>`; always-visible combobox + listbox; `items`, `getValue`, `getLabel`, optional `filter` (default casefold + accent-fold includes), `value`, `onSelect`, `label`, `placeholder`, `emptyText`, `listLabel`, `disabled`, `className`. Arrows, Home/End, PageUp/PageDown, Enter, Escape.
|
|
37
|
-
| `select` | Select, trigger, value, content, group, label, item, separator, scroll buttons; trigger `size`; trigger text is `text-base md:text-sm` like Input
|
|
38
|
-
| `separator`, `skeleton` | `Separator`, `Skeleton`
|
|
39
|
-
| `slider` | `Slider`; `value` number, `onValueChange`, optional `onValueCommit`, `min`, `max`, `step`, `disabled`, `id`, `aria-labelledby`, `className`. Radix Slider; 44px thumb hit; square track; primary fill. Name it with `aria-labelledby`.
|
|
40
|
-
| `sortable-table-head` | `SortableTableHead`; `sorted`, `direction` (`asc` \
|
|
41
|
-
| `
|
|
42
|
-
| `
|
|
43
|
-
| `
|
|
44
|
-
| `
|
|
45
|
-
| `table`
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
48
|
-
| `toggle` | `Toggle`, `toggleVariants`, `selectedToggleChrome`; `variant`, `size`. Pressed state is the selected wash, text, and border via `data-state=on`, `aria-pressed`, and `aria-checked`
|
|
49
|
-
| `toggle-group` | `ToggleGroup`, `ToggleGroupItem`; `variant`, `size`. Items share `toggleVariants`, so single (radio) and multiple selections match a pressed `Toggle`
|
|
50
|
-
| `theme-provider` | `ThemeProvider`, `useTheme`; optional `storageKey` (default `atlas-theme`), `enableShortcut` for the `d` toggle
|
|
51
|
-
| `tooltip` | `Tooltip`, `TooltipTrigger`, `TooltipContent`, `TooltipProvider`; opens on hover and focus; short labels only
|
|
52
|
-
| `form/markdown-field` | `FormMarkdownField`; `field` is `TextFieldApi`; `label`, optional `id`, `placeholder`, `rows`, `showError`. Write / preview; preview uses `Markdown`.
|
|
53
|
-
| `form/text-field` | `FormTextField`, type `TextFieldApi`; controlled field, label, multiline, description, input constraints
|
|
54
|
-
| `form/select-field` | `FormSelectField`; `value`, `onValueChange`, `label`, optional `meta` and placeholder; select item children
|
|
55
|
-
| `form/date-picker-field` | `FormDatePickerField`; `value`, `onValueChange`, `label`, optional `meta`, placeholder, and `className` (forwarded to the trigger)
|
|
56
|
-
| `form/date-time-picker-field` | `FormDateTimePickerField`; `value` is `Date` or `null`; `onValueChange` emits `Date \
|
|
57
|
-
| `form/field-error` | `FieldError`, `getFieldErrorMessage`; types `FieldErrorMessage`, `FieldMetaState`
|
|
58
|
-
| `form/feedback-field` | `FormFeedbackField`; nullable `message`
|
|
59
|
-
| `next/tabs-nav-link` | `TabsNavLink`; Next Link props and required `active` boolean; requires Next.js 16
|
|
60
|
-
| `utils` | `cn`, `onInputChange`
|
|
61
|
-
| `theme.css` | Tailwind 4 theme; installation in [README](./README.md)
|
|
8
|
+
| Subpath | Main exports and options |
|
|
9
|
+
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
10
|
+
| `accordion` | `Accordion`, `AccordionItem`, `AccordionTrigger`, `AccordionContent`; Radix `type` `single` (with `collapsible`) or `multiple` |
|
|
11
|
+
| `alert` | `Alert`, `AlertTitle`, `AlertDescription`, `alertVariants`; `variant` `default`, `success`, `warning`, `destructive`; tone on title and icon, body stays muted; destructive is `role="alert"` |
|
|
12
|
+
| `avatar` | `Avatar`, `AvatarImage`, `AvatarFallback`; `size` `sm`, `default`, `lg`; round by design |
|
|
13
|
+
| `breadcrumb` | `Breadcrumb`, `BreadcrumbList`, `BreadcrumbItem`, `BreadcrumbLink` (`asChild` for router links), `BreadcrumbPage` (`aria-current`), `BreadcrumbSeparator`, `BreadcrumbEllipsis` |
|
|
14
|
+
| `button` | `Button`, `buttonVariants`, `quietButtonInteraction`; `variant`, `size`, `asChild`; outline/ghost hover is brand purple + selected wash, not muted grey |
|
|
15
|
+
| `badge` | `Badge`, `badgeVariants`; `variant`, `tone`, `asChild` |
|
|
16
|
+
| `calendar` | `Calendar`, `CalendarDayButton`; React Day Picker props and `buttonVariant` |
|
|
17
|
+
| `card` | `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardAction`, `CardContent`, `CardFooter`; `Card` supports `flush`; root uses `min-h-min shrink-0` so flex columns do not collapse it, and `min-w-0` so nested tables scroll; `CardContent className="px-0"` overrides padding without `!` |
|
|
18
|
+
| `checkbox` | `Checkbox` |
|
|
19
|
+
| `color-legend` | `ColorLegend`; `title`, `items` as `{ color, range?, label }[]`, optional `caption`, `children`, `aria-label`, `className` (overlay chrome). No attribution. |
|
|
20
|
+
| `combobox` | `Combobox`; `options` as `{ value, label }[]`, `value`, `onValueChange`; optional placeholder, search, empty text; trigger matches Input/SelectTrigger chrome; keyboard highlight scrolls into view |
|
|
21
|
+
| `date-picker` | `DatePickerButton`, `toDate`, `formatLocalDate`, `DateRange`; `mode` `"single"` (default) or `"range"`; single `value` is `Date` or `yyyy-MM-dd`; range `value` is `{ from, to }`; trigger matches Input chrome; optional `numberOfMonths` (range default 1 below `md`, 2 at `md+`) and `side` |
|
|
22
|
+
| `date-time-picker` | `DateTimePickerButton`, `resolveTimeStep`, `DEFAULT_TIME_STEP`; controlled `value` is `Date` or `null`; `onChange` emits `Date \ |
|
|
23
|
+
| `dialog` | `Dialog`, trigger, portal, overlay, content, close, header, footer, title, description; `DialogContent` supports `showCloseButton` |
|
|
24
|
+
| `dropdown-menu` | `DropdownMenu` family (trigger, content, item, checkbox/radio items, label, separator, shortcut, sub menus); item `variant="destructive"` and `inset`; for commands, not values |
|
|
25
|
+
| `empty-panel` | `EmptyPanel`; required `children`; optional `size`, `muted`, `className` |
|
|
26
|
+
| `error-boundary` | `ErrorBoundary`, `ErrorFallback`; optional `message`; retry resets, reload refreshes the page |
|
|
27
|
+
| `field` | Field, label, legend, description, group, set, title, content, separator, error; `Field` supports `orientation` |
|
|
28
|
+
| `info-tip` | `InfoTip`, `InlineTip`; required `label` (aria-label); `title`, `description`, `children`, `layout` `box` \| `inline`, `side`, `align`, `badge`, `icon`, `className`. Popover, 20px glyph, 44px hit. Hover opens only on a fine pointer. Not a Tooltip. |
|
|
29
|
+
| `input`, `textarea`, `label` | `Input`, `Textarea`, `Label` |
|
|
30
|
+
| `markdown` | `Markdown`, `MarkdownContent`; `content`, optional `className`. GFM via `react-markdown` + `remark-gfm` in this subpath only. Sanitized (no raw HTML; http/https/mailto/#/`/` URLs). Token styles, no typography plugin. |
|
|
31
|
+
| `meter` | `Meter`; `value`, `max`, optional `min` (default 0), `fillClassName`, `markers` as `{ position, className? }[]`, required `aria-label`, `className`. `role="meter"`. Not `Progress`. |
|
|
32
|
+
| `pagination` | `Pagination`, `PaginationContent`, `PaginationItem`, `PaginationLink` (`isActive` sets `aria-current`, the selected wash, and a selected border), `PaginationPrevious`, `PaginationNext`, `PaginationEllipsis` |
|
|
33
|
+
| `popover` | `Popover`, trigger, anchor, content, header, title, description |
|
|
34
|
+
| `progress` | `Progress`; Radix props, `value` 0–100; label it with `aria-label` or `aria-labelledby`. For a value against a scale with ticks, use `Meter`. |
|
|
35
|
+
| `radio-group` | `RadioGroup`, `RadioGroupItem`; short visible lists; arrow keys move the selection; round dots |
|
|
36
|
+
| `search-picker` | `SearchPicker<T>`; always-visible combobox + listbox; `items`, `getValue`, `getLabel`, optional `filter` (default casefold + accent-fold includes), `value`, `onSelect`, `label`, `placeholder`, `emptyText`, `listLabel`, `disabled`, `className`. Arrows, Home/End, PageUp/PageDown, Enter, Escape. |
|
|
37
|
+
| `select` | Select, trigger, value, content, group, label, item, separator, scroll buttons; trigger `size`; trigger text is `text-base md:text-sm` like Input |
|
|
38
|
+
| `separator`, `skeleton` | `Separator`, `Skeleton` |
|
|
39
|
+
| `slider` | `Slider`; `value` number, `onValueChange`, optional `onValueCommit`, `min`, `max`, `step`, `disabled`, `id`, `aria-labelledby`, `className`. Radix Slider; 44px thumb hit; square track; primary fill. Name it with `aria-labelledby`. |
|
|
40
|
+
| `sortable-table-head` | `SortableTableHead`; `sorted`, `direction` (`asc` \ |
|
|
41
|
+
| `spinner` | `Spinner`; `role="status"` with `aria-label` (default `Loading`) |
|
|
42
|
+
| `stat-tile` | `StatTile`, `statTileGrid`, `sectionLabel`; `label`, `value`, optional `sub`, `children`, `className`. |
|
|
43
|
+
| `switch` | `Switch`; settings that apply immediately; square track and thumb |
|
|
44
|
+
| `table` | Table, header, body, footer, row, head, cell, caption; root scroller is `min-w-0 overflow-x-auto` with a fade cue; cells are `px-2` below `sm` |
|
|
45
|
+
| `table-body-skeleton` | `TableBodySkeleton`; `columns`, optional `rows` (default 5) |
|
|
46
|
+
| `tabs` | `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent`, `TabsNav`, `tabsListVariants`, `tabsTriggerVariants`; list `variant` is `default` or `line`; style `TabsNav` links with `tabsTriggerVariants()` |
|
|
47
|
+
| `toast` | `Toaster`, `toast`; mount one `Toaster` (`position`, `closeButton` (default on), `expand`, `visibleToasts`, `duration`), then `toast(message, options)`, `.success`, `.info`, `.warning`, `.error`, `.loading`, `.dismiss(id?)`. Options: `id` (replaces that toast), `description`, `duration`, `action` / `cancel` as `{ label, onClick }`. Kit-owned API: no toast library is exposed |
|
|
48
|
+
| `toggle` | `Toggle`, `toggleVariants`, `selectedToggleChrome`; `variant`, `size`. Pressed state is the selected wash, text, and border via `data-state=on`, `aria-pressed`, and `aria-checked` |
|
|
49
|
+
| `toggle-group` | `ToggleGroup`, `ToggleGroupItem`; `variant`, `size`. Items share `toggleVariants`, so single (radio) and multiple selections match a pressed `Toggle` |
|
|
50
|
+
| `theme-provider` | `ThemeProvider`, `useTheme`; optional `storageKey` (default `atlas-theme`), `enableShortcut` for the `d` toggle |
|
|
51
|
+
| `tooltip` | `Tooltip`, `TooltipTrigger`, `TooltipContent`, `TooltipProvider`; opens on hover and focus; short labels only |
|
|
52
|
+
| `form/markdown-field` | `FormMarkdownField`; `field` is `TextFieldApi`; `label`, optional `id`, `placeholder`, `rows`, `showError`. Write / preview; preview uses `Markdown`. |
|
|
53
|
+
| `form/text-field` | `FormTextField`, type `TextFieldApi`; controlled field, label, multiline, description, input constraints |
|
|
54
|
+
| `form/select-field` | `FormSelectField`; `value`, `onValueChange`, `label`, optional `meta` and placeholder; select item children |
|
|
55
|
+
| `form/date-picker-field` | `FormDatePickerField`; `value`, `onValueChange`, `label`, optional `meta`, placeholder, and `className` (forwarded to the trigger) |
|
|
56
|
+
| `form/date-time-picker-field` | `FormDateTimePickerField`; `value` is `Date` or `null`; `onValueChange` emits `Date \ |
|
|
57
|
+
| `form/field-error` | `FieldError`, `getFieldErrorMessage`; types `FieldErrorMessage`, `FieldMetaState` |
|
|
58
|
+
| `form/feedback-field` | `FormFeedbackField`; nullable `message` |
|
|
59
|
+
| `next/tabs-nav-link` | `TabsNavLink`; Next Link props and required `active` boolean; requires Next.js 16 |
|
|
60
|
+
| `utils` | `cn`, `onInputChange` |
|
|
61
|
+
| `theme.css` | Tailwind 4 theme; installation in [README](./README.md) |
|
|
62
62
|
|
|
63
63
|
## Status
|
|
64
64
|
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ keeping locally (`InfoTip`, `ColorLegend`, `SearchPicker`, `Markdown`,
|
|
|
7
7
|
React 19 and Tailwind 4 are required.
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
|
-
npm install --save-exact atlas-react-kit@0.
|
|
10
|
+
npm install --save-exact atlas-react-kit@0.8.0
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
Import components by subpath:
|
|
@@ -116,7 +116,7 @@ artifact with the package owner's npm login:
|
|
|
116
116
|
```sh
|
|
117
117
|
mkdir -p release-artifacts
|
|
118
118
|
npm pack --pack-destination release-artifacts
|
|
119
|
-
npm publish ./release-artifacts/atlas-react-kit-0.
|
|
119
|
+
npm publish ./release-artifacts/atlas-react-kit-0.8.0.tgz --access public
|
|
120
120
|
```
|
|
121
121
|
|
|
122
122
|
See [CONTRIBUTING.md](./CONTRIBUTING.md) for adding components, the browser
|
package/dist/toast.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/** Identifies a toast, to replace it in place or dismiss it. */
|
|
3
|
+
type ToastId = string | number;
|
|
4
|
+
/** A button in a toast. Clicking it runs `onClick`, then closes the toast. */
|
|
5
|
+
interface ToastAction {
|
|
6
|
+
label: string;
|
|
7
|
+
onClick: () => void;
|
|
8
|
+
}
|
|
9
|
+
interface ToastOptions {
|
|
10
|
+
/** An existing toast's id replaces that toast, e.g. loading → success. */
|
|
11
|
+
id?: ToastId;
|
|
12
|
+
/** A second, muted line under the message. */
|
|
13
|
+
description?: ReactNode;
|
|
14
|
+
/** Milliseconds before it closes; `Number.POSITIVE_INFINITY` keeps it open. */
|
|
15
|
+
duration?: number;
|
|
16
|
+
/** The primary button, such as "Undo" or "Retry". */
|
|
17
|
+
action?: ToastAction;
|
|
18
|
+
/** A secondary outline button, such as "Dismiss". */
|
|
19
|
+
cancel?: ToastAction;
|
|
20
|
+
}
|
|
21
|
+
/** Shows a toast and returns its id. */
|
|
22
|
+
type ShowToast = (message: ReactNode, options?: ToastOptions) => ToastId;
|
|
23
|
+
type Toast = ShowToast & {
|
|
24
|
+
success: ShowToast;
|
|
25
|
+
info: ShowToast;
|
|
26
|
+
warning: ShowToast;
|
|
27
|
+
error: ShowToast;
|
|
28
|
+
/** A spinner toast that stays until it is replaced (same `id`) or dismissed. */
|
|
29
|
+
loading: ShowToast;
|
|
30
|
+
/** Closes one toast by id, or every toast when called without one. */
|
|
31
|
+
dismiss: (id?: ToastId) => void;
|
|
32
|
+
};
|
|
33
|
+
type ToastPosition = "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right";
|
|
34
|
+
interface ToasterProps {
|
|
35
|
+
/** Where toasts stack. Default `bottom-right`. */
|
|
36
|
+
position?: ToastPosition;
|
|
37
|
+
/** A labelled close button on every toast. Default `true`. */
|
|
38
|
+
closeButton?: boolean;
|
|
39
|
+
/** Keep the stack expanded instead of collapsed behind the newest toast. */
|
|
40
|
+
expand?: boolean;
|
|
41
|
+
/** How many toasts show at once. Default 3. */
|
|
42
|
+
visibleToasts?: number;
|
|
43
|
+
/** Milliseconds before a toast closes when it sets no `duration`. Default 4000. */
|
|
44
|
+
duration?: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Shows a toast through the app's one `Toaster`: `toast("Saved")`,
|
|
48
|
+
* `toast.success(...)`, `toast.error(...)`. Returns its id.
|
|
49
|
+
*/
|
|
50
|
+
declare const toast: Toast;
|
|
51
|
+
/**
|
|
52
|
+
* Mount one near the app root, and show toasts with `toast()` from this
|
|
53
|
+
* module. Only the props declared here reach the library.
|
|
54
|
+
*/
|
|
55
|
+
declare const Toaster: ({ position, closeButton, expand, visibleToasts, duration, }: ToasterProps) => import("react").JSX.Element;
|
|
56
|
+
export { Toaster, toast };
|
|
57
|
+
export type { ToastAction, ToastId, ToastOptions, ToastPosition, ToasterProps };
|
package/dist/toast.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { CircleAlertIcon, CircleCheckIcon, InfoIcon, LoaderCircleIcon, XIcon, } from "lucide-react";
|
|
4
|
+
import { useTheme } from "next-themes";
|
|
5
|
+
import { Toaster as Sonner, toast as sonnerToast, } from "sonner";
|
|
6
|
+
import { buttonVariants } from "./button.js";
|
|
7
|
+
import { cn } from "./utils.js";
|
|
8
|
+
/**
|
|
9
|
+
* Copies only the kit's options, so plain JavaScript callers cannot hand the
|
|
10
|
+
* library its own styling options (class names, `unstyled`, rich colors).
|
|
11
|
+
*/
|
|
12
|
+
function libraryOptions(options = {}) {
|
|
13
|
+
const { id, description, duration, action, cancel } = options;
|
|
14
|
+
return {
|
|
15
|
+
id,
|
|
16
|
+
description,
|
|
17
|
+
duration,
|
|
18
|
+
action: action && { label: action.label, onClick: () => action.onClick() },
|
|
19
|
+
cancel: cancel && { label: cancel.label, onClick: () => cancel.onClick() },
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const show = (method) => (message, options) => method(message, libraryOptions(options));
|
|
23
|
+
/**
|
|
24
|
+
* Shows a toast through the app's one `Toaster`: `toast("Saved")`,
|
|
25
|
+
* `toast.success(...)`, `toast.error(...)`. Returns its id.
|
|
26
|
+
*/
|
|
27
|
+
const toast = Object.assign(show(sonnerToast), {
|
|
28
|
+
success: show(sonnerToast.success),
|
|
29
|
+
info: show(sonnerToast.info),
|
|
30
|
+
warning: show(sonnerToast.warning),
|
|
31
|
+
error: show(sonnerToast.error),
|
|
32
|
+
loading: show(sonnerToast.loading),
|
|
33
|
+
dismiss: (id) => {
|
|
34
|
+
sonnerToast.dismiss(id);
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
/**
|
|
38
|
+
* Toasts drawn entirely with kit classes. Sonner's own styles are unlayered
|
|
39
|
+
* CSS that Tailwind utilities cannot override, so the toaster runs Sonner
|
|
40
|
+
* `unstyled` and styles every part here: the popover surface, Alert-style
|
|
41
|
+
* status icons (the tone colors the icon, title, and border, not the body
|
|
42
|
+
* text), kit buttons for actions, and a labelled close button with the
|
|
43
|
+
* shared focus ring.
|
|
44
|
+
*/
|
|
45
|
+
const classNames = {
|
|
46
|
+
toast: "flex w-(--width) flex-wrap items-start justify-end gap-3 rounded-none border border-border bg-popover p-4 pr-10 text-sm text-popover-foreground shadow-lg",
|
|
47
|
+
// Fills the row beside the icon, so action buttons wrap to their own row
|
|
48
|
+
// (aligned right by the toast's justify-end).
|
|
49
|
+
content: "flex min-w-0 flex-1 basis-[calc(100%-1.75rem)] flex-col gap-0.5",
|
|
50
|
+
title: "font-medium leading-5",
|
|
51
|
+
description: "leading-5 text-muted-foreground",
|
|
52
|
+
icon: "mt-0.5 flex size-4 shrink-0 items-center justify-center [&_svg]:size-4",
|
|
53
|
+
actionButton: cn(buttonVariants({ size: "xs" }), "shrink-0"),
|
|
54
|
+
cancelButton: cn(buttonVariants({ variant: "outline", size: "xs" }), "shrink-0"),
|
|
55
|
+
closeButton: cn(buttonVariants({ variant: "ghost", size: "icon-xs" }), "absolute top-2 right-2 text-muted-foreground"),
|
|
56
|
+
success: "border-success/40 [&_[data-title]]:text-success",
|
|
57
|
+
warning: "border-warning/40 [&_[data-title]]:text-warning",
|
|
58
|
+
error: "border-destructive/40 [&_[data-title]]:text-destructive",
|
|
59
|
+
};
|
|
60
|
+
const icons = {
|
|
61
|
+
success: _jsx(CircleCheckIcon, { "aria-hidden": true, className: "text-success" }),
|
|
62
|
+
info: _jsx(InfoIcon, { "aria-hidden": true, className: "text-foreground" }),
|
|
63
|
+
warning: _jsx(CircleAlertIcon, { "aria-hidden": true, className: "text-warning" }),
|
|
64
|
+
error: _jsx(CircleAlertIcon, { "aria-hidden": true, className: "text-destructive" }),
|
|
65
|
+
loading: (_jsx(LoaderCircleIcon, { "aria-hidden": true, className: "animate-spin text-muted-foreground" })),
|
|
66
|
+
close: _jsx(XIcon, { "aria-hidden": true }),
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Mount one near the app root, and show toasts with `toast()` from this
|
|
70
|
+
* module. Only the props declared here reach the library.
|
|
71
|
+
*/
|
|
72
|
+
const Toaster = ({ position, closeButton = true, expand, visibleToasts, duration, }) => {
|
|
73
|
+
const { theme = "system" } = useTheme();
|
|
74
|
+
return (_jsx(Sonner, { theme: theme, className: "toaster group", position: position, closeButton: closeButton, expand: expand, visibleToasts: visibleToasts, duration: duration, icons: icons, toastOptions: { unstyled: true, classNames } }));
|
|
75
|
+
};
|
|
76
|
+
export { Toaster, toast };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atlas-react-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Shared React components and Tailwind theme for Atlas",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -148,10 +148,6 @@
|
|
|
148
148
|
"types": "./dist/slider.d.ts",
|
|
149
149
|
"default": "./dist/slider.js"
|
|
150
150
|
},
|
|
151
|
-
"./sonner": {
|
|
152
|
-
"types": "./dist/sonner.d.ts",
|
|
153
|
-
"default": "./dist/sonner.js"
|
|
154
|
-
},
|
|
155
151
|
"./sortable-table-head": {
|
|
156
152
|
"types": "./dist/sortable-table-head.d.ts",
|
|
157
153
|
"default": "./dist/sortable-table-head.js"
|
|
@@ -188,6 +184,10 @@
|
|
|
188
184
|
"types": "./dist/theme-provider.d.ts",
|
|
189
185
|
"default": "./dist/theme-provider.js"
|
|
190
186
|
},
|
|
187
|
+
"./toast": {
|
|
188
|
+
"types": "./dist/toast.d.ts",
|
|
189
|
+
"default": "./dist/toast.js"
|
|
190
|
+
},
|
|
191
191
|
"./toggle": {
|
|
192
192
|
"types": "./dist/toggle.d.ts",
|
|
193
193
|
"default": "./dist/toggle.js"
|
|
@@ -39,8 +39,10 @@ and tells Tailwind to scan the kit's compiled files:
|
|
|
39
39
|
|
|
40
40
|
Dark mode needs `ThemeProvider` from `atlas-react-kit/theme-provider` near the
|
|
41
41
|
root (or a `dark` class on an ancestor). Toasts need one `<Toaster />` from
|
|
42
|
-
`atlas-react-kit/
|
|
43
|
-
|
|
42
|
+
`atlas-react-kit/toast`; show them with `toast()` from the same module, using
|
|
43
|
+
only the options it declares. Never import a toast library such as `sonner`
|
|
44
|
+
directly: the kit owns the toast API, and a second copy never reaches its
|
|
45
|
+
toaster. Fix missing setup rather than working
|
|
44
46
|
around unstyled components.
|
|
45
47
|
|
|
46
48
|
## 3. Pick the kit component for the job
|
package/dist/sonner.d.ts
DELETED
package/dist/sonner.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
import { useTheme } from "next-themes";
|
|
5
|
-
import { Toaster as Sonner } from "sonner";
|
|
6
|
-
const Toaster = ({ ...props }) => {
|
|
7
|
-
const { theme = "system" } = useTheme();
|
|
8
|
-
return (_jsx(Sonner, { theme: theme, className: "toaster group", style: {
|
|
9
|
-
"--normal-bg": "var(--popover)",
|
|
10
|
-
"--normal-text": "var(--popover-foreground)",
|
|
11
|
-
"--normal-border": "var(--border)",
|
|
12
|
-
"--border-radius": "0px",
|
|
13
|
-
}, ...props }));
|
|
14
|
-
};
|
|
15
|
-
export { Toaster };
|