atlas-react-kit 0.11.2 → 0.13.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.
Files changed (42) hide show
  1. package/COMPONENTS.md +176 -83
  2. package/DESIGN_RULES.md +14 -1
  3. package/README.md +3 -3
  4. package/dist/alert.d.ts +1 -1
  5. package/dist/badge.d.ts +2 -2
  6. package/dist/button.d.ts +2 -2
  7. package/dist/date-picker.d.ts +3 -9
  8. package/dist/date-picker.js +8 -38
  9. package/dist/date-time-picker.d.ts +1 -1
  10. package/dist/date-time-picker.js +3 -3
  11. package/dist/error-boundary.d.ts +1 -1
  12. package/dist/field.d.ts +1 -1
  13. package/dist/form/control-field.d.ts +31 -0
  14. package/dist/form/control-field.js +22 -0
  15. package/dist/form/date-picker-field.d.ts +9 -3
  16. package/dist/form/date-picker-field.js +3 -3
  17. package/dist/form/date-time-picker-field.d.ts +10 -4
  18. package/dist/form/date-time-picker-field.js +3 -3
  19. package/dist/form/field-error.d.ts +18 -0
  20. package/dist/form/field-shell.d.ts +29 -10
  21. package/dist/form/field-shell.js +37 -11
  22. package/dist/form/markdown-field.d.ts +4 -2
  23. package/dist/form/markdown-field.js +3 -3
  24. package/dist/form/select-field.d.ts +5 -3
  25. package/dist/form/select-field.js +3 -3
  26. package/dist/form/text-field.d.ts +3 -4
  27. package/dist/form/text-field.js +6 -6
  28. package/dist/internal/date-like.d.ts +31 -0
  29. package/dist/internal/date-like.js +33 -0
  30. package/dist/label.d.ts +16 -1
  31. package/dist/label.js +7 -3
  32. package/dist/nav-link.d.ts +22 -0
  33. package/dist/nav-link.js +31 -0
  34. package/dist/next/nav-link.d.ts +11 -0
  35. package/dist/next/nav-link.js +14 -0
  36. package/dist/picker-shell.d.ts +48 -6
  37. package/dist/picker-shell.js +28 -0
  38. package/dist/toast.d.ts +4 -2
  39. package/dist/toast.js +18 -3
  40. package/dist/toggle.d.ts +1 -1
  41. package/package.json +17 -5
  42. package/skills/atlas-react-kit/SKILL.md +2 -0
@@ -0,0 +1,33 @@
1
+ import { parseISO } from "date-fns";
2
+ /**
3
+ * Coerce a date-like value to a local `Date`.
4
+ * Plain calendar dates (`yyyy-MM-dd`) parse as local midnight so they do not
5
+ * shift when the runtime timezone is behind UTC.
6
+ */
7
+ export function toDate(value) {
8
+ if (value == null || value === "")
9
+ return undefined;
10
+ if (value instanceof Date) {
11
+ return Number.isNaN(value.getTime()) ? undefined : value;
12
+ }
13
+ if (typeof value === "number") {
14
+ const date = new Date(value);
15
+ return Number.isNaN(date.getTime()) ? undefined : date;
16
+ }
17
+ const trimmed = value.trim();
18
+ const ymd = /^(\d{4})-(\d{2})-(\d{2})$/.exec(trimmed);
19
+ if (ymd) {
20
+ const year = Number(ymd[1]);
21
+ const month = Number(ymd[2]);
22
+ const day = Number(ymd[3]);
23
+ const date = new Date(year, month - 1, day);
24
+ if (date.getFullYear() !== year ||
25
+ date.getMonth() !== month - 1 ||
26
+ date.getDate() !== day) {
27
+ return undefined;
28
+ }
29
+ return date;
30
+ }
31
+ const parsed = parseISO(trimmed);
32
+ return Number.isNaN(parsed.getTime()) ? undefined : parsed;
33
+ }
package/dist/label.d.ts CHANGED
@@ -1,4 +1,19 @@
1
1
  import * as React from "react";
2
2
  import { Label as LabelPrimitive } from "radix-ui";
3
- declare function Label({ className, ...props }: React.ComponentProps<typeof LabelPrimitive.Root>): React.JSX.Element;
3
+ type LabelProps = React.ComponentProps<typeof LabelPrimitive.Root> & {
4
+ /**
5
+ * Shows a visible required marker after the text. The marker is hidden
6
+ * from assistive tech, so set `required` (or `aria-required`) on the
7
+ * control too; screen readers announce it from there.
8
+ */
9
+ required?: boolean;
10
+ /** Classes for the required marker (`data-slot="label-required"`). */
11
+ requiredClassName?: string;
12
+ };
13
+ /**
14
+ * Form label. `required` adds a visible marker; style it with
15
+ * `requiredClassName` or the `label-required` slot.
16
+ */
17
+ declare function Label({ className, required, requiredClassName, children, ...props }: LabelProps): React.JSX.Element;
4
18
  export { Label };
19
+ export type { LabelProps };
package/dist/label.js CHANGED
@@ -1,9 +1,13 @@
1
1
  "use client";
2
- import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { Label as LabelPrimitive } from "radix-ui";
5
5
  import { cn } from "./utils.js";
6
- function Label({ className, ...props }) {
7
- return (_jsx(LabelPrimitive.Root, { "data-slot": "label", className: cn("flex items-center gap-2 text-xs font-semibold tracking-wide uppercase select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50 peer-data-[slot=checkbox]:text-sm peer-data-[slot=checkbox]:font-normal peer-data-[slot=checkbox]:tracking-normal peer-data-[slot=checkbox]:normal-case peer-data-[slot=radio-group-item]:text-sm peer-data-[slot=radio-group-item]:font-normal peer-data-[slot=radio-group-item]:tracking-normal peer-data-[slot=radio-group-item]:normal-case peer-data-[slot=switch]:text-sm peer-data-[slot=switch]:font-normal peer-data-[slot=switch]:tracking-normal peer-data-[slot=switch]:normal-case", className), ...props }));
6
+ /**
7
+ * Form label. `required` adds a visible marker; style it with
8
+ * `requiredClassName` or the `label-required` slot.
9
+ */
10
+ function Label({ className, required, requiredClassName, children, ...props }) {
11
+ return (_jsxs(LabelPrimitive.Root, { "data-slot": "label", className: cn("flex items-center gap-2 text-xs font-semibold tracking-wide uppercase select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50 peer-data-[slot=checkbox]:text-sm peer-data-[slot=checkbox]:font-normal peer-data-[slot=checkbox]:tracking-normal peer-data-[slot=checkbox]:normal-case peer-data-[slot=radio-group-item]:text-sm peer-data-[slot=radio-group-item]:font-normal peer-data-[slot=radio-group-item]:tracking-normal peer-data-[slot=radio-group-item]:normal-case peer-data-[slot=switch]:text-sm peer-data-[slot=switch]:font-normal peer-data-[slot=switch]:tracking-normal peer-data-[slot=switch]:normal-case", className), ...props, children: [children, required ? (_jsx("span", { "data-slot": "label-required", "aria-hidden": "true", className: cn("-ml-1.5 text-destructive", requiredClassName), children: "*" })) : null] }));
8
12
  }
9
13
  export { Label };
@@ -0,0 +1,22 @@
1
+ import * as React from "react";
2
+ /**
3
+ * Pill chrome for app-shell navigation. Inactive is muted text with an
4
+ * accent hover; active uses the shared selected wash, text, and border
5
+ * (`selectedState.active`) so the current page meets non-text contrast.
6
+ * Apps pass `active` — the kit has no router.
7
+ */
8
+ declare const navLinkVariants: (props?: import("class-variance-authority/types").ClassProp | undefined) => string;
9
+ /**
10
+ * Pill link for app-shell destinations (Calendar, Tasks, Settings). Pass
11
+ * `active` from the route; the kit does not read the URL. `asChild` wraps a
12
+ * router `Link` with these styles, the same Slot pattern as `BreadcrumbLink`.
13
+ *
14
+ * Not a tab: in-page view switches that belong in the URL use `TabsNav`
15
+ * and `tabsTriggerVariants()`. Next apps can import the optional adapter
16
+ * from `atlas-react-kit/next/nav-link` instead of composing `asChild`.
17
+ */
18
+ declare function NavLink({ asChild, active, className, ...props }: React.ComponentProps<"a"> & {
19
+ asChild?: boolean;
20
+ active: boolean;
21
+ }): React.JSX.Element;
22
+ export { NavLink, navLinkVariants };
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { cva } from "class-variance-authority";
4
+ import { Slot } from "radix-ui";
5
+ import { focusRing, selectedState } from "./internal/styles.js";
6
+ import { cn } from "./utils.js";
7
+ /**
8
+ * Pill chrome for app-shell navigation. Inactive is muted text with an
9
+ * accent hover; active uses the shared selected wash, text, and border
10
+ * (`selectedState.active`) so the current page meets non-text contrast.
11
+ * Apps pass `active` — the kit has no router.
12
+ */
13
+ const navLinkVariants = cva([
14
+ focusRing,
15
+ selectedState.active,
16
+ "inline-flex items-center gap-1.5 rounded-none border border-transparent px-3 py-1.5 text-sm text-muted-foreground transition-colors hover:bg-accent data-[state=active]:font-medium",
17
+ ]);
18
+ /**
19
+ * Pill link for app-shell destinations (Calendar, Tasks, Settings). Pass
20
+ * `active` from the route; the kit does not read the URL. `asChild` wraps a
21
+ * router `Link` with these styles, the same Slot pattern as `BreadcrumbLink`.
22
+ *
23
+ * Not a tab: in-page view switches that belong in the URL use `TabsNav`
24
+ * and `tabsTriggerVariants()`. Next apps can import the optional adapter
25
+ * from `atlas-react-kit/next/nav-link` instead of composing `asChild`.
26
+ */
27
+ function NavLink({ asChild, active, className, ...props }) {
28
+ const Comp = asChild ? Slot.Root : "a";
29
+ return (_jsx(Comp, { "data-slot": "nav-link", "data-state": active ? "active" : "inactive", "aria-current": active ? "page" : undefined, className: cn(navLinkVariants(), className), ...props }));
30
+ }
31
+ export { NavLink, navLinkVariants };
@@ -0,0 +1,11 @@
1
+ import type * as React from "react";
2
+ import Link from "next/link.js";
3
+ /**
4
+ * Next.js adapter for the shell `NavLink` pill. Same contract as
5
+ * `TabsNavLink`: Next `Link` props plus a required `active` boolean. The
6
+ * kit still does not read the router; the app passes `active`.
7
+ */
8
+ declare function NavLink({ active, className, ...props }: React.ComponentProps<typeof Link> & {
9
+ active: boolean;
10
+ }): React.JSX.Element;
11
+ export { NavLink };
@@ -0,0 +1,14 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import Link from "next/link.js";
4
+ import { navLinkVariants } from "../nav-link.js";
5
+ import { cn } from "../utils.js";
6
+ /**
7
+ * Next.js adapter for the shell `NavLink` pill. Same contract as
8
+ * `TabsNavLink`: Next `Link` props plus a required `active` boolean. The
9
+ * kit still does not read the router; the app passes `active`.
10
+ */
11
+ function NavLink({ active, className, ...props }) {
12
+ return (_jsx(Link, { "data-slot": "nav-link", "data-state": active ? "active" : "inactive", "aria-current": active ? "page" : undefined, className: cn(navLinkVariants(), className), ...props }));
13
+ }
14
+ export { NavLink };
@@ -1,16 +1,42 @@
1
1
  import * as React from "react";
2
- import type { PropsBase } from "react-day-picker";
2
+ import type { Locale } from "date-fns";
3
+ import { type DateLike, type DateMatcher } from "./internal/date-like.js";
3
4
  import { PopoverContent } from "./popover.js";
4
5
  /**
5
6
  * Not a public entry. The trigger, popover, and Clear footer that
6
7
  * `DatePickerButton` and `DateTimePickerButton` share.
7
8
  */
8
9
  /**
9
- * Day Picker options for the picker's calendar: disabled matchers,
10
- * `startMonth` / `endMonth`, `weekStartsOn`, `locale`, `className`, and so on.
11
- * The picker owns the selection, focus, and month props.
10
+ * Options for the picker's calendar. The picker owns the selection, focus,
11
+ * and month props; these are the kit's own types, so a Day Picker upgrade
12
+ * does not change them.
12
13
  */
13
- export type PickerCalendarProps = Omit<PropsBase, "mode" | "required" | "autoFocus" | "defaultMonth" | "numberOfMonths">;
14
+ export type PickerCalendarProps = {
15
+ /** Days that cannot be picked. */
16
+ disabled?: DateMatcher | DateMatcher[];
17
+ /** Days left out of the grid. */
18
+ hidden?: DateMatcher | DateMatcher[];
19
+ /** Earliest month the calendar pages to. */
20
+ startMonth?: Date;
21
+ /** Latest month the calendar pages to. */
22
+ endMonth?: Date;
23
+ /** First day of the week, `0` (Sunday) to `6`. Defaults to the locale's. */
24
+ weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
25
+ /** A date-fns locale for month and weekday names. */
26
+ locale?: Locale;
27
+ /** Show the leading and trailing days of the neighbouring months. Default `true`. */
28
+ showOutsideDays?: boolean;
29
+ /** Always show six weeks, so the popover height does not change. */
30
+ fixedWeeks?: boolean;
31
+ /** Show ISO or locale week numbers in a first column. */
32
+ showWeekNumber?: boolean;
33
+ /** Month and year as text (`label`, default) or as dropdowns. */
34
+ captionLayout?: "label" | "dropdown" | "dropdown-months" | "dropdown-years";
35
+ /** The day marked as today. Defaults to the current date. */
36
+ today?: Date;
37
+ /** Classes for the calendar root. */
38
+ className?: string;
39
+ };
14
40
  /** Props both pickers take for their trigger and popover. */
15
41
  export type PickerTriggerProps = {
16
42
  id?: string;
@@ -34,10 +60,26 @@ export type PickerTriggerProps = {
34
60
  side?: React.ComponentProps<typeof PopoverContent>["side"];
35
61
  /** Month shown when the popover opens; falls back to the selected date. */
36
62
  defaultMonth?: Date;
63
+ /**
64
+ * Earliest day that can be picked. Earlier days are disabled and the
65
+ * calendar does not page before its month.
66
+ */
67
+ minDate?: DateLike;
68
+ /**
69
+ * Latest day that can be picked. Later days are disabled and the calendar
70
+ * does not page past its month.
71
+ */
72
+ maxDate?: DateLike;
37
73
  /** Day Picker options passed through to the calendar. */
38
74
  calendarProps?: PickerCalendarProps;
39
75
  };
40
- type PickerShellProps = Omit<PickerTriggerProps, "placeholder" | "defaultMonth" | "calendarProps"> & {
76
+ /**
77
+ * `calendarProps` with `minDate` / `maxDate` applied: days outside them join
78
+ * any `disabled` matchers, and they bound paging unless `startMonth` /
79
+ * `endMonth` are set.
80
+ */
81
+ export declare function limitCalendarProps(calendarProps: PickerCalendarProps | undefined, minDate: DateLike, maxDate: DateLike): PickerCalendarProps | undefined;
82
+ type PickerShellProps = Omit<PickerTriggerProps, "placeholder" | "defaultMonth" | "calendarProps" | "minDate" | "maxDate"> & {
41
83
  /** Muted trigger text while nothing is picked. */
42
84
  empty: boolean;
43
85
  /** Trigger text: the formatted value or the placeholder. */
@@ -3,10 +3,38 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { CalendarIcon } from "lucide-react";
5
5
  import { Button } from "./button.js";
6
+ import { toDate, } from "./internal/date-like.js";
6
7
  import { PICKER_COLLISION_PADDING, pickerContentClassName, pickerTriggerClassName, pickerValueId, } from "./internal/form-control.js";
7
8
  import { preloadCalendar } from "./lazy-calendar.js";
8
9
  import { Popover, PopoverContent, PopoverTrigger } from "./popover.js";
9
10
  import { cn } from "./utils.js";
11
+ /**
12
+ * `calendarProps` with `minDate` / `maxDate` applied: days outside them join
13
+ * any `disabled` matchers, and they bound paging unless `startMonth` /
14
+ * `endMonth` are set.
15
+ */
16
+ export function limitCalendarProps(calendarProps, minDate, maxDate) {
17
+ const min = toDate(minDate);
18
+ const max = toDate(maxDate);
19
+ if (!min && !max)
20
+ return calendarProps;
21
+ const disabled = calendarProps?.disabled;
22
+ const matchers = [
23
+ ...(disabled === undefined
24
+ ? []
25
+ : Array.isArray(disabled)
26
+ ? disabled
27
+ : [disabled]),
28
+ ...(min ? [{ before: min }] : []),
29
+ ...(max ? [{ after: max }] : []),
30
+ ];
31
+ return {
32
+ ...calendarProps,
33
+ disabled: matchers,
34
+ startMonth: calendarProps?.startMonth ?? min,
35
+ endMonth: calendarProps?.endMonth ?? max,
36
+ };
37
+ }
10
38
  /** Form-control trigger plus the viewport-clamped calendar popover. */
11
39
  export function PickerShell({ id, disabled, className, contentClassName, "aria-invalid": ariaInvalid, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, side, empty, label, dialogLabel, open, onOpenChange, onInteractOutside, children, }) {
12
40
  return (_jsxs(Popover, { open: open, onOpenChange: onOpenChange, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { id: id, type: "button", variant: "outline", disabled: disabled, "aria-invalid": ariaInvalid, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "data-empty": empty, className: cn(pickerTriggerClassName, className), onPointerEnter: preloadCalendar, onFocus: preloadCalendar, children: [_jsx(CalendarIcon, { "data-icon": "inline-start" }), _jsx("span", { "data-slot": "date-picker-value", id: id ? pickerValueId(id) : undefined, children: label })] }) }), _jsx(PopoverContent, { align: "start", side: side, collisionPadding: PICKER_COLLISION_PADDING, "aria-label": dialogLabel,
package/dist/toast.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ReactNode } from "react";
1
+ import { type ReactNode } from "react";
2
2
  /** Identifies a toast, to replace it in place or dismiss it. */
3
3
  type ToastId = string | number;
4
4
  /** A button in a toast. Clicking it runs `onClick`, then closes the toast. */
@@ -50,7 +50,9 @@ interface ToasterProps {
50
50
  declare const toast: Toast;
51
51
  /**
52
52
  * Mount one near the app root, and show toasts with `toast()` from this
53
- * module. Only the props declared here reach the library.
53
+ * module. Only the props declared here reach the library. The stack
54
+ * expands while keyboard focus is inside it, as it does on hover, so every
55
+ * toast's buttons are visible and reachable.
54
56
  */
55
57
  declare const Toaster: ({ position, closeButton, expand, visibleToasts, duration, }: ToasterProps) => import("react").JSX.Element;
56
58
  export { Toaster, toast };
package/dist/toast.js CHANGED
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useState } from "react";
3
4
  import { CircleAlertIcon, CircleCheckIcon, InfoIcon, LoaderCircleIcon, XIcon, } from "lucide-react";
4
5
  import { useTheme } from "next-themes";
5
6
  import { Toaster as Sonner, toast as sonnerToast, } from "sonner";
@@ -52,12 +53,18 @@ const toast = Object.assign(show(sonnerToast), {
52
53
  * is the badge itself; the X is 12px. `overflow-visible` on the toast and
53
54
  * toaster keeps stacked badges from being clipped.
54
55
  *
56
+ * Stacking: while the stack is collapsed, every part of the toasts behind
57
+ * the front one is `invisible`. Their badges would otherwise peek out above
58
+ * the front toast, closer together than the 24px target spacing, and their
59
+ * buttons would stay in the tab order unseen. Hovering or focusing the stack
60
+ * expands it (see `Toaster`), which shows them again.
61
+ *
55
62
  * Padding is asymmetric: `pl-4` matches Alert; `pr-6` clears the badge
56
63
  * (about 16px of it sits inside the border). Icon-to-text is `gap-x-2.5`
57
64
  * so the status icon and copy read as one unit.
58
65
  */
59
66
  const classNames = {
60
- toast: "relative flex w-max max-w-[min(356px,calc(100vw-2rem))] flex-wrap items-center justify-end gap-x-2.5 gap-y-2 overflow-visible rounded-none border border-border bg-popover py-3 pl-4 pr-6 text-sm text-popover-foreground shadow-md",
67
+ toast: "relative flex w-max max-w-[min(356px,calc(100vw-2rem))] flex-wrap items-center justify-end gap-x-2.5 gap-y-2 overflow-visible rounded-none border border-border bg-popover py-3 pl-4 pr-6 text-sm text-popover-foreground shadow-md data-[expanded=false]:data-[front=false]:*:invisible",
61
68
  // Fills the row beside the icon, so action buttons wrap to their own row
62
69
  // (aligned right by the toast's justify-end). Without an icon the basis
63
70
  // falls back to the title's width, so a one-word toast stays compact.
@@ -84,10 +91,18 @@ const icons = {
84
91
  };
85
92
  /**
86
93
  * Mount one near the app root, and show toasts with `toast()` from this
87
- * module. Only the props declared here reach the library.
94
+ * module. Only the props declared here reach the library. The stack
95
+ * expands while keyboard focus is inside it, as it does on hover, so every
96
+ * toast's buttons are visible and reachable.
88
97
  */
89
98
  const Toaster = ({ position, closeButton = true, expand, visibleToasts, duration, }) => {
90
99
  const { theme = "system" } = useTheme();
91
- return (_jsx(Sonner, { theme: theme, className: "toaster group overflow-visible", position: position, closeButton: closeButton, expand: expand, visibleToasts: visibleToasts, duration: duration, icons: icons, toastOptions: { unstyled: true, classNames } }));
100
+ const [focusWithin, setFocusWithin] = useState(false);
101
+ const onBlur = (event) => {
102
+ if (!event.currentTarget.contains(event.relatedTarget)) {
103
+ setFocusWithin(false);
104
+ }
105
+ };
106
+ return (_jsx("div", { "data-slot": "toaster", className: "contents", onFocus: () => setFocusWithin(true), onBlur: onBlur, children: _jsx(Sonner, { theme: theme, className: "toaster group overflow-visible", position: position, closeButton: closeButton, expand: expand || focusWithin, visibleToasts: visibleToasts, duration: duration, icons: icons, toastOptions: { unstyled: true, classNames } }) }));
92
107
  };
93
108
  export { Toaster, toast };
package/dist/toggle.d.ts CHANGED
@@ -9,7 +9,7 @@ import { Toggle as TogglePrimitive } from "radix-ui";
9
9
  declare const selectedToggleChrome: string;
10
10
  declare const toggleVariants: (props?: ({
11
11
  variant?: "default" | "outline" | null | undefined;
12
- size?: "default" | "sm" | "lg" | null | undefined;
12
+ size?: "default" | "lg" | "sm" | null | undefined;
13
13
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
14
14
  declare function Toggle({ className, variant, size, ...props }: React.ComponentProps<typeof TogglePrimitive.Root> & VariantProps<typeof toggleVariants>): React.JSX.Element;
15
15
  export { Toggle, toggleVariants, selectedToggleChrome };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atlas-react-kit",
3
- "version": "0.11.2",
3
+ "version": "0.13.0",
4
4
  "description": "Shared React components and Tailwind theme for Atlas",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -112,6 +112,10 @@
112
112
  "types": "./dist/meter.d.ts",
113
113
  "default": "./dist/meter.js"
114
114
  },
115
+ "./nav-link": {
116
+ "types": "./dist/nav-link.d.ts",
117
+ "default": "./dist/nav-link.js"
118
+ },
115
119
  "./pagination": {
116
120
  "types": "./dist/pagination.d.ts",
117
121
  "default": "./dist/pagination.js"
@@ -200,6 +204,10 @@
200
204
  "types": "./dist/tooltip.d.ts",
201
205
  "default": "./dist/tooltip.js"
202
206
  },
207
+ "./form/control-field": {
208
+ "types": "./dist/form/control-field.d.ts",
209
+ "default": "./dist/form/control-field.js"
210
+ },
203
211
  "./form/date-picker-field": {
204
212
  "types": "./dist/form/date-picker-field.d.ts",
205
213
  "default": "./dist/form/date-picker-field.js"
@@ -228,6 +236,10 @@
228
236
  "types": "./dist/form/text-field.d.ts",
229
237
  "default": "./dist/form/text-field.js"
230
238
  },
239
+ "./next/nav-link": {
240
+ "types": "./dist/next/nav-link.d.ts",
241
+ "default": "./dist/next/nav-link.js"
242
+ },
231
243
  "./next/tabs-nav-link": {
232
244
  "types": "./dist/next/tabs-nav-link.d.ts",
233
245
  "default": "./dist/next/tabs-nav-link.js"
@@ -307,10 +319,10 @@
307
319
  "@types/node": "^25.5.0",
308
320
  "@types/react": "^19.2.14",
309
321
  "@types/react-dom": "^19.2.3",
310
- "@vitest/coverage-v8": "4.1.11",
322
+ "@vitest/coverage-v8": "5.0.5",
311
323
  "date-fns": "^4.4.0",
312
324
  "jsdom": "^29.1.1",
313
- "next": "16.2.6",
325
+ "next": "16.4.2",
314
326
  "next-themes": "^0.4.6",
315
327
  "prettier": "^3.8.1",
316
328
  "react": "^19.2.4",
@@ -320,8 +332,8 @@
320
332
  "remark-gfm": "^4.0.1",
321
333
  "sonner": "^2.0.7",
322
334
  "tailwindcss": "^4.2.1",
323
- "typescript": "^6.0.3",
335
+ "typescript": "^7.0.2",
324
336
  "unified": "^11.0.5",
325
- "vitest": "^4.1.9"
337
+ "vitest": "^5.0.5"
326
338
  }
327
339
  }
@@ -61,9 +61,11 @@ Import each component from its subpath, e.g.
61
61
  | One date, or a from/to range | `DatePickerButton` from `date-picker` (`mode="range"` for ranges) |
62
62
  | Date and time (not `datetime-local`) | `DateTimePickerButton` from `date-time-picker` |
63
63
  | Labelled field with error text | `FormTextField`, `FormSelectField`, `FormDatePickerField`, `FormDateTimePickerField`, `FormMarkdownField` from `form/*` |
64
+ | Labelled custom control (combobox) in a form | `FormControlField` from `form/control-field` |
64
65
  | Form-level error (save failed) | `FormFeedbackField` from `form/feedback-field` |
65
66
  | Content panels on one page | `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent` from `tabs` |
66
67
  | View switch that changes the URL | `TabsNav` with links: `TabsNavLink` from `next/tabs-nav-link` in Next, else `tabsTriggerVariants()` |
68
+ | App shell nav (Calendar, Tasks, Settings) | `NavLink` from `nav-link` (`asChild` for a router link); Next: `next/nav-link` |
67
69
  | Status chip (paid, pending, failed) | `Badge variant="soft"` with `tone="success"`, `"warning"`, `"destructive"`, or `"neutral"` |
68
70
  | Data table | `Table` family from `table`; `SortableTableHead`; `TableBodySkeleton` while loading |
69
71
  | Nothing to show yet | `EmptyPanel` from `empty-panel` |