atlas-react-kit 0.4.0 → 0.4.1

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 CHANGED
@@ -5,39 +5,39 @@ 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
- | `button` | `Button`, `buttonVariants`, `quietButtonInteraction`; `variant`, `size`, `asChild`; outline/ghost hover is brand purple + selected wash, not muted grey |
11
- | `badge` | `Badge`, `badgeVariants`; `variant`, `tone`, `asChild` |
12
- | `calendar` | `Calendar`, `CalendarDayButton`; React Day Picker props and `buttonVariant` |
13
- | `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; `CardContent className="px-0"` overrides padding without `!` |
14
- | `checkbox` | `Checkbox` |
15
- | `combobox` | `Combobox`; `options` as `{ value, label }[]`, `value`, `onValueChange`; optional placeholder, search, empty text; trigger matches Input/SelectTrigger chrome; keyboard highlight scrolls into view |
16
- | `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` |
17
- | `dialog` | `Dialog`, trigger, portal, overlay, content, close, header, footer, title, description; `DialogContent` supports `showCloseButton` |
18
- | `empty-panel` | `EmptyPanel`; required `children`; optional `size`, `muted`, `className` |
19
- | `error-boundary` | `ErrorBoundary`, `ErrorFallback`; optional `message`; retry resets, reload refreshes the page |
20
- | `field` | Field, label, legend, description, group, set, title, content, separator, error; `Field` supports `orientation` |
21
- | `input`, `textarea`, `label` | `Input`, `Textarea`, `Label` |
22
- | `popover` | `Popover`, trigger, anchor, content, header, title, description |
23
- | `select` | Select, trigger, value, content, group, label, item, separator, scroll buttons; trigger `size`; trigger text is `text-base md:text-sm` like Input |
24
- | `separator`, `skeleton` | `Separator`, `Skeleton` |
25
- | `sortable-table-head` | `SortableTableHead`; `sorted`, `direction` (`asc` \| `desc`), `onClick`; sets `aria-sort` |
26
- | `sonner` | `Toaster`; Sonner props, with `next-themes` theme defaults |
27
- | `table` | Table, header, body, footer, row, head, cell, caption |
28
- | `table-body-skeleton` | `TableBodySkeleton`; `columns`, optional `rows` (default 5) |
29
- | `tabs` | `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent`, `TabsNav`, `tabsListVariants`; list `variant` is `default` or `line` |
30
- | `toggle` | `Toggle`, `toggleVariants`; `variant`, `size` |
31
- | `toggle-group` | `ToggleGroup`, `ToggleGroupItem`; `variant`, `size` |
32
- | `theme-provider` | `ThemeProvider`, `useTheme`; optional `storageKey` (default `atlas-theme`), `enableShortcut` for the `d` toggle |
33
- | `form/text-field` | `FormTextField`, type `TextFieldApi`; controlled field, label, multiline, description, input constraints |
34
- | `form/select-field` | `FormSelectField`; `value`, `onValueChange`, `label`, optional `meta` and placeholder; select item children |
35
- | `form/date-picker-field` | `FormDatePickerField`; `value`, `onValueChange`, `label`, optional `meta`, placeholder, and `className` (forwarded to the trigger) |
36
- | `form/field-error` | `FieldError`, `getFieldErrorMessage`; types `FieldErrorMessage`, `FieldMetaState` |
37
- | `form/feedback-field` | `FormFeedbackField`; nullable `message` |
38
- | `next/tabs-nav-link` | `TabsNavLink`; Next Link props and required `active` boolean; requires Next.js 16 |
39
- | `utils` | `cn`, `onInputChange` |
40
- | `theme.css` | Tailwind 4 theme; installation in [README](./README.md) |
8
+ | Subpath | Main exports and options |
9
+ | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
10
+ | `button` | `Button`, `buttonVariants`, `quietButtonInteraction`; `variant`, `size`, `asChild`; outline/ghost hover is brand purple + selected wash, not muted grey |
11
+ | `badge` | `Badge`, `badgeVariants`; `variant`, `tone`, `asChild` |
12
+ | `calendar` | `Calendar`, `CalendarDayButton`; React Day Picker props and `buttonVariant` |
13
+ | `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 `!` |
14
+ | `checkbox` | `Checkbox` |
15
+ | `combobox` | `Combobox`; `options` as `{ value, label }[]`, `value`, `onValueChange`; optional placeholder, search, empty text; trigger matches Input/SelectTrigger chrome; keyboard highlight scrolls into view |
16
+ | `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` |
17
+ | `dialog` | `Dialog`, trigger, portal, overlay, content, close, header, footer, title, description; `DialogContent` supports `showCloseButton` |
18
+ | `empty-panel` | `EmptyPanel`; required `children`; optional `size`, `muted`, `className` |
19
+ | `error-boundary` | `ErrorBoundary`, `ErrorFallback`; optional `message`; retry resets, reload refreshes the page |
20
+ | `field` | Field, label, legend, description, group, set, title, content, separator, error; `Field` supports `orientation` |
21
+ | `input`, `textarea`, `label` | `Input`, `Textarea`, `Label` |
22
+ | `popover` | `Popover`, trigger, anchor, content, header, title, description |
23
+ | `select` | Select, trigger, value, content, group, label, item, separator, scroll buttons; trigger `size`; trigger text is `text-base md:text-sm` like Input |
24
+ | `separator`, `skeleton` | `Separator`, `Skeleton` |
25
+ | `sortable-table-head` | `SortableTableHead`; `sorted`, `direction` (`asc` \| `desc`), `onClick`; sets `aria-sort` |
26
+ | `sonner` | `Toaster`; Sonner props, with `next-themes` theme defaults |
27
+ | `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` |
28
+ | `table-body-skeleton` | `TableBodySkeleton`; `columns`, optional `rows` (default 5) |
29
+ | `tabs` | `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent`, `TabsNav`, `tabsListVariants`; list `variant` is `default` or `line` |
30
+ | `toggle` | `Toggle`, `toggleVariants`; `variant`, `size` |
31
+ | `toggle-group` | `ToggleGroup`, `ToggleGroupItem`; `variant`, `size` |
32
+ | `theme-provider` | `ThemeProvider`, `useTheme`; optional `storageKey` (default `atlas-theme`), `enableShortcut` for the `d` toggle |
33
+ | `form/text-field` | `FormTextField`, type `TextFieldApi`; controlled field, label, multiline, description, input constraints |
34
+ | `form/select-field` | `FormSelectField`; `value`, `onValueChange`, `label`, optional `meta` and placeholder; select item children |
35
+ | `form/date-picker-field` | `FormDatePickerField`; `value`, `onValueChange`, `label`, optional `meta`, placeholder, and `className` (forwarded to the trigger) |
36
+ | `form/field-error` | `FieldError`, `getFieldErrorMessage`; types `FieldErrorMessage`, `FieldMetaState` |
37
+ | `form/feedback-field` | `FormFeedbackField`; nullable `message` |
38
+ | `next/tabs-nav-link` | `TabsNavLink`; Next Link props and required `active` boolean; requires Next.js 16 |
39
+ | `utils` | `cn`, `onInputChange` |
40
+ | `theme.css` | Tailwind 4 theme; installation in [README](./README.md) |
41
41
 
42
42
  ## Forms
43
43
 
package/DESIGN_RULES.md CHANGED
@@ -30,10 +30,13 @@ other circles. Card and dialog titles already use uppercase, tracked
30
30
  `font-heading` styling.
31
31
 
32
32
  Use `EmptyPanel` for empty states, `TableBodySkeleton` for loading table bodies,
33
- and `<Card flush>` for an edge-to-edge list or table. `CardContent className="px-0"`
33
+ and `<Card flush>` for an edge-to-edge list or table. `Table` scrolls wide
34
+ columns inside itself (`min-w-0 overflow-x-auto`) and tightens cell padding
35
+ below `sm`. `CardContent className="px-0"`
34
36
  overrides body padding without `!px-0` when only the body should go flush. Cards
35
37
  keep `min-h-min shrink-0` so they do not collapse inside a bounded flex
36
- column. `Dialog` already scrolls inside the viewport on small screens; avoid
38
+ column, and `min-w-0` so nested tables scroll instead of widening the card.
39
+ `Dialog` already scrolls inside the viewport on small screens; avoid
37
40
  additional height limits.
38
41
 
39
42
  `Input`, `SelectTrigger`, `DatePickerButton`, and `Combobox` share form-control
package/README.md CHANGED
@@ -4,7 +4,7 @@ Shared React components and a Tailwind theme with square corners, semantic
4
4
  colors, and distinct selected states. React 19 and Tailwind 4 are required.
5
5
 
6
6
  ```sh
7
- npm install --save-exact atlas-react-kit@0.4.0
7
+ npm install --save-exact atlas-react-kit@0.4.1
8
8
  ```
9
9
 
10
10
  Import components by subpath:
@@ -59,7 +59,7 @@ without compilation and processed by the consuming application's Tailwind build.
59
59
  The optional Next.js 16 adapter requires Next only when imported. The package
60
60
  does not bundle React.
61
61
 
62
- 0.3.0 is already on npm. Bumping the version in `package.json` and
62
+ 0.4.0 is already on npm. Bumping the version in `package.json` and
63
63
  merging to `main` (path-filtered to package files) or running
64
64
  `workflow_dispatch` publishes through npm OIDC trusted publishing after
65
65
  check, test, and pack gates. Versions already on npm are skipped.
@@ -70,7 +70,7 @@ artifact with the package owner's npm login:
70
70
  ```sh
71
71
  mkdir -p release-artifacts
72
72
  npm pack --pack-destination release-artifacts
73
- npm publish ./release-artifacts/atlas-react-kit-0.4.0.tgz --access public
73
+ npm publish ./release-artifacts/atlas-react-kit-0.4.1.tgz --access public
74
74
  ```
75
75
 
76
76
  Pin an exact package version in consuming applications. Roll back an upgrade by
package/dist/card.d.ts CHANGED
@@ -4,8 +4,8 @@ import * as React from "react";
4
4
  * `@layer components`) so a utility `px-0` / `py-0` on Card or its sections
5
5
  * overrides it without `!`. `flush` sets the variable to 0 so lists and
6
6
  * tables can run edge to edge. `min-h-min shrink-0` keeps the card from
7
- * collapsing inside a bounded flex column while `overflow-hidden` still
8
- * clips media.
7
+ * collapsing inside a bounded flex column. `min-w-0` lets nested tables
8
+ * scroll instead of widening the card. `overflow-hidden` still clips media.
9
9
  */
10
10
  declare function Card({ className, size, flush, ...props }: React.ComponentProps<"div"> & {
11
11
  size?: "default" | "sm";
package/dist/card.js CHANGED
@@ -6,16 +6,16 @@ import { cn } from "./utils.js";
6
6
  * `@layer components`) so a utility `px-0` / `py-0` on Card or its sections
7
7
  * overrides it without `!`. `flush` sets the variable to 0 so lists and
8
8
  * tables can run edge to edge. `min-h-min shrink-0` keeps the card from
9
- * collapsing inside a bounded flex column while `overflow-hidden` still
10
- * clips media.
9
+ * collapsing inside a bounded flex column. `min-w-0` lets nested tables
10
+ * scroll instead of widening the card. `overflow-hidden` still clips media.
11
11
  */
12
12
  function Card({ className, size = "default", flush = false, ...props }) {
13
- return (_jsx("div", { "data-slot": "card", "data-size": size, className: cn("group/card flex min-h-min shrink-0 flex-col overflow-hidden bg-card text-sm text-card-foreground shadow-sm ring-1 ring-foreground/5 has-[>img:first-child]:pt-0 *:[img:first-child]:rounded-none *:[img:last-child]:rounded-none", size === "sm"
13
+ return (_jsx("div", { "data-slot": "card", "data-size": size, className: cn("group/card flex min-h-min min-w-0 shrink-0 flex-col overflow-hidden bg-card text-sm text-card-foreground shadow-sm ring-1 ring-foreground/5 has-[>img:first-child]:pt-0 *:[img:first-child]:rounded-none *:[img:last-child]:rounded-none", size === "sm"
14
14
  ? "gap-5 [--card-p:--spacing(5)]"
15
15
  : "gap-8 [--card-p:--spacing(8)]", flush && "[--card-p:0px]", className), ...props }));
16
16
  }
17
17
  function CardHeader({ className, ...props }) {
18
- return (_jsx("div", { "data-slot": "card-header", className: cn("group/card-header @container/card-header grid auto-rows-min items-start gap-1.5 rounded-none has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]", className), ...props }));
18
+ return (_jsx("div", { "data-slot": "card-header", className: cn("group/card-header @container/card-header grid min-w-0 auto-rows-min items-start gap-1.5 rounded-none has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto]", className), ...props }));
19
19
  }
20
20
  function CardTitle({ as: Component = "div", className, ...props }) {
21
21
  return (_jsx(Component, { "data-slot": "card-title", className: cn("font-heading text-base font-semibold tracking-wider uppercase", className), ...props }));
@@ -27,9 +27,9 @@ function CardAction({ className, ...props }) {
27
27
  return (_jsx("div", { "data-slot": "card-action", className: cn("col-start-2 row-span-2 row-start-1 self-start justify-self-end", className), ...props }));
28
28
  }
29
29
  function CardContent({ className, ...props }) {
30
- return _jsx("div", { "data-slot": "card-content", className: className, ...props });
30
+ return (_jsx("div", { "data-slot": "card-content", className: cn("min-w-0", className), ...props }));
31
31
  }
32
32
  function CardFooter({ className, ...props }) {
33
- return (_jsx("div", { "data-slot": "card-footer", className: cn("flex items-center", className), ...props }));
33
+ return (_jsx("div", { "data-slot": "card-footer", className: cn("flex min-w-0 items-center", className), ...props }));
34
34
  }
35
35
  export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent, };
package/dist/table.d.ts CHANGED
@@ -1,4 +1,9 @@
1
1
  import * as React from "react";
2
+ /**
3
+ * Data table. The root is a `min-w-0 overflow-x-auto` scroller so nowrap
4
+ * columns scroll inside the table instead of widening a card or panel.
5
+ * Cell padding is `px-2` below `sm` and the original `p-3` from `sm` up.
6
+ */
2
7
  declare function Table({ className, ...props }: React.ComponentProps<"table">): React.JSX.Element;
3
8
  declare function TableHeader({ className, ...props }: React.ComponentProps<"thead">): React.JSX.Element;
4
9
  declare function TableBody({ className, ...props }: React.ComponentProps<"tbody">): React.JSX.Element;
package/dist/table.js CHANGED
@@ -2,8 +2,13 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { cn } from "./utils.js";
5
+ /**
6
+ * Data table. The root is a `min-w-0 overflow-x-auto` scroller so nowrap
7
+ * columns scroll inside the table instead of widening a card or panel.
8
+ * Cell padding is `px-2` below `sm` and the original `p-3` from `sm` up.
9
+ */
5
10
  function Table({ className, ...props }) {
6
- return (_jsx("div", { "data-slot": "table-container", className: "relative w-full overflow-x-auto", children: _jsx("table", { "data-slot": "table", className: cn("w-full caption-bottom text-sm", className), ...props }) }));
11
+ return (_jsx("div", { "data-slot": "table-container", className: "relative w-full min-w-0 max-w-full overflow-x-auto overscroll-x-contain", children: _jsx("table", { "data-slot": "table", className: cn("w-full min-w-full caption-bottom text-sm", className), ...props }) }));
7
12
  }
8
13
  function TableHeader({ className, ...props }) {
9
14
  return (_jsx("thead", { "data-slot": "table-header", className: cn("[&_tr]:border-b", className), ...props }));
@@ -18,10 +23,10 @@ function TableRow({ className, ...props }) {
18
23
  return (_jsx("tr", { "data-slot": "table-row", className: cn("border-b transition-colors hover:bg-muted/50 has-aria-expanded:bg-muted/50 data-[state=selected]:bg-selected", className), ...props }));
19
24
  }
20
25
  function TableHead({ className, ...props }) {
21
- return (_jsx("th", { "data-slot": "table-head", className: cn("h-12 px-3 text-left align-middle text-xs font-medium tracking-wider whitespace-nowrap text-muted-foreground uppercase [&:has([role=checkbox])]:pr-0", className), ...props }));
26
+ return (_jsx("th", { "data-slot": "table-head", className: cn("h-10 px-2 text-left align-middle text-xs font-medium tracking-wider whitespace-nowrap text-muted-foreground uppercase sm:h-12 sm:px-3 [&:has([role=checkbox])]:pr-0", className), ...props }));
22
27
  }
23
28
  function TableCell({ className, ...props }) {
24
- return (_jsx("td", { "data-slot": "table-cell", className: cn("p-3 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0", className), ...props }));
29
+ return (_jsx("td", { "data-slot": "table-cell", className: cn("px-2 py-2 align-middle whitespace-nowrap sm:p-3 [&:has([role=checkbox])]:pr-0", className), ...props }));
25
30
  }
26
31
  function TableCaption({ className, ...props }) {
27
32
  return (_jsx("caption", { "data-slot": "table-caption", className: cn("mt-4 text-sm text-muted-foreground", className), ...props }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atlas-react-kit",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Shared React components and Tailwind theme for Atlas",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/theme.css CHANGED
@@ -202,4 +202,43 @@
202
202
  [data-slot="card-footer"].border-t {
203
203
  padding-top: var(--card-p);
204
204
  }
205
+
206
+ /*
207
+ * Horizontal scroll shadows: edge fades stay pinned (`scroll`) while
208
+ * matching covers ride with the content (`local`), so a clipped column
209
+ * like LICENSE is visible as overflow instead of looking truncated.
210
+ */
211
+ [data-slot="table-container"] {
212
+ --table-scroll-fade: var(--background);
213
+ background:
214
+ linear-gradient(to right, var(--table-scroll-fade) 40%, transparent),
215
+ linear-gradient(to left, var(--table-scroll-fade) 40%, transparent),
216
+ linear-gradient(
217
+ to right,
218
+ color-mix(in oklch, var(--foreground) 16%, transparent),
219
+ transparent 80%
220
+ ),
221
+ linear-gradient(
222
+ to left,
223
+ color-mix(in oklch, var(--foreground) 16%, transparent),
224
+ transparent 80%
225
+ );
226
+ background-repeat: no-repeat;
227
+ background-size:
228
+ 1.5rem 100%,
229
+ 1.5rem 100%,
230
+ 0.75rem 100%,
231
+ 0.75rem 100%;
232
+ background-position:
233
+ left center,
234
+ right center,
235
+ left center,
236
+ right center;
237
+ background-attachment: local, local, scroll, scroll;
238
+ }
239
+
240
+ /* Covers match the card face so the fade does not flash the page background. */
241
+ [data-slot="card"] [data-slot="table-container"] {
242
+ --table-scroll-fade: var(--card);
243
+ }
205
244
  }