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.
- package/COMPONENTS.md +176 -83
- package/DESIGN_RULES.md +14 -1
- package/README.md +3 -3
- package/dist/alert.d.ts +1 -1
- package/dist/badge.d.ts +2 -2
- package/dist/button.d.ts +2 -2
- package/dist/date-picker.d.ts +3 -9
- package/dist/date-picker.js +8 -38
- package/dist/date-time-picker.d.ts +1 -1
- package/dist/date-time-picker.js +3 -3
- package/dist/error-boundary.d.ts +1 -1
- package/dist/field.d.ts +1 -1
- package/dist/form/control-field.d.ts +31 -0
- package/dist/form/control-field.js +22 -0
- package/dist/form/date-picker-field.d.ts +9 -3
- package/dist/form/date-picker-field.js +3 -3
- package/dist/form/date-time-picker-field.d.ts +10 -4
- package/dist/form/date-time-picker-field.js +3 -3
- package/dist/form/field-error.d.ts +18 -0
- package/dist/form/field-shell.d.ts +29 -10
- package/dist/form/field-shell.js +37 -11
- package/dist/form/markdown-field.d.ts +4 -2
- package/dist/form/markdown-field.js +3 -3
- package/dist/form/select-field.d.ts +5 -3
- package/dist/form/select-field.js +3 -3
- package/dist/form/text-field.d.ts +3 -4
- package/dist/form/text-field.js +6 -6
- package/dist/internal/date-like.d.ts +31 -0
- package/dist/internal/date-like.js +33 -0
- package/dist/label.d.ts +16 -1
- package/dist/label.js +7 -3
- package/dist/nav-link.d.ts +22 -0
- package/dist/nav-link.js +31 -0
- package/dist/next/nav-link.d.ts +11 -0
- package/dist/next/nav-link.js +14 -0
- package/dist/picker-shell.d.ts +48 -6
- package/dist/picker-shell.js +28 -0
- package/dist/toast.d.ts +4 -2
- package/dist/toast.js +18 -3
- package/dist/toggle.d.ts +1 -1
- package/package.json +17 -5
- package/skills/atlas-react-kit/SKILL.md +2 -0
package/COMPONENTS.md
CHANGED
|
@@ -26,62 +26,65 @@ theme from `next-themes`, so toast consumers install that too.
|
|
|
26
26
|
| `markdown`, `form/markdown-field` | `npm i react-markdown@^10.1.0 remark-gfm@^4.0.1` |
|
|
27
27
|
| `theme-provider` | `npm i next-themes@^0.4.6` |
|
|
28
28
|
| `toast` | `npm i sonner@^2.0.7 next-themes@^0.4.6` |
|
|
29
|
-
| `next/tabs-nav-link`
|
|
30
|
-
|
|
31
|
-
| Subpath | Main exports and options
|
|
32
|
-
| ----------------------------- |
|
|
33
|
-
| `accordion` | `Accordion`, `AccordionItem`, `AccordionTrigger`, `AccordionContent`; Radix `type` `single` (with `collapsible`) or `multiple`
|
|
34
|
-
| `alert` | `Alert`, `AlertTitle`, `AlertDescription`, `alertVariants`; `variant` `default`, `success`, `warning`, `destructive`; tone on title and icon, body stays muted; destructive is `role="alert"`
|
|
35
|
-
| `avatar` | `Avatar`, `AvatarImage`, `AvatarFallback`; `size` `sm`, `default`, `lg`; round by design
|
|
36
|
-
| `breadcrumb` | `Breadcrumb`, `BreadcrumbList`, `BreadcrumbItem`, `BreadcrumbLink` (`asChild` for router links), `BreadcrumbPage` (`aria-current`), `BreadcrumbSeparator`, `BreadcrumbEllipsis`
|
|
37
|
-
| `button` | `Button`, `buttonVariants`, `quietButtonInteraction`; `variant`, `size`, `asChild`; outline/ghost hover is brand purple + selected wash, not muted grey
|
|
38
|
-
| `badge` | `Badge`, `badgeVariants`; `variant`, `tone`, `asChild`
|
|
39
|
-
| `calendar` | `Calendar`, `CalendarDayButton`; React Day Picker props and `buttonVariant`
|
|
40
|
-
| `card` | `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardAction`, `CardContent`, `CardFooter`; `Card` supports `flush`; `CardTitle as="h2"` (up to `h4`) makes it a section heading; 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 `!`
|
|
41
|
-
| `checkbox` | `Checkbox`
|
|
42
|
-
| `color-legend` | `ColorLegend`; `title`, `items` as `{ color, range?, label }[]`, optional `caption`, `children`, `aria-label`, `className` (overlay chrome). No attribution.
|
|
43
|
-
| `combobox` | `Combobox`; `options` as `{ value, label }[]`, `value`, `onValueChange`; optional placeholder, search, empty text, `creatable`, `normalizeCreateValue` (query → value or `null`), `createLabel`; trigger matches Input/SelectTrigger chrome; keyboard highlight scrolls into view; create is a listbox option selected with Enter
|
|
44
|
-
| `date-picker` | `DatePickerButton`, `toDate`, `formatLocalDate`, `DateRange
|
|
45
|
-
| `date-time-picker` | `DateTimePickerButton`, `resolveTimeStep`, `DEFAULT_TIME_STEP`; controlled `value` is `Date` or `null`; `onChange` emits `Date \
|
|
46
|
-
| `dialog` | `Dialog`, trigger, portal, overlay, content, close, header, footer, title, description; `DialogContent` supports `showCloseButton`
|
|
47
|
-
| `dropdown-menu` | `DropdownMenu` family (trigger, content, item, checkbox/radio items, label, separator, shortcut, sub menus); item `variant="destructive"` and `inset`; for commands, not values
|
|
48
|
-
| `empty-panel` | `EmptyPanel`; required `children`; optional `size`, `muted`, `className`
|
|
49
|
-
| `error-boundary` | `ErrorBoundary`, `ErrorFallback`; optional `message`; retry resets, reload refreshes the page
|
|
50
|
-
| `field` | Field, label, legend, description, group, set, title, content, separator, error; `Field` supports `orientation`
|
|
51
|
-
| `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.
|
|
52
|
-
| `input`, `textarea`, `label` | `Input`, `Textarea`, `Label`
|
|
53
|
-
| `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.
|
|
54
|
-
| `meter` | `Meter`; `value`, `max`, optional `min` (default 0), `fillClassName`, `markers` as `{ position, className? }[]`, required `aria-label`, `className`. `role="meter"`. Not `Progress`.
|
|
55
|
-
| `
|
|
56
|
-
| `
|
|
57
|
-
| `
|
|
58
|
-
| `
|
|
59
|
-
| `
|
|
60
|
-
| `
|
|
61
|
-
| `separator
|
|
62
|
-
| `
|
|
63
|
-
| `
|
|
64
|
-
| `
|
|
65
|
-
| `
|
|
66
|
-
| `
|
|
67
|
-
| `
|
|
68
|
-
| `table
|
|
69
|
-
| `
|
|
70
|
-
| `
|
|
71
|
-
| `
|
|
72
|
-
| `toggle
|
|
73
|
-
| `
|
|
74
|
-
| `
|
|
75
|
-
| `
|
|
76
|
-
| `form/
|
|
77
|
-
| `form/
|
|
78
|
-
| `form/
|
|
79
|
-
| `form/
|
|
80
|
-
| `form/field
|
|
81
|
-
| `form/
|
|
82
|
-
| `
|
|
83
|
-
| `
|
|
84
|
-
| `
|
|
29
|
+
| `next/nav-link`, `next/tabs-nav-link` | `npm i next@^16.0.0` |
|
|
30
|
+
|
|
31
|
+
| Subpath | Main exports and options |
|
|
32
|
+
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
33
|
+
| `accordion` | `Accordion`, `AccordionItem`, `AccordionTrigger`, `AccordionContent`; Radix `type` `single` (with `collapsible`) or `multiple` |
|
|
34
|
+
| `alert` | `Alert`, `AlertTitle`, `AlertDescription`, `alertVariants`; `variant` `default`, `success`, `warning`, `destructive`; tone on title and icon, body stays muted; destructive is `role="alert"` |
|
|
35
|
+
| `avatar` | `Avatar`, `AvatarImage`, `AvatarFallback`; `size` `sm`, `default`, `lg`; round by design |
|
|
36
|
+
| `breadcrumb` | `Breadcrumb`, `BreadcrumbList`, `BreadcrumbItem`, `BreadcrumbLink` (`asChild` for router links), `BreadcrumbPage` (`aria-current`), `BreadcrumbSeparator`, `BreadcrumbEllipsis` |
|
|
37
|
+
| `button` | `Button`, `buttonVariants`, `quietButtonInteraction`; `variant`, `size`, `asChild`; outline/ghost hover is brand purple + selected wash, not muted grey |
|
|
38
|
+
| `badge` | `Badge`, `badgeVariants`; `variant`, `tone`, `asChild` |
|
|
39
|
+
| `calendar` | `Calendar`, `CalendarDayButton`; React Day Picker props and `buttonVariant` |
|
|
40
|
+
| `card` | `Card`, `CardHeader`, `CardTitle`, `CardDescription`, `CardAction`, `CardContent`, `CardFooter`; `Card` supports `flush`; `CardTitle as="h2"` (up to `h4`) makes it a section heading; 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 `!` |
|
|
41
|
+
| `checkbox` | `Checkbox` |
|
|
42
|
+
| `color-legend` | `ColorLegend`; `title`, `items` as `{ color, range?, label }[]`, optional `caption`, `children`, `aria-label`, `className` (overlay chrome). No attribution. |
|
|
43
|
+
| `combobox` | `Combobox`; `options` as `{ value, label }[]`, `value`, `onValueChange`; optional placeholder, search, empty text, `creatable`, `normalizeCreateValue` (query → value or `null`), `createLabel`; trigger matches Input/SelectTrigger chrome; keyboard highlight scrolls into view; create is a listbox option selected with Enter |
|
|
44
|
+
| `date-picker` | `DatePickerButton`, `toDate`, `formatLocalDate`, and the kit's own `DateRange`, `DateMatcher`, `DateLike`, and `DatePickerCalendarProps` types (no Day Picker types); `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+`), `minDate` / `maxDate` (days outside are disabled), `side`, `aria-labelledby`, and `aria-describedby` |
|
|
45
|
+
| `date-time-picker` | `DateTimePickerButton`, `resolveTimeStep`, `DEFAULT_TIME_STEP`; controlled `value` is `Date` or `null`; `onChange` emits `Date \ |
|
|
46
|
+
| `dialog` | `Dialog`, trigger, portal, overlay, content, close, header, footer, title, description; `DialogContent` supports `showCloseButton` |
|
|
47
|
+
| `dropdown-menu` | `DropdownMenu` family (trigger, content, item, checkbox/radio items, label, separator, shortcut, sub menus); item `variant="destructive"` and `inset`; for commands, not values |
|
|
48
|
+
| `empty-panel` | `EmptyPanel`; required `children`; optional `size`, `muted`, `className` |
|
|
49
|
+
| `error-boundary` | `ErrorBoundary`, `ErrorFallback`; optional `message`; retry resets, reload refreshes the page |
|
|
50
|
+
| `field` | Field, label, legend, description, group, set, title, content, separator, error; `Field` supports `orientation` |
|
|
51
|
+
| `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. |
|
|
52
|
+
| `input`, `textarea`, `label` | `Input`, `Textarea`, `Label`; `Label` `required` shows a visible marker (set `required` on the control too) |
|
|
53
|
+
| `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. |
|
|
54
|
+
| `meter` | `Meter`; `value`, `max`, optional `min` (default 0), `fillClassName`, `markers` as `{ position, className? }[]`, required `aria-label`, `className`. `role="meter"`. Not `Progress`. |
|
|
55
|
+
| `nav-link` | `NavLink`, `navLinkVariants`; required `active` boolean, `asChild` for router links. Pill chrome: inactive `text-muted-foreground` + `hover:bg-accent`, active selected wash. No router. |
|
|
56
|
+
| `pagination` | `Pagination`, `PaginationContent`, `PaginationItem`, `PaginationLink` (`isActive` sets `aria-current`, the selected wash, and a selected border; `disabled` drops the `href` for a page that does not exist, such as Previous on page 1), `PaginationPrevious`, `PaginationNext` (custom text becomes the link name), `PaginationEllipsis` |
|
|
57
|
+
| `popover` | `Popover`, trigger, anchor, content, header, title, description |
|
|
58
|
+
| `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`. |
|
|
59
|
+
| `radio-group` | `RadioGroup`, `RadioGroupItem`; short visible lists; arrow keys move the selection; round dots |
|
|
60
|
+
| `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. |
|
|
61
|
+
| `select` | Select, trigger, value, content, group, label, item, separator, scroll buttons; trigger `size`; trigger text is `text-base md:text-sm` like Input |
|
|
62
|
+
| `separator`, `skeleton` | `Separator`, `Skeleton` |
|
|
63
|
+
| `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`. |
|
|
64
|
+
| `sortable-table-head` | `SortableTableHead`; `sorted`, `direction` (`asc` \ |
|
|
65
|
+
| `spinner` | `Spinner`; `role="status"` with `aria-label` (default `Loading`) |
|
|
66
|
+
| `stat-tile` | `StatTile`, `statTileGrid`, `sectionLabel`; `label`, `value`, optional `sub`, `children`, `className`. |
|
|
67
|
+
| `switch` | `Switch`; settings that apply immediately; square track and thumb |
|
|
68
|
+
| `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` |
|
|
69
|
+
| `table-body-skeleton` | `TableBodySkeleton`; `columns`, optional `rows` (default 5) |
|
|
70
|
+
| `tabs` | `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent`, `TabsNav`, `tabsListVariants`, `tabsTriggerVariants`; list `variant` is `default` or `line`; style `TabsNav` links with `tabsTriggerVariants()`; `TabsNav` / `TabsList` scroll horizontally only (`overflow-y` hidden, `p-1` counted in the scroller height, edge fade, active item into view) — do not wrap them in `overflow-x-auto` |
|
|
71
|
+
| `toast` | `Toaster`, `toast`; mount one `Toaster` (`position`, `closeButton` (default on), `expand`, `visibleToasts`, `duration`), then `toast(message, options)`. The stack expands on hover and while keyboard focus is inside it; collapsed toasts behind the front one are hidden, `.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 |
|
|
72
|
+
| `toggle` | `Toggle`, `toggleVariants`, `selectedToggleChrome`; `variant`, `size`. Pressed state is the selected wash, text, and border via `data-state=on`, `aria-pressed`, and `aria-checked` |
|
|
73
|
+
| `toggle-group` | `ToggleGroup`, `ToggleGroupItem`; `variant`, `size`. Items share `toggleVariants`, so single (radio) and multiple selections match a pressed `Toggle` |
|
|
74
|
+
| `theme-provider` | `ThemeProvider`, `useTheme`; optional `storageKey` (default `atlas-theme`), `enableShortcut` for the `d` toggle |
|
|
75
|
+
| `tooltip` | `Tooltip`, `TooltipTrigger`, `TooltipContent`, `TooltipProvider`; opens on hover and focus; short labels only |
|
|
76
|
+
| `form/control-field` | `FormControlField`, type `FormControlProps`; `label`, optional `id`, `description`, `required`, `meta`, `submitted`, `showError`; `children` renders the control from `{ id, aria-invalid, aria-describedby, aria-required }` |
|
|
77
|
+
| `form/markdown-field` | `FormMarkdownField`; `field` is `TextFieldApi`; `label`, optional `id`, `placeholder`, `rows`, `showError`, `required`. Write / preview; preview uses `Markdown`. |
|
|
78
|
+
| `form/text-field` | `FormTextField`, type `TextFieldApi`; controlled field, label, multiline, description, input constraints; `required` also marks the label |
|
|
79
|
+
| `form/select-field` | `FormSelectField`; `value`, `onValueChange`, `label`, optional `meta`, placeholder, and `required`; select item children |
|
|
80
|
+
| `form/date-picker-field` | `FormDatePickerField`; `value`, `onValueChange`, `label`, optional `meta`, placeholder, `required`, `minDate` / `maxDate`, and `className` (forwarded to the trigger) |
|
|
81
|
+
| `form/date-time-picker-field` | `FormDateTimePickerField`; `value` is `Date` or `null`; `onValueChange` emits `Date` or `null`; optional `meta`, placeholder, `timeStep`, `required`, `minDate` / `maxDate`, and `className` (forwarded to the trigger) |
|
|
82
|
+
| `form/field-error` | `FieldError` (optional `id`), `getFieldErrorMessage`; types `FieldErrorMessage`, `FieldMetaState`, `ErrorTimingProps` |
|
|
83
|
+
| `form/feedback-field` | `FormFeedbackField`; nullable `message` |
|
|
84
|
+
| `next/nav-link` | `NavLink`; Next Link props and required `active` boolean; same pill as `nav-link`; requires Next.js 16 |
|
|
85
|
+
| `next/tabs-nav-link` | `TabsNavLink`; Next Link props and required `active` boolean; requires Next.js 16 |
|
|
86
|
+
| `utils` | `cn`, `onInputChange` |
|
|
87
|
+
| `theme.css` | Tailwind 4 theme; installation in [README](./README.md) |
|
|
85
88
|
|
|
86
89
|
## Status
|
|
87
90
|
|
|
@@ -90,11 +93,10 @@ through the deprecation policy in
|
|
|
90
93
|
[CONTRIBUTING.md](https://github.com/Kerubi-5/atlas-design-system/blob/main/CONTRIBUTING.md):
|
|
91
94
|
a deprecation notice first, removal in a later minor release.
|
|
92
95
|
|
|
93
|
-
**Beta** components may still change shape in a minor release
|
|
94
|
-
changelog calls out every
|
|
95
|
-
`
|
|
96
|
-
`
|
|
97
|
-
`slider`, `spinner`, `stat-tile`, `switch`, `tooltip`.
|
|
96
|
+
**Beta** components may still change shape in a minor release, before and
|
|
97
|
+
after 1.0; they are exempt from semver, and the changelog calls out every
|
|
98
|
+
change: `accordion`, `avatar`, `breadcrumb`, `dropdown-menu`, `nav-link`,
|
|
99
|
+
`pagination`, `radio-group`, `spinner`, `switch`.
|
|
98
100
|
|
|
99
101
|
## Styling parts
|
|
100
102
|
|
|
@@ -103,26 +105,27 @@ through to it. Where a part sits inside a component, a prop names it, and
|
|
|
103
105
|
each part carries a `data-slot` for parent selectors such as
|
|
104
106
|
`*:data-[slot=stat-tile-value]:text-2xl`.
|
|
105
107
|
|
|
106
|
-
| Component | Part props
|
|
107
|
-
| -------------------------------------------------- |
|
|
108
|
-
| `DialogContent` | `overlayClassName`, `closeButtonClassName`
|
|
109
|
-
| `SelectTrigger` | a `className` height replaces `size`
|
|
110
|
-
| `TooltipContent` | `arrowClassName`
|
|
111
|
-
| `Combobox` | `contentClassName` (panel, default trigger width), `listClassName`; button props go to trigger
|
|
112
|
-
| `SearchPicker` | `listClassName`; div props go to the root
|
|
113
|
-
| `InfoTip` | `contentClassName`; button props go to the trigger
|
|
114
|
-
| `
|
|
115
|
-
| `
|
|
116
|
-
| `
|
|
117
|
-
| `
|
|
118
|
-
| `
|
|
119
|
-
| `
|
|
120
|
-
| `
|
|
121
|
-
| `
|
|
122
|
-
| `
|
|
123
|
-
| `
|
|
124
|
-
| `
|
|
125
|
-
| `
|
|
108
|
+
| Component | Part props | Slots |
|
|
109
|
+
| -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
110
|
+
| `DialogContent` | `overlayClassName`, `closeButtonClassName` | `dialog-close-button` (the built-in X; your own `DialogClose` keeps `dialog-close`) |
|
|
111
|
+
| `SelectTrigger` | a `className` height replaces `size` | `select-icon`, `select-viewport`, `select-item-indicator` |
|
|
112
|
+
| `TooltipContent` | `arrowClassName` | `tooltip-arrow` |
|
|
113
|
+
| `Combobox` | `contentClassName` (panel, default trigger width), `listClassName`; button props go to trigger | `combobox-search`, `combobox-list`, `combobox-option` |
|
|
114
|
+
| `SearchPicker` | `listClassName`; div props go to the root | `search-picker-option`, `search-picker-empty` |
|
|
115
|
+
| `InfoTip` | `contentClassName`; button props go to the trigger | |
|
|
116
|
+
| `Label`, `FieldLabel` | `requiredClassName` | `label-required` |
|
|
117
|
+
| `DatePickerButton`, `DateTimePickerButton` | `contentClassName`, `calendarProps` (`disabled` / `hidden` days, `startMonth`, `endMonth`, `weekStartsOn`, date-fns `locale`, `showOutsideDays`, `fixedWeeks`, `showWeekNumber`, `captionLayout`, `today`, `className`); `minDate` / `maxDate` add to its disabled days | `date-picker-value`, `date-picker-footer`, `date-time-picker-time` |
|
|
118
|
+
| `form/*` fields | `fieldClassName` (wrapper); `className` styles the control (on `FormControlField`, the wrapper); `FormSelectField` `contentClassName`; `FormMarkdownField` `previewClassName` | `form-field`, `form-field-header`, `form-field-description`, `form-field-error`, `form-feedback`, `form-markdown-preview` |
|
|
119
|
+
| `Table` | `containerClassName` (the scroll box, e.g. `max-h-96 overflow-y-auto`); `className` styles the `<table>` | |
|
|
120
|
+
| `TabsList`, `TabsNav` | `scrollerClassName`; `TabsNav` `listClassName`; a list `className` height replaces `h-11` | `tabs-scroller` |
|
|
121
|
+
| `SortableTableHead` | `buttonClassName` | `sortable-table-head-button` |
|
|
122
|
+
| `AccordionTrigger`, `AccordionContent` | `headerClassName`; `AccordionContent` `className` styles the inner box | `accordion-header`, `accordion-content-inner` |
|
|
123
|
+
| `Progress` | `indicatorClassName` | `progress-indicator` |
|
|
124
|
+
| `Meter` | `fillClassName` | `meter-fill`, `meter-marker` |
|
|
125
|
+
| `StatTile` | | `stat-tile-label`, `stat-tile-value`, `stat-tile-sub` |
|
|
126
|
+
| `ColorLegend` | | `color-legend-title`, `-list`, `-item`, `-swatch`, `-range`, `-label`, `-caption` |
|
|
127
|
+
| `RadioGroupItem` | | `radio-group-dot` |
|
|
128
|
+
| `EmptyPanel`, `ErrorFallback`, `TableBodySkeleton` | `className` | `empty-panel`, `error-boundary` |
|
|
126
129
|
|
|
127
130
|
## Forms
|
|
128
131
|
|
|
@@ -133,7 +136,10 @@ type TextFieldApi = {
|
|
|
133
136
|
name: string
|
|
134
137
|
state: {
|
|
135
138
|
value: string
|
|
136
|
-
meta: {
|
|
139
|
+
meta: {
|
|
140
|
+
errors: (string | { message?: string } | undefined)[]
|
|
141
|
+
isTouched?: boolean
|
|
142
|
+
}
|
|
137
143
|
}
|
|
138
144
|
handleChange: (value: string) => void
|
|
139
145
|
handleBlur: () => void
|
|
@@ -155,6 +161,45 @@ description. The date fields label their trigger with `aria-labelledby` (the
|
|
|
155
161
|
label, then the trigger) rather than `<label for>`, so the picked date is
|
|
156
162
|
part of its name.
|
|
157
163
|
|
|
164
|
+
Errors wait for the person. When `meta.isTouched` is `false`, a `form/*`
|
|
165
|
+
field hides its error text and invalid styling until the field is touched or
|
|
166
|
+
its `submitted` prop is set (TanStack Form:
|
|
167
|
+
`form.state.submissionAttempts > 0`). Pass TanStack's `field.state.meta` as
|
|
168
|
+
is and this works on its own; meta without `isTouched` shows errors as soon
|
|
169
|
+
as they exist, as before. `showError={false}` always hides them. Every
|
|
170
|
+
`form/*` field, `FormSelectField` and both date fields included, takes
|
|
171
|
+
`submitted` and `showError`.
|
|
172
|
+
|
|
173
|
+
`FormControlField` gives a control the kit does not ship the same label,
|
|
174
|
+
required marker, hint, error, ids, and error timing. `children` is a
|
|
175
|
+
function that receives the props to spread on the control:
|
|
176
|
+
|
|
177
|
+
```tsx
|
|
178
|
+
<div className="grid grid-cols-2 items-start gap-3">
|
|
179
|
+
<FormTextField field={amount} label="Amount" required />
|
|
180
|
+
<FormControlField label="Currency" meta={currency.state.meta}>
|
|
181
|
+
{(control) => (
|
|
182
|
+
<Combobox
|
|
183
|
+
{...control}
|
|
184
|
+
options={options}
|
|
185
|
+
value={value}
|
|
186
|
+
onValueChange={set}
|
|
187
|
+
/>
|
|
188
|
+
)}
|
|
189
|
+
</FormControlField>
|
|
190
|
+
</div>
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Errors sit below the control and take no space until they show, so use
|
|
194
|
+
`items-start` on a row of fields to keep the controls on one top edge.
|
|
195
|
+
|
|
196
|
+
Set `required` on a `form/*` field to mark its label with a visible `*`.
|
|
197
|
+
The marker is hidden from screen readers, which announce the control's own
|
|
198
|
+
`required` (`aria-required` on the select trigger). The date pickers are
|
|
199
|
+
buttons, which cannot be required, so their fields add "Required" to the
|
|
200
|
+
trigger's description instead. Outside the form adapters, `<Label required>`
|
|
201
|
+
draws the same marker; set `required` on the control yourself.
|
|
202
|
+
|
|
158
203
|
`DatePickerButton` is single-day by default. For a from/to range, set
|
|
159
204
|
`mode="range"`; `value` is `{ from, to }` (each side `Date` or `yyyy-MM-dd`)
|
|
160
205
|
and `onChange` receives `DateRange | undefined`. The trigger uses the same
|
|
@@ -163,6 +208,10 @@ one month below `md` and two months at `md+` unless `numberOfMonths` is set,
|
|
|
163
208
|
clamps to the viewport with collision padding and scroll, stays `w-auto` so
|
|
164
209
|
it does not collapse to the default popover width, and includes a Clear
|
|
165
210
|
action. Pass `side` to prefer a placement; Radix still flips on collision.
|
|
211
|
+
`minDate` and `maxDate` (each `Date` or `yyyy-MM-dd`) disable the days
|
|
212
|
+
outside them, on top of any `calendarProps.disabled`, and stop month paging
|
|
213
|
+
there unless `calendarProps` sets `startMonth` / `endMonth`. They limit the
|
|
214
|
+
calendar only; validate a value set some other way in your form.
|
|
166
215
|
The popover is a dialog named "Choose date" ("Choose dates" in range mode),
|
|
167
216
|
and focus moves to the selected day, or today, when it opens. Pass
|
|
168
217
|
`aria-labelledby` and `aria-describedby` to name and describe the trigger;
|
|
@@ -250,6 +299,50 @@ choice under `atlas-theme` unless `storageKey` is set. The `d` dark/light toggle
|
|
|
250
299
|
is off by default; pass `enableShortcut` to turn it on, and give people a setting
|
|
251
300
|
to turn it off again, since a single-key shortcut can fire by accident (WCAG 2.1.4).
|
|
252
301
|
|
|
302
|
+
## App shell navigation
|
|
303
|
+
|
|
304
|
+
Pill links for top-level destinations (Calendar, Tasks, Settings). Pass
|
|
305
|
+
`active` from the route; the kit does not read the URL. Wrap a router link
|
|
306
|
+
with `asChild`, or use the optional Next adapter.
|
|
307
|
+
|
|
308
|
+
```tsx
|
|
309
|
+
import Link from "next/link"
|
|
310
|
+
import { NavLink } from "atlas-react-kit/nav-link"
|
|
311
|
+
|
|
312
|
+
export function AppNav({ pathname }: { pathname: string }) {
|
|
313
|
+
return (
|
|
314
|
+
<nav aria-label="App" className="flex items-center gap-1">
|
|
315
|
+
<NavLink asChild active={pathname === "/calendar"}>
|
|
316
|
+
<Link href="/calendar">Calendar</Link>
|
|
317
|
+
</NavLink>
|
|
318
|
+
<NavLink asChild active={pathname === "/tasks"}>
|
|
319
|
+
<Link href="/tasks">Tasks</Link>
|
|
320
|
+
</NavLink>
|
|
321
|
+
</nav>
|
|
322
|
+
)
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
```tsx
|
|
327
|
+
import { NavLink } from "atlas-react-kit/next/nav-link"
|
|
328
|
+
|
|
329
|
+
export function AppNav({ pathname }: { pathname: string }) {
|
|
330
|
+
return (
|
|
331
|
+
<nav aria-label="App" className="flex items-center gap-1">
|
|
332
|
+
<NavLink href="/calendar" active={pathname === "/calendar"}>
|
|
333
|
+
Calendar
|
|
334
|
+
</NavLink>
|
|
335
|
+
<NavLink href="/tasks" active={pathname === "/tasks"}>
|
|
336
|
+
Tasks
|
|
337
|
+
</NavLink>
|
|
338
|
+
</nav>
|
|
339
|
+
)
|
|
340
|
+
}
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
In-page view switches that still belong in the URL use `TabsNav`, not
|
|
344
|
+
`NavLink`.
|
|
345
|
+
|
|
253
346
|
## URL navigation in Next.js
|
|
254
347
|
|
|
255
348
|
```tsx
|
|
@@ -297,5 +390,5 @@ export function ViewSwitcher({ view }: { view: string }) {
|
|
|
297
390
|
```
|
|
298
391
|
|
|
299
392
|
Hook-driven controls and form handlers declare their client boundary; presentational
|
|
300
|
-
modules such as `button`, `badge`, `card`, and `skeleton` can be composed from
|
|
393
|
+
modules such as `button`, `badge`, `card`, `nav-link`, and `skeleton` can be composed from
|
|
301
394
|
React Server Components. Pass interactive callbacks from client components.
|
package/DESIGN_RULES.md
CHANGED
|
@@ -138,9 +138,22 @@ or its `data-slot`.
|
|
|
138
138
|
`text-base md:text-sm`, `border-input`, and `shadow-xs`. Do not restyle those
|
|
139
139
|
triggers as outline buttons in application code.
|
|
140
140
|
|
|
141
|
+
`form/*` fields stack label, hint, control, and error with `gap-1.5`, and the
|
|
142
|
+
error sits below the control. It takes no space until it shows, so a row of
|
|
143
|
+
fields keeps its controls on one top edge only with `items-start`
|
|
144
|
+
(`grid grid-cols-2 items-start gap-3`); the default `stretch` is fine for a
|
|
145
|
+
single column. Wrap a control the kit does not ship (a combobox, a segmented
|
|
146
|
+
picker) in `FormControlField` instead of `Field` and `FieldLabel`, whose
|
|
147
|
+
`gap-3` spacing does not match. A field shows its error once
|
|
148
|
+
`meta.isTouched` is true or `submitted` is set, never on a field the person
|
|
149
|
+
has not reached yet.
|
|
150
|
+
|
|
141
151
|
Use `Tabs` with actual `TabsContent` panels. For URL view switches, use a labelled
|
|
142
152
|
`TabsNav` with links and `aria-current="page"` on the active link. The optional
|
|
143
|
-
Next adapter provides `TabsNavLink` with this behavior.
|
|
153
|
+
Next adapter provides `TabsNavLink` with this behavior. App-shell destinations
|
|
154
|
+
(Calendar, Tasks, Settings) use `NavLink` from `nav-link`: a pill with `active`
|
|
155
|
+
from the app, not tabs. Pass `asChild` for a router link, or use the optional
|
|
156
|
+
Next adapter `next/nav-link`. `TabsNav` and `TabsList`
|
|
144
157
|
scroll overflowing labels inside themselves (`overflow-x-auto overflow-y-hidden`,
|
|
145
158
|
with padding for the active border and focus ring counted in the scroller
|
|
146
159
|
height, and an edge fade like `Table`). Do not wrap them in another
|
package/README.md
CHANGED
|
@@ -5,10 +5,10 @@ colors, and distinct selected states. 0.6.0 added generic pieces apps were
|
|
|
5
5
|
keeping locally (`InfoTip`, `ColorLegend`, `SearchPicker`, `Markdown`,
|
|
6
6
|
`StatTile`, `Meter`, `Slider`) plus the ToggleGroup selected-state fix.
|
|
7
7
|
React 19, Tailwind 4, and Node >=20.19 are required. Next 16 is needed only
|
|
8
|
-
when using `next/tabs-nav-link`.
|
|
8
|
+
when using `next/nav-link` or `next/tabs-nav-link`.
|
|
9
9
|
|
|
10
10
|
```sh
|
|
11
|
-
npm install --save-exact atlas-react-kit@0.
|
|
11
|
+
npm install --save-exact atlas-react-kit@0.12.0
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
Import components by subpath:
|
|
@@ -128,7 +128,7 @@ artifact with the package owner's npm login:
|
|
|
128
128
|
```sh
|
|
129
129
|
mkdir -p release-artifacts
|
|
130
130
|
npm pack --pack-destination release-artifacts
|
|
131
|
-
npm publish ./release-artifacts/atlas-react-kit-0.
|
|
131
|
+
npm publish ./release-artifacts/atlas-react-kit-0.12.0.tgz --access public
|
|
132
132
|
```
|
|
133
133
|
|
|
134
134
|
Pin an exact package version in consuming applications. Roll back an upgrade by
|
package/dist/alert.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { type VariantProps } from "class-variance-authority";
|
|
|
6
6
|
* (the destructive tint is too faint for text in light mode).
|
|
7
7
|
*/
|
|
8
8
|
declare const alertVariants: (props?: ({
|
|
9
|
-
variant?: "default" | "
|
|
9
|
+
variant?: "default" | "destructive" | "success" | "warning" | null | undefined;
|
|
10
10
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
11
11
|
/**
|
|
12
12
|
* Inline message about the page or a section (save failed, trial ending).
|
package/dist/badge.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { type VariantProps } from "class-variance-authority";
|
|
3
3
|
declare const badgeVariants: (props?: ({
|
|
4
|
-
variant?: "default" | "
|
|
5
|
-
tone?: "
|
|
4
|
+
variant?: "default" | "destructive" | "ghost" | "link" | "outline" | "secondary" | "soft" | null | undefined;
|
|
5
|
+
tone?: "destructive" | "neutral" | "success" | "warning" | null | undefined;
|
|
6
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
7
|
declare function Badge({ className, variant, tone, asChild, ...props }: React.ComponentProps<"span"> & VariantProps<typeof badgeVariants> & {
|
|
8
8
|
asChild?: boolean;
|
package/dist/button.d.ts
CHANGED
|
@@ -8,8 +8,8 @@ import { type VariantProps } from "class-variance-authority";
|
|
|
8
8
|
*/
|
|
9
9
|
declare const quietButtonInteraction: string;
|
|
10
10
|
declare const buttonVariants: (props?: ({
|
|
11
|
-
variant?: "default" | "
|
|
12
|
-
size?: "default" | "
|
|
11
|
+
variant?: "default" | "destructive" | "ghost" | "link" | "outline" | "secondary" | null | undefined;
|
|
12
|
+
size?: "default" | "icon" | "icon-lg" | "icon-sm" | "icon-xs" | "lg" | "sm" | "xs" | null | undefined;
|
|
13
13
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
14
14
|
declare function Button({ className, variant, size, asChild, ...props }: React.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
|
|
15
15
|
asChild?: boolean;
|
package/dist/date-picker.d.ts
CHANGED
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import type
|
|
2
|
+
import { toDate, type DateLike, type DateMatcher, type DateRange } from "./internal/date-like.js";
|
|
3
3
|
import { type PickerCalendarProps, type PickerTriggerProps } from "./picker-shell.js";
|
|
4
|
-
export type { DateRange };
|
|
5
|
-
export
|
|
4
|
+
export type { DateLike, DateMatcher, DateRange };
|
|
5
|
+
export { toDate };
|
|
6
6
|
/** From/to value for `DatePickerButton` in range mode; each side is `DateLike`. */
|
|
7
7
|
export type DatePickerRangeValue = {
|
|
8
8
|
from?: DateLike;
|
|
9
9
|
to?: DateLike;
|
|
10
10
|
};
|
|
11
|
-
/**
|
|
12
|
-
* Coerce a date-like value to a local `Date`.
|
|
13
|
-
* Plain calendar dates (`yyyy-MM-dd`) parse as local midnight so they do not
|
|
14
|
-
* shift when the runtime timezone is behind UTC.
|
|
15
|
-
*/
|
|
16
|
-
export declare function toDate(value: DateLike): Date | undefined;
|
|
17
11
|
/** Format a Date as a timezone-safe calendar date (`yyyy-MM-dd`). */
|
|
18
12
|
export declare function formatLocalDate(date: Date): string;
|
|
19
13
|
export type { PickerCalendarProps as DatePickerCalendarProps };
|