@nucleux/item 0.0.0-stage → 0.6.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nucleux
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,44 @@
1
- # Temporary Holding Version
1
+ # @nucleux/item
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Flexible list row with media, content and actions — Nucleux agentic UI for React.
4
+
5
+ Part of **[Nucleux](https://github.com/intelligaia-open-labs/nucleux)** — agentic UI components for React. Install a single component, or the full kit via [`@nucleux/react`](https://www.npmjs.com/package/@nucleux/react).
6
+
7
+
8
+ ## Exports
9
+
10
+ - **`Item`** — the row (`variant`: `default` | `outline` | `muted`; `size`: `default` | `sm`; `asChild` for links)
11
+ - **`ItemMedia`** (`variant`: `default` | `icon` | `image`), **`ItemContent`**, **`ItemTitle`**, **`ItemDescription`**, **`ItemActions`**
12
+ - **`ItemHeader`**, **`ItemFooter`** — full-width rows above / below
13
+ - **`ItemGroup`** — `role="list"` wrapper; **`ItemSeparator`** — rule between items
14
+ - **`itemVariants`**, **`itemMediaVariants`** — the class strings
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ pnpm add @nucleux/item @nucleux/tokens
20
+ ```
21
+
22
+ `react` / `react-dom` are peer dependencies.
23
+
24
+ ## Usage
25
+
26
+ ```tsx
27
+ import { Item, ItemActions, ItemContent, ItemDescription, ItemMedia, ItemTitle } from "@nucleux/item";
28
+
29
+ <Item variant="outline">
30
+ <ItemMedia variant="icon"><ShieldAlert /></ItemMedia>
31
+ <ItemContent>
32
+ <ItemTitle>Security alert</ItemTitle>
33
+ <ItemDescription>New sign-in from Chrome on macOS.</ItemDescription>
34
+ </ItemContent>
35
+ <ItemActions><Button variant="secondary" size="sm">Review</Button></ItemActions>
36
+ </Item>
37
+ ```
38
+
39
+ Requires the theme once in your app: `import "@nucleux/tokens/styles.css";`
40
+ and the Tailwind preset from `@nucleux/tokens/preset`.
41
+
42
+ ## License
43
+
44
+ MIT © Nucleux
package/dist/index.cjs ADDED
@@ -0,0 +1,166 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var React = require('react');
5
+ var utils = require('@nucleux/utils');
6
+ var separator = require('@nucleux/separator');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+
9
+ function _interopNamespace(e) {
10
+ if (e && e.__esModule) return e;
11
+ var n = Object.create(null);
12
+ if (e) {
13
+ Object.keys(e).forEach(function (k) {
14
+ if (k !== 'default') {
15
+ var d = Object.getOwnPropertyDescriptor(e, k);
16
+ Object.defineProperty(n, k, d.get ? d : {
17
+ enumerable: true,
18
+ get: function () { return e[k]; }
19
+ });
20
+ }
21
+ });
22
+ }
23
+ n.default = e;
24
+ return Object.freeze(n);
25
+ }
26
+
27
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
28
+
29
+ // src/index.tsx
30
+ var ItemGroupContext = React__namespace.createContext(false);
31
+ var ItemGroup = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(ItemGroupContext.Provider, { value: true, children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref, role: "list", "data-slot": "item-group", className: utils.cn("group/item-group flex flex-col", className), ...props }) }));
32
+ ItemGroup.displayName = "ItemGroup";
33
+ var ItemSeparator = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(separator.Separator, { ref, "data-slot": "item-separator", orientation: "horizontal", className: utils.cn("my-0", className), ...props }));
34
+ ItemSeparator.displayName = "ItemSeparator";
35
+ var itemBase = "group/item flex flex-wrap items-center rounded-md border border-transparent text-sm outline-none transition-colors duration-100 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [a&]:transition-colors hover:[a&]:bg-accent/50";
36
+ var itemVariantClasses = {
37
+ default: "bg-transparent",
38
+ outline: "border-border",
39
+ muted: "bg-muted/50"
40
+ };
41
+ var itemSizeClasses = {
42
+ default: "gap-4 p-4",
43
+ sm: "gap-2.5 px-4 py-3"
44
+ };
45
+ function itemVariants({
46
+ variant = "default",
47
+ size = "default",
48
+ className
49
+ } = {}) {
50
+ return utils.cn(itemBase, itemVariantClasses[variant ?? "default"], itemSizeClasses[size ?? "default"], className);
51
+ }
52
+ var Item = React__namespace.forwardRef(
53
+ ({ className, variant = "default", size = "default", asChild = false, ...props }, ref) => {
54
+ const inGroup = React__namespace.useContext(ItemGroupContext);
55
+ const shared = {
56
+ "data-slot": "item",
57
+ "data-variant": variant,
58
+ "data-size": size,
59
+ className: itemVariants({ variant, size, className })
60
+ };
61
+ if (asChild) {
62
+ const el = /* @__PURE__ */ jsxRuntime.jsx(utils.Slot, { ref, ...shared, ...props });
63
+ return inGroup ? /* @__PURE__ */ jsxRuntime.jsx("div", { role: "listitem", "data-slot": "item-listitem", className: "contents", children: el }) : el;
64
+ }
65
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, role: inGroup ? "listitem" : void 0, ...shared, ...props });
66
+ }
67
+ );
68
+ Item.displayName = "Item";
69
+ var itemMediaBase = "flex shrink-0 items-center justify-center gap-2 group-has-[[data-slot=item-description]]/item:translate-y-0.5 group-has-[[data-slot=item-description]]/item:self-start [&_svg]:pointer-events-none";
70
+ var itemMediaVariantClasses = {
71
+ default: "bg-transparent",
72
+ icon: "size-8 rounded-sm border border-border bg-muted [&_svg:not([class*='size-'])]:size-4",
73
+ image: "size-10 overflow-hidden rounded-sm [&_img]:size-full [&_img]:object-cover"
74
+ };
75
+ function itemMediaVariants({
76
+ variant = "default",
77
+ className
78
+ } = {}) {
79
+ return utils.cn(itemMediaBase, itemMediaVariantClasses[variant ?? "default"], className);
80
+ }
81
+ var ItemMedia = React__namespace.forwardRef(
82
+ ({ className, variant = "default", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
83
+ "div",
84
+ {
85
+ ref,
86
+ "data-slot": "item-media",
87
+ "data-variant": variant,
88
+ className: itemMediaVariants({ variant, className }),
89
+ ...props
90
+ }
91
+ )
92
+ );
93
+ ItemMedia.displayName = "ItemMedia";
94
+ var ItemContent = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
95
+ "div",
96
+ {
97
+ ref,
98
+ "data-slot": "item-content",
99
+ className: utils.cn("flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none", className),
100
+ ...props
101
+ }
102
+ ));
103
+ ItemContent.displayName = "ItemContent";
104
+ var ItemTitle = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
105
+ "div",
106
+ {
107
+ ref,
108
+ "data-slot": "item-title",
109
+ className: utils.cn("flex w-fit items-center gap-2 text-sm font-medium leading-snug", className),
110
+ ...props
111
+ }
112
+ ));
113
+ ItemTitle.displayName = "ItemTitle";
114
+ var ItemDescription = React__namespace.forwardRef(
115
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
116
+ "p",
117
+ {
118
+ ref,
119
+ "data-slot": "item-description",
120
+ className: utils.cn(
121
+ "line-clamp-2 text-balance text-sm font-normal leading-normal text-muted-foreground",
122
+ "[&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
123
+ className
124
+ ),
125
+ ...props
126
+ }
127
+ )
128
+ );
129
+ ItemDescription.displayName = "ItemDescription";
130
+ var ItemActions = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx("div", { ref, "data-slot": "item-actions", className: utils.cn("flex items-center gap-2", className), ...props }));
131
+ ItemActions.displayName = "ItemActions";
132
+ var ItemHeader = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
133
+ "div",
134
+ {
135
+ ref,
136
+ "data-slot": "item-header",
137
+ className: utils.cn("flex basis-full items-center justify-between gap-2", className),
138
+ ...props
139
+ }
140
+ ));
141
+ ItemHeader.displayName = "ItemHeader";
142
+ var ItemFooter = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
143
+ "div",
144
+ {
145
+ ref,
146
+ "data-slot": "item-footer",
147
+ className: utils.cn("flex basis-full items-center justify-between gap-2", className),
148
+ ...props
149
+ }
150
+ ));
151
+ ItemFooter.displayName = "ItemFooter";
152
+
153
+ exports.Item = Item;
154
+ exports.ItemActions = ItemActions;
155
+ exports.ItemContent = ItemContent;
156
+ exports.ItemDescription = ItemDescription;
157
+ exports.ItemFooter = ItemFooter;
158
+ exports.ItemGroup = ItemGroup;
159
+ exports.ItemHeader = ItemHeader;
160
+ exports.ItemMedia = ItemMedia;
161
+ exports.ItemSeparator = ItemSeparator;
162
+ exports.ItemTitle = ItemTitle;
163
+ exports.itemMediaVariants = itemMediaVariants;
164
+ exports.itemVariants = itemVariants;
165
+ //# sourceMappingURL=index.cjs.map
166
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.tsx"],"names":["React","jsx","cn","Separator","Slot"],"mappings":"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","file":"index.cjs","sourcesContent":["import * as React from \"react\";\nimport { cn, Slot } from \"@nucleux/utils\";\nimport { Separator, type SeparatorProps } from \"@nucleux/separator\";\n\nexport type ItemVariant = \"default\" | \"outline\" | \"muted\";\nexport type ItemSize = \"default\" | \"sm\";\nexport type ItemMediaVariant = \"default\" | \"icon\" | \"image\";\n\nconst ItemGroupContext = React.createContext(false);\n\nexport type ItemGroupProps = React.HTMLAttributes<HTMLDivElement>;\n\n/**\n * A vertical list of Items, exposed to assistive tech as a list\n * (`role=\"list\"`). Items rendered inside get `role=\"listitem\"`; an Item\n * using `asChild` (e.g. a link) keeps its child's role and is wrapped in a\n * layout-neutral (`display: contents`) listitem.\n * Put an ItemSeparator between Items for dividing rules.\n */\nexport const ItemGroup = React.forwardRef<HTMLDivElement, ItemGroupProps>(({ className, ...props }, ref) => (\n <ItemGroupContext.Provider value={true}>\n <div ref={ref} role=\"list\" data-slot=\"item-group\" className={cn(\"group/item-group flex flex-col\", className)} {...props} />\n </ItemGroupContext.Provider>\n));\nItemGroup.displayName = \"ItemGroup\";\n\nexport type ItemSeparatorProps = SeparatorProps;\n\n/** A horizontal rule between Items in an ItemGroup. */\nexport const ItemSeparator = React.forwardRef<HTMLDivElement, ItemSeparatorProps>(({ className, ...props }, ref) => (\n <Separator ref={ref} data-slot=\"item-separator\" orientation=\"horizontal\" className={cn(\"my-0\", className)} {...props} />\n));\nItemSeparator.displayName = \"ItemSeparator\";\n\nconst itemBase =\n \"group/item flex flex-wrap items-center rounded-md border border-transparent text-sm outline-none transition-colors duration-100 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [a&]:transition-colors hover:[a&]:bg-accent/50\";\n\nconst itemVariantClasses: Record<ItemVariant, string> = {\n default: \"bg-transparent\",\n outline: \"border-border\",\n muted: \"bg-muted/50\",\n};\n\nconst itemSizeClasses: Record<ItemSize, string> = {\n default: \"gap-4 p-4\",\n sm: \"gap-2.5 px-4 py-3\",\n};\n\n/** Returns the Item class string for a variant and size (shadcn's `itemVariants` cva helper). */\nexport function itemVariants({\n variant = \"default\",\n size = \"default\",\n className,\n}: { variant?: ItemVariant | null; size?: ItemSize | null; className?: string } = {}) {\n return cn(itemBase, itemVariantClasses[variant ?? \"default\"], itemSizeClasses[size ?? \"default\"], className);\n}\n\nexport interface ItemProps extends React.HTMLAttributes<HTMLDivElement> {\n /** \"default\" (transparent), \"outline\" (bordered) or \"muted\" (soft fill). */\n variant?: ItemVariant;\n /** \"default\" (roomy) or \"sm\" (compact). */\n size?: ItemSize;\n /** Render the single child (e.g. an `<a>` or router Link) as the row, making it clickable with a hover tint. */\n asChild?: boolean;\n}\n\n/**\n * A flexible row for lists, settings and search results: media on the\n * left, title and description in the middle, actions on the right.\n * Compose ItemMedia, ItemContent (ItemTitle, ItemDescription), ItemActions,\n * and optionally ItemHeader / ItemFooter spanning the full width. Use\n * `asChild` with an `<a>` to make the whole row a link; group rows in an\n * ItemGroup.\n */\nexport const Item = React.forwardRef<HTMLDivElement, ItemProps>(\n ({ className, variant = \"default\", size = \"default\", asChild = false, ...props }, ref) => {\n const inGroup = React.useContext(ItemGroupContext);\n const shared = {\n \"data-slot\": \"item\",\n \"data-variant\": variant,\n \"data-size\": size,\n className: itemVariants({ variant, size, className }),\n };\n if (asChild) {\n const el = <Slot ref={ref} {...shared} {...props} />;\n // A link or button can't also be a listitem, so inside an ItemGroup it\n // gets a layout-neutral listitem wrapper to keep the list valid.\n return inGroup ? (\n <div role=\"listitem\" data-slot=\"item-listitem\" className=\"contents\">\n {el}\n </div>\n ) : (\n el\n );\n }\n return <div ref={ref} role={inGroup ? \"listitem\" : undefined} {...shared} {...props} />;\n },\n);\nItem.displayName = \"Item\";\n\nconst itemMediaBase =\n \"flex shrink-0 items-center justify-center gap-2 group-has-[[data-slot=item-description]]/item:translate-y-0.5 group-has-[[data-slot=item-description]]/item:self-start [&_svg]:pointer-events-none\";\n\nconst itemMediaVariantClasses: Record<ItemMediaVariant, string> = {\n default: \"bg-transparent\",\n icon: \"size-8 rounded-sm border border-border bg-muted [&_svg:not([class*='size-'])]:size-4\",\n image: \"size-10 overflow-hidden rounded-sm [&_img]:size-full [&_img]:object-cover\",\n};\n\n/** Returns the ItemMedia class string for a variant. */\nexport function itemMediaVariants({\n variant = \"default\",\n className,\n}: { variant?: ItemMediaVariant | null; className?: string } = {}) {\n return cn(itemMediaBase, itemMediaVariantClasses[variant ?? \"default\"], className);\n}\n\nexport interface ItemMediaProps extends React.HTMLAttributes<HTMLDivElement> {\n /** \"default\" (as-is, e.g. an Avatar), \"icon\" (icon in a bordered muted tile) or \"image\" (40px cover thumbnail). */\n variant?: ItemMediaVariant;\n}\n\n/** The leading icon, avatar or thumbnail; aligns to the top when the Item has a description. */\nexport const ItemMedia = React.forwardRef<HTMLDivElement, ItemMediaProps>(\n ({ className, variant = \"default\", ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"item-media\"\n data-variant={variant}\n className={itemMediaVariants({ variant, className })}\n {...props}\n />\n ),\n);\nItemMedia.displayName = \"ItemMedia\";\n\nexport type ItemContentProps = React.HTMLAttributes<HTMLDivElement>;\n\n/** The flexible middle column holding ItemTitle and ItemDescription. */\nexport const ItemContent = React.forwardRef<HTMLDivElement, ItemContentProps>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"item-content\"\n className={cn(\"flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none\", className)}\n {...props}\n />\n));\nItemContent.displayName = \"ItemContent\";\n\nexport type ItemTitleProps = React.HTMLAttributes<HTMLDivElement>;\n\n/** The row's primary label; can hold an inline Badge or icon. */\nexport const ItemTitle = React.forwardRef<HTMLDivElement, ItemTitleProps>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"item-title\"\n className={cn(\"flex w-fit items-center gap-2 text-sm font-medium leading-snug\", className)}\n {...props}\n />\n));\nItemTitle.displayName = \"ItemTitle\";\n\nexport type ItemDescriptionProps = React.HTMLAttributes<HTMLParagraphElement>;\n\n/** Secondary muted text under the title, clamped to two lines; links inside are underlined. */\nexport const ItemDescription = React.forwardRef<HTMLParagraphElement, ItemDescriptionProps>(\n ({ className, ...props }, ref) => (\n <p\n ref={ref}\n data-slot=\"item-description\"\n className={cn(\n \"line-clamp-2 text-balance text-sm font-normal leading-normal text-muted-foreground\",\n \"[&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary\",\n className,\n )}\n {...props}\n />\n ),\n);\nItemDescription.displayName = \"ItemDescription\";\n\nexport type ItemActionsProps = React.HTMLAttributes<HTMLDivElement>;\n\n/** Trailing buttons or controls for the row. */\nexport const ItemActions = React.forwardRef<HTMLDivElement, ItemActionsProps>(({ className, ...props }, ref) => (\n <div ref={ref} data-slot=\"item-actions\" className={cn(\"flex items-center gap-2\", className)} {...props} />\n));\nItemActions.displayName = \"ItemActions\";\n\nexport type ItemHeaderProps = React.HTMLAttributes<HTMLDivElement>;\n\n/** A full-width row above the main content (e.g. a cover image or a title with a menu). */\nexport const ItemHeader = React.forwardRef<HTMLDivElement, ItemHeaderProps>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"item-header\"\n className={cn(\"flex basis-full items-center justify-between gap-2\", className)}\n {...props}\n />\n));\nItemHeader.displayName = \"ItemHeader\";\n\nexport type ItemFooterProps = React.HTMLAttributes<HTMLDivElement>;\n\n/** A full-width row below the main content (e.g. metadata or secondary actions). */\nexport const ItemFooter = React.forwardRef<HTMLDivElement, ItemFooterProps>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"item-footer\"\n className={cn(\"flex basis-full items-center justify-between gap-2\", className)}\n {...props}\n />\n));\nItemFooter.displayName = \"ItemFooter\";\n"]}
@@ -0,0 +1,72 @@
1
+ import * as React from 'react';
2
+ import { SeparatorProps } from '@nucleux/separator';
3
+
4
+ type ItemVariant = "default" | "outline" | "muted";
5
+ type ItemSize = "default" | "sm";
6
+ type ItemMediaVariant = "default" | "icon" | "image";
7
+ type ItemGroupProps = React.HTMLAttributes<HTMLDivElement>;
8
+ /**
9
+ * A vertical list of Items, exposed to assistive tech as a list
10
+ * (`role="list"`). Items rendered inside get `role="listitem"`; an Item
11
+ * using `asChild` (e.g. a link) keeps its child's role and is wrapped in a
12
+ * layout-neutral (`display: contents`) listitem.
13
+ * Put an ItemSeparator between Items for dividing rules.
14
+ */
15
+ declare const ItemGroup: React.ForwardRefExoticComponent<ItemGroupProps & React.RefAttributes<HTMLDivElement>>;
16
+ type ItemSeparatorProps = SeparatorProps;
17
+ /** A horizontal rule between Items in an ItemGroup. */
18
+ declare const ItemSeparator: React.ForwardRefExoticComponent<SeparatorProps & React.RefAttributes<HTMLDivElement>>;
19
+ /** Returns the Item class string for a variant and size (shadcn's `itemVariants` cva helper). */
20
+ declare function itemVariants({ variant, size, className, }?: {
21
+ variant?: ItemVariant | null;
22
+ size?: ItemSize | null;
23
+ className?: string;
24
+ }): string;
25
+ interface ItemProps extends React.HTMLAttributes<HTMLDivElement> {
26
+ /** "default" (transparent), "outline" (bordered) or "muted" (soft fill). */
27
+ variant?: ItemVariant;
28
+ /** "default" (roomy) or "sm" (compact). */
29
+ size?: ItemSize;
30
+ /** Render the single child (e.g. an `<a>` or router Link) as the row, making it clickable with a hover tint. */
31
+ asChild?: boolean;
32
+ }
33
+ /**
34
+ * A flexible row for lists, settings and search results: media on the
35
+ * left, title and description in the middle, actions on the right.
36
+ * Compose ItemMedia, ItemContent (ItemTitle, ItemDescription), ItemActions,
37
+ * and optionally ItemHeader / ItemFooter spanning the full width. Use
38
+ * `asChild` with an `<a>` to make the whole row a link; group rows in an
39
+ * ItemGroup.
40
+ */
41
+ declare const Item: React.ForwardRefExoticComponent<ItemProps & React.RefAttributes<HTMLDivElement>>;
42
+ /** Returns the ItemMedia class string for a variant. */
43
+ declare function itemMediaVariants({ variant, className, }?: {
44
+ variant?: ItemMediaVariant | null;
45
+ className?: string;
46
+ }): string;
47
+ interface ItemMediaProps extends React.HTMLAttributes<HTMLDivElement> {
48
+ /** "default" (as-is, e.g. an Avatar), "icon" (icon in a bordered muted tile) or "image" (40px cover thumbnail). */
49
+ variant?: ItemMediaVariant;
50
+ }
51
+ /** The leading icon, avatar or thumbnail; aligns to the top when the Item has a description. */
52
+ declare const ItemMedia: React.ForwardRefExoticComponent<ItemMediaProps & React.RefAttributes<HTMLDivElement>>;
53
+ type ItemContentProps = React.HTMLAttributes<HTMLDivElement>;
54
+ /** The flexible middle column holding ItemTitle and ItemDescription. */
55
+ declare const ItemContent: React.ForwardRefExoticComponent<ItemContentProps & React.RefAttributes<HTMLDivElement>>;
56
+ type ItemTitleProps = React.HTMLAttributes<HTMLDivElement>;
57
+ /** The row's primary label; can hold an inline Badge or icon. */
58
+ declare const ItemTitle: React.ForwardRefExoticComponent<ItemTitleProps & React.RefAttributes<HTMLDivElement>>;
59
+ type ItemDescriptionProps = React.HTMLAttributes<HTMLParagraphElement>;
60
+ /** Secondary muted text under the title, clamped to two lines; links inside are underlined. */
61
+ declare const ItemDescription: React.ForwardRefExoticComponent<ItemDescriptionProps & React.RefAttributes<HTMLParagraphElement>>;
62
+ type ItemActionsProps = React.HTMLAttributes<HTMLDivElement>;
63
+ /** Trailing buttons or controls for the row. */
64
+ declare const ItemActions: React.ForwardRefExoticComponent<ItemActionsProps & React.RefAttributes<HTMLDivElement>>;
65
+ type ItemHeaderProps = React.HTMLAttributes<HTMLDivElement>;
66
+ /** A full-width row above the main content (e.g. a cover image or a title with a menu). */
67
+ declare const ItemHeader: React.ForwardRefExoticComponent<ItemHeaderProps & React.RefAttributes<HTMLDivElement>>;
68
+ type ItemFooterProps = React.HTMLAttributes<HTMLDivElement>;
69
+ /** A full-width row below the main content (e.g. metadata or secondary actions). */
70
+ declare const ItemFooter: React.ForwardRefExoticComponent<ItemFooterProps & React.RefAttributes<HTMLDivElement>>;
71
+
72
+ export { Item, ItemActions, type ItemActionsProps, ItemContent, type ItemContentProps, ItemDescription, type ItemDescriptionProps, ItemFooter, type ItemFooterProps, ItemGroup, type ItemGroupProps, ItemHeader, type ItemHeaderProps, ItemMedia, type ItemMediaProps, type ItemMediaVariant, type ItemProps, ItemSeparator, type ItemSeparatorProps, type ItemSize, ItemTitle, type ItemTitleProps, type ItemVariant, itemMediaVariants, itemVariants };
@@ -0,0 +1,72 @@
1
+ import * as React from 'react';
2
+ import { SeparatorProps } from '@nucleux/separator';
3
+
4
+ type ItemVariant = "default" | "outline" | "muted";
5
+ type ItemSize = "default" | "sm";
6
+ type ItemMediaVariant = "default" | "icon" | "image";
7
+ type ItemGroupProps = React.HTMLAttributes<HTMLDivElement>;
8
+ /**
9
+ * A vertical list of Items, exposed to assistive tech as a list
10
+ * (`role="list"`). Items rendered inside get `role="listitem"`; an Item
11
+ * using `asChild` (e.g. a link) keeps its child's role and is wrapped in a
12
+ * layout-neutral (`display: contents`) listitem.
13
+ * Put an ItemSeparator between Items for dividing rules.
14
+ */
15
+ declare const ItemGroup: React.ForwardRefExoticComponent<ItemGroupProps & React.RefAttributes<HTMLDivElement>>;
16
+ type ItemSeparatorProps = SeparatorProps;
17
+ /** A horizontal rule between Items in an ItemGroup. */
18
+ declare const ItemSeparator: React.ForwardRefExoticComponent<SeparatorProps & React.RefAttributes<HTMLDivElement>>;
19
+ /** Returns the Item class string for a variant and size (shadcn's `itemVariants` cva helper). */
20
+ declare function itemVariants({ variant, size, className, }?: {
21
+ variant?: ItemVariant | null;
22
+ size?: ItemSize | null;
23
+ className?: string;
24
+ }): string;
25
+ interface ItemProps extends React.HTMLAttributes<HTMLDivElement> {
26
+ /** "default" (transparent), "outline" (bordered) or "muted" (soft fill). */
27
+ variant?: ItemVariant;
28
+ /** "default" (roomy) or "sm" (compact). */
29
+ size?: ItemSize;
30
+ /** Render the single child (e.g. an `<a>` or router Link) as the row, making it clickable with a hover tint. */
31
+ asChild?: boolean;
32
+ }
33
+ /**
34
+ * A flexible row for lists, settings and search results: media on the
35
+ * left, title and description in the middle, actions on the right.
36
+ * Compose ItemMedia, ItemContent (ItemTitle, ItemDescription), ItemActions,
37
+ * and optionally ItemHeader / ItemFooter spanning the full width. Use
38
+ * `asChild` with an `<a>` to make the whole row a link; group rows in an
39
+ * ItemGroup.
40
+ */
41
+ declare const Item: React.ForwardRefExoticComponent<ItemProps & React.RefAttributes<HTMLDivElement>>;
42
+ /** Returns the ItemMedia class string for a variant. */
43
+ declare function itemMediaVariants({ variant, className, }?: {
44
+ variant?: ItemMediaVariant | null;
45
+ className?: string;
46
+ }): string;
47
+ interface ItemMediaProps extends React.HTMLAttributes<HTMLDivElement> {
48
+ /** "default" (as-is, e.g. an Avatar), "icon" (icon in a bordered muted tile) or "image" (40px cover thumbnail). */
49
+ variant?: ItemMediaVariant;
50
+ }
51
+ /** The leading icon, avatar or thumbnail; aligns to the top when the Item has a description. */
52
+ declare const ItemMedia: React.ForwardRefExoticComponent<ItemMediaProps & React.RefAttributes<HTMLDivElement>>;
53
+ type ItemContentProps = React.HTMLAttributes<HTMLDivElement>;
54
+ /** The flexible middle column holding ItemTitle and ItemDescription. */
55
+ declare const ItemContent: React.ForwardRefExoticComponent<ItemContentProps & React.RefAttributes<HTMLDivElement>>;
56
+ type ItemTitleProps = React.HTMLAttributes<HTMLDivElement>;
57
+ /** The row's primary label; can hold an inline Badge or icon. */
58
+ declare const ItemTitle: React.ForwardRefExoticComponent<ItemTitleProps & React.RefAttributes<HTMLDivElement>>;
59
+ type ItemDescriptionProps = React.HTMLAttributes<HTMLParagraphElement>;
60
+ /** Secondary muted text under the title, clamped to two lines; links inside are underlined. */
61
+ declare const ItemDescription: React.ForwardRefExoticComponent<ItemDescriptionProps & React.RefAttributes<HTMLParagraphElement>>;
62
+ type ItemActionsProps = React.HTMLAttributes<HTMLDivElement>;
63
+ /** Trailing buttons or controls for the row. */
64
+ declare const ItemActions: React.ForwardRefExoticComponent<ItemActionsProps & React.RefAttributes<HTMLDivElement>>;
65
+ type ItemHeaderProps = React.HTMLAttributes<HTMLDivElement>;
66
+ /** A full-width row above the main content (e.g. a cover image or a title with a menu). */
67
+ declare const ItemHeader: React.ForwardRefExoticComponent<ItemHeaderProps & React.RefAttributes<HTMLDivElement>>;
68
+ type ItemFooterProps = React.HTMLAttributes<HTMLDivElement>;
69
+ /** A full-width row below the main content (e.g. metadata or secondary actions). */
70
+ declare const ItemFooter: React.ForwardRefExoticComponent<ItemFooterProps & React.RefAttributes<HTMLDivElement>>;
71
+
72
+ export { Item, ItemActions, type ItemActionsProps, ItemContent, type ItemContentProps, ItemDescription, type ItemDescriptionProps, ItemFooter, type ItemFooterProps, ItemGroup, type ItemGroupProps, ItemHeader, type ItemHeaderProps, ItemMedia, type ItemMediaProps, type ItemMediaVariant, type ItemProps, ItemSeparator, type ItemSeparatorProps, type ItemSize, ItemTitle, type ItemTitleProps, type ItemVariant, itemMediaVariants, itemVariants };
package/dist/index.js ADDED
@@ -0,0 +1,133 @@
1
+ "use client";
2
+ import * as React from 'react';
3
+ import { cn, Slot } from '@nucleux/utils';
4
+ import { Separator } from '@nucleux/separator';
5
+ import { jsx } from 'react/jsx-runtime';
6
+
7
+ // src/index.tsx
8
+ var ItemGroupContext = React.createContext(false);
9
+ var ItemGroup = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(ItemGroupContext.Provider, { value: true, children: /* @__PURE__ */ jsx("div", { ref, role: "list", "data-slot": "item-group", className: cn("group/item-group flex flex-col", className), ...props }) }));
10
+ ItemGroup.displayName = "ItemGroup";
11
+ var ItemSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(Separator, { ref, "data-slot": "item-separator", orientation: "horizontal", className: cn("my-0", className), ...props }));
12
+ ItemSeparator.displayName = "ItemSeparator";
13
+ var itemBase = "group/item flex flex-wrap items-center rounded-md border border-transparent text-sm outline-none transition-colors duration-100 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [a&]:transition-colors hover:[a&]:bg-accent/50";
14
+ var itemVariantClasses = {
15
+ default: "bg-transparent",
16
+ outline: "border-border",
17
+ muted: "bg-muted/50"
18
+ };
19
+ var itemSizeClasses = {
20
+ default: "gap-4 p-4",
21
+ sm: "gap-2.5 px-4 py-3"
22
+ };
23
+ function itemVariants({
24
+ variant = "default",
25
+ size = "default",
26
+ className
27
+ } = {}) {
28
+ return cn(itemBase, itemVariantClasses[variant ?? "default"], itemSizeClasses[size ?? "default"], className);
29
+ }
30
+ var Item = React.forwardRef(
31
+ ({ className, variant = "default", size = "default", asChild = false, ...props }, ref) => {
32
+ const inGroup = React.useContext(ItemGroupContext);
33
+ const shared = {
34
+ "data-slot": "item",
35
+ "data-variant": variant,
36
+ "data-size": size,
37
+ className: itemVariants({ variant, size, className })
38
+ };
39
+ if (asChild) {
40
+ const el = /* @__PURE__ */ jsx(Slot, { ref, ...shared, ...props });
41
+ return inGroup ? /* @__PURE__ */ jsx("div", { role: "listitem", "data-slot": "item-listitem", className: "contents", children: el }) : el;
42
+ }
43
+ return /* @__PURE__ */ jsx("div", { ref, role: inGroup ? "listitem" : void 0, ...shared, ...props });
44
+ }
45
+ );
46
+ Item.displayName = "Item";
47
+ var itemMediaBase = "flex shrink-0 items-center justify-center gap-2 group-has-[[data-slot=item-description]]/item:translate-y-0.5 group-has-[[data-slot=item-description]]/item:self-start [&_svg]:pointer-events-none";
48
+ var itemMediaVariantClasses = {
49
+ default: "bg-transparent",
50
+ icon: "size-8 rounded-sm border border-border bg-muted [&_svg:not([class*='size-'])]:size-4",
51
+ image: "size-10 overflow-hidden rounded-sm [&_img]:size-full [&_img]:object-cover"
52
+ };
53
+ function itemMediaVariants({
54
+ variant = "default",
55
+ className
56
+ } = {}) {
57
+ return cn(itemMediaBase, itemMediaVariantClasses[variant ?? "default"], className);
58
+ }
59
+ var ItemMedia = React.forwardRef(
60
+ ({ className, variant = "default", ...props }, ref) => /* @__PURE__ */ jsx(
61
+ "div",
62
+ {
63
+ ref,
64
+ "data-slot": "item-media",
65
+ "data-variant": variant,
66
+ className: itemMediaVariants({ variant, className }),
67
+ ...props
68
+ }
69
+ )
70
+ );
71
+ ItemMedia.displayName = "ItemMedia";
72
+ var ItemContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
73
+ "div",
74
+ {
75
+ ref,
76
+ "data-slot": "item-content",
77
+ className: cn("flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none", className),
78
+ ...props
79
+ }
80
+ ));
81
+ ItemContent.displayName = "ItemContent";
82
+ var ItemTitle = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
83
+ "div",
84
+ {
85
+ ref,
86
+ "data-slot": "item-title",
87
+ className: cn("flex w-fit items-center gap-2 text-sm font-medium leading-snug", className),
88
+ ...props
89
+ }
90
+ ));
91
+ ItemTitle.displayName = "ItemTitle";
92
+ var ItemDescription = React.forwardRef(
93
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
94
+ "p",
95
+ {
96
+ ref,
97
+ "data-slot": "item-description",
98
+ className: cn(
99
+ "line-clamp-2 text-balance text-sm font-normal leading-normal text-muted-foreground",
100
+ "[&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
101
+ className
102
+ ),
103
+ ...props
104
+ }
105
+ )
106
+ );
107
+ ItemDescription.displayName = "ItemDescription";
108
+ var ItemActions = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, "data-slot": "item-actions", className: cn("flex items-center gap-2", className), ...props }));
109
+ ItemActions.displayName = "ItemActions";
110
+ var ItemHeader = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
111
+ "div",
112
+ {
113
+ ref,
114
+ "data-slot": "item-header",
115
+ className: cn("flex basis-full items-center justify-between gap-2", className),
116
+ ...props
117
+ }
118
+ ));
119
+ ItemHeader.displayName = "ItemHeader";
120
+ var ItemFooter = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
121
+ "div",
122
+ {
123
+ ref,
124
+ "data-slot": "item-footer",
125
+ className: cn("flex basis-full items-center justify-between gap-2", className),
126
+ ...props
127
+ }
128
+ ));
129
+ ItemFooter.displayName = "ItemFooter";
130
+
131
+ export { Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, itemMediaVariants, itemVariants };
132
+ //# sourceMappingURL=index.js.map
133
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import * as React from \"react\";\nimport { cn, Slot } from \"@nucleux/utils\";\nimport { Separator, type SeparatorProps } from \"@nucleux/separator\";\n\nexport type ItemVariant = \"default\" | \"outline\" | \"muted\";\nexport type ItemSize = \"default\" | \"sm\";\nexport type ItemMediaVariant = \"default\" | \"icon\" | \"image\";\n\nconst ItemGroupContext = React.createContext(false);\n\nexport type ItemGroupProps = React.HTMLAttributes<HTMLDivElement>;\n\n/**\n * A vertical list of Items, exposed to assistive tech as a list\n * (`role=\"list\"`). Items rendered inside get `role=\"listitem\"`; an Item\n * using `asChild` (e.g. a link) keeps its child's role and is wrapped in a\n * layout-neutral (`display: contents`) listitem.\n * Put an ItemSeparator between Items for dividing rules.\n */\nexport const ItemGroup = React.forwardRef<HTMLDivElement, ItemGroupProps>(({ className, ...props }, ref) => (\n <ItemGroupContext.Provider value={true}>\n <div ref={ref} role=\"list\" data-slot=\"item-group\" className={cn(\"group/item-group flex flex-col\", className)} {...props} />\n </ItemGroupContext.Provider>\n));\nItemGroup.displayName = \"ItemGroup\";\n\nexport type ItemSeparatorProps = SeparatorProps;\n\n/** A horizontal rule between Items in an ItemGroup. */\nexport const ItemSeparator = React.forwardRef<HTMLDivElement, ItemSeparatorProps>(({ className, ...props }, ref) => (\n <Separator ref={ref} data-slot=\"item-separator\" orientation=\"horizontal\" className={cn(\"my-0\", className)} {...props} />\n));\nItemSeparator.displayName = \"ItemSeparator\";\n\nconst itemBase =\n \"group/item flex flex-wrap items-center rounded-md border border-transparent text-sm outline-none transition-colors duration-100 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [a&]:transition-colors hover:[a&]:bg-accent/50\";\n\nconst itemVariantClasses: Record<ItemVariant, string> = {\n default: \"bg-transparent\",\n outline: \"border-border\",\n muted: \"bg-muted/50\",\n};\n\nconst itemSizeClasses: Record<ItemSize, string> = {\n default: \"gap-4 p-4\",\n sm: \"gap-2.5 px-4 py-3\",\n};\n\n/** Returns the Item class string for a variant and size (shadcn's `itemVariants` cva helper). */\nexport function itemVariants({\n variant = \"default\",\n size = \"default\",\n className,\n}: { variant?: ItemVariant | null; size?: ItemSize | null; className?: string } = {}) {\n return cn(itemBase, itemVariantClasses[variant ?? \"default\"], itemSizeClasses[size ?? \"default\"], className);\n}\n\nexport interface ItemProps extends React.HTMLAttributes<HTMLDivElement> {\n /** \"default\" (transparent), \"outline\" (bordered) or \"muted\" (soft fill). */\n variant?: ItemVariant;\n /** \"default\" (roomy) or \"sm\" (compact). */\n size?: ItemSize;\n /** Render the single child (e.g. an `<a>` or router Link) as the row, making it clickable with a hover tint. */\n asChild?: boolean;\n}\n\n/**\n * A flexible row for lists, settings and search results: media on the\n * left, title and description in the middle, actions on the right.\n * Compose ItemMedia, ItemContent (ItemTitle, ItemDescription), ItemActions,\n * and optionally ItemHeader / ItemFooter spanning the full width. Use\n * `asChild` with an `<a>` to make the whole row a link; group rows in an\n * ItemGroup.\n */\nexport const Item = React.forwardRef<HTMLDivElement, ItemProps>(\n ({ className, variant = \"default\", size = \"default\", asChild = false, ...props }, ref) => {\n const inGroup = React.useContext(ItemGroupContext);\n const shared = {\n \"data-slot\": \"item\",\n \"data-variant\": variant,\n \"data-size\": size,\n className: itemVariants({ variant, size, className }),\n };\n if (asChild) {\n const el = <Slot ref={ref} {...shared} {...props} />;\n // A link or button can't also be a listitem, so inside an ItemGroup it\n // gets a layout-neutral listitem wrapper to keep the list valid.\n return inGroup ? (\n <div role=\"listitem\" data-slot=\"item-listitem\" className=\"contents\">\n {el}\n </div>\n ) : (\n el\n );\n }\n return <div ref={ref} role={inGroup ? \"listitem\" : undefined} {...shared} {...props} />;\n },\n);\nItem.displayName = \"Item\";\n\nconst itemMediaBase =\n \"flex shrink-0 items-center justify-center gap-2 group-has-[[data-slot=item-description]]/item:translate-y-0.5 group-has-[[data-slot=item-description]]/item:self-start [&_svg]:pointer-events-none\";\n\nconst itemMediaVariantClasses: Record<ItemMediaVariant, string> = {\n default: \"bg-transparent\",\n icon: \"size-8 rounded-sm border border-border bg-muted [&_svg:not([class*='size-'])]:size-4\",\n image: \"size-10 overflow-hidden rounded-sm [&_img]:size-full [&_img]:object-cover\",\n};\n\n/** Returns the ItemMedia class string for a variant. */\nexport function itemMediaVariants({\n variant = \"default\",\n className,\n}: { variant?: ItemMediaVariant | null; className?: string } = {}) {\n return cn(itemMediaBase, itemMediaVariantClasses[variant ?? \"default\"], className);\n}\n\nexport interface ItemMediaProps extends React.HTMLAttributes<HTMLDivElement> {\n /** \"default\" (as-is, e.g. an Avatar), \"icon\" (icon in a bordered muted tile) or \"image\" (40px cover thumbnail). */\n variant?: ItemMediaVariant;\n}\n\n/** The leading icon, avatar or thumbnail; aligns to the top when the Item has a description. */\nexport const ItemMedia = React.forwardRef<HTMLDivElement, ItemMediaProps>(\n ({ className, variant = \"default\", ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"item-media\"\n data-variant={variant}\n className={itemMediaVariants({ variant, className })}\n {...props}\n />\n ),\n);\nItemMedia.displayName = \"ItemMedia\";\n\nexport type ItemContentProps = React.HTMLAttributes<HTMLDivElement>;\n\n/** The flexible middle column holding ItemTitle and ItemDescription. */\nexport const ItemContent = React.forwardRef<HTMLDivElement, ItemContentProps>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"item-content\"\n className={cn(\"flex flex-1 flex-col gap-1 [&+[data-slot=item-content]]:flex-none\", className)}\n {...props}\n />\n));\nItemContent.displayName = \"ItemContent\";\n\nexport type ItemTitleProps = React.HTMLAttributes<HTMLDivElement>;\n\n/** The row's primary label; can hold an inline Badge or icon. */\nexport const ItemTitle = React.forwardRef<HTMLDivElement, ItemTitleProps>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"item-title\"\n className={cn(\"flex w-fit items-center gap-2 text-sm font-medium leading-snug\", className)}\n {...props}\n />\n));\nItemTitle.displayName = \"ItemTitle\";\n\nexport type ItemDescriptionProps = React.HTMLAttributes<HTMLParagraphElement>;\n\n/** Secondary muted text under the title, clamped to two lines; links inside are underlined. */\nexport const ItemDescription = React.forwardRef<HTMLParagraphElement, ItemDescriptionProps>(\n ({ className, ...props }, ref) => (\n <p\n ref={ref}\n data-slot=\"item-description\"\n className={cn(\n \"line-clamp-2 text-balance text-sm font-normal leading-normal text-muted-foreground\",\n \"[&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary\",\n className,\n )}\n {...props}\n />\n ),\n);\nItemDescription.displayName = \"ItemDescription\";\n\nexport type ItemActionsProps = React.HTMLAttributes<HTMLDivElement>;\n\n/** Trailing buttons or controls for the row. */\nexport const ItemActions = React.forwardRef<HTMLDivElement, ItemActionsProps>(({ className, ...props }, ref) => (\n <div ref={ref} data-slot=\"item-actions\" className={cn(\"flex items-center gap-2\", className)} {...props} />\n));\nItemActions.displayName = \"ItemActions\";\n\nexport type ItemHeaderProps = React.HTMLAttributes<HTMLDivElement>;\n\n/** A full-width row above the main content (e.g. a cover image or a title with a menu). */\nexport const ItemHeader = React.forwardRef<HTMLDivElement, ItemHeaderProps>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"item-header\"\n className={cn(\"flex basis-full items-center justify-between gap-2\", className)}\n {...props}\n />\n));\nItemHeader.displayName = \"ItemHeader\";\n\nexport type ItemFooterProps = React.HTMLAttributes<HTMLDivElement>;\n\n/** A full-width row below the main content (e.g. metadata or secondary actions). */\nexport const ItemFooter = React.forwardRef<HTMLDivElement, ItemFooterProps>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n data-slot=\"item-footer\"\n className={cn(\"flex basis-full items-center justify-between gap-2\", className)}\n {...props}\n />\n));\nItemFooter.displayName = \"ItemFooter\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,59 @@
1
1
  {
2
2
  "name": "@nucleux/item",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.6.0",
4
+ "type": "module",
5
+ "sideEffects": false,
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md"
19
+ ],
20
+ "peerDependencies": {
21
+ "react": ">=18",
22
+ "react-dom": ">=18"
23
+ },
24
+ "dependencies": {
25
+ "@nucleux/utils": "0.6.0",
26
+ "@nucleux/separator": "0.6.0"
27
+ },
28
+ "devDependencies": {
29
+ "tsup": "^8.3.5",
30
+ "typescript": "^5.7.2",
31
+ "@types/react": "^18.3.18",
32
+ "react": "^18.3.1",
33
+ "lucide-react": "^0.469.0"
34
+ },
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "license": "MIT",
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "git+https://github.com/intelligaia-open-labs/nucleux.git",
42
+ "directory": "packages/item"
43
+ },
44
+ "homepage": "https://github.com/intelligaia-open-labs/nucleux#readme",
45
+ "description": "Flexible list row with media, content and actions — Nucleux agentic UI for React.",
46
+ "keywords": [
47
+ "nucleux",
48
+ "react",
49
+ "ui",
50
+ "components",
51
+ "agentic",
52
+ "ai",
53
+ "tailwind",
54
+ "item"
55
+ ],
56
+ "scripts": {
57
+ "build": "tsup"
58
+ }
6
59
  }