@nexub/patterns 0.0.2 → 1.1.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/dist/index.js CHANGED
@@ -1,330 +1,43 @@
1
- import * as React from 'react';
2
- import { cn, Avatar, Badge, Button } from '@nexub/react';
3
- import { jsx, jsxs } from 'react/jsx-runtime';
4
- import { TrendingUp, TrendingDown, Minus, Check } from '@nexub/icons';
5
-
6
- // src/components/ActivityFeed/ActivityFeed.tsx
7
- var Root = React.forwardRef(
8
- ({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(
9
- "ul",
10
- {
11
- ref,
12
- role: "feed",
13
- "aria-label": "Activity feed",
14
- className: cn("flex flex-col divide-y divide-[var(--color-border-default)]", className),
15
- ...props,
16
- children
17
- }
18
- )
19
- );
20
- Root.displayName = "ActivityFeed.Root";
21
- var Item = ({ avatar, title, description, timestamp, className }) => /* @__PURE__ */ jsxs("li", { className: cn("flex items-start gap-3 py-3", className), children: [
22
- avatar && /* @__PURE__ */ jsx("div", { className: "shrink-0 mt-0.5", children: avatar }),
23
- /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
24
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-[var(--color-text-primary)]", children: title }),
25
- description && /* @__PURE__ */ jsx("p", { className: "text-sm text-[var(--color-text-muted)] mt-0.5", children: description })
26
- ] }),
27
- timestamp && /* @__PURE__ */ jsx("time", { className: "shrink-0 text-xs text-[var(--color-text-muted)]", children: timestamp })
28
- ] });
29
- Item.displayName = "ActivityFeed.Item";
30
- var ActivityFeed = { Root, Item };
31
- var FilterBar = React.forwardRef(
32
- ({ searchPlaceholder, onSearch, searchValue, filters, actions, className, ...props }, ref) => /* @__PURE__ */ jsxs("div", { ref, className: cn("flex flex-wrap items-center gap-3", className), ...props, children: [
33
- /* @__PURE__ */ jsx(
34
- "input",
35
- {
36
- type: "search",
37
- placeholder: searchPlaceholder ?? "Search\u2026",
38
- value: searchValue,
39
- onChange: (e) => onSearch?.(e.target.value),
40
- className: "h-9 rounded-md border border-[var(--color-border-default)] bg-[var(--color-bg-default)] px-3 py-2 text-sm placeholder:text-[var(--color-text-muted)] focus:outline-none focus:ring-2 focus:ring-[var(--color-brand-primary-500)] w-full sm:w-64"
41
- }
42
- ),
43
- filters && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-2", children: filters }),
44
- actions && /* @__PURE__ */ jsx("div", { className: "ml-auto flex items-center gap-2", children: actions })
45
- ] })
46
- );
47
- FilterBar.displayName = "FilterBar";
48
- var StatCard = React.forwardRef(
49
- ({
50
- label,
51
- value,
52
- delta,
53
- deltaType = "neutral",
54
- icon,
55
- description,
56
- className,
57
- ...props
58
- }, ref) => {
59
- const deltaColor = deltaType === "increase" ? "var(--color-success-500)" : deltaType === "decrease" ? "var(--color-error-500)" : "var(--color-text-muted)";
60
- const DeltaIcon = deltaType === "increase" ? TrendingUp : deltaType === "decrease" ? TrendingDown : Minus;
61
- return /* @__PURE__ */ jsxs(
62
- "div",
63
- {
64
- ref,
65
- className: cn(
66
- "rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-default)] p-6 flex flex-col gap-3",
67
- className
68
- ),
69
- ...props,
70
- children: [
71
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
72
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-[var(--color-text-muted)]", children: label }),
73
- icon && /* @__PURE__ */ jsx("span", { className: "text-[var(--color-text-muted)]", children: icon })
74
- ] }),
75
- /* @__PURE__ */ jsx("div", { className: "text-3xl font-bold tracking-tight text-[var(--color-text-primary)]", children: value }),
76
- (delta || description) && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
77
- delta && /* @__PURE__ */ jsxs(
78
- "span",
79
- {
80
- className: "inline-flex items-center gap-1 text-xs font-medium",
81
- style: { color: deltaColor },
82
- "data-delta-type": deltaType,
83
- children: [
84
- /* @__PURE__ */ jsx(DeltaIcon, { size: "xs", "aria-hidden": "true" }),
85
- delta
86
- ]
87
- }
88
- ),
89
- description && /* @__PURE__ */ jsx("span", { className: "text-xs text-[var(--color-text-muted)]", children: description })
90
- ] })
91
- ]
92
- }
93
- );
94
- }
95
- );
96
- StatCard.displayName = "StatCard";
97
- var UserCard = React.forwardRef(
98
- ({
99
- name,
100
- role,
101
- email,
102
- avatarSrc,
103
- avatarFallback,
104
- actions,
105
- size = "md",
106
- className,
107
- ...props
108
- }, ref) => {
109
- return /* @__PURE__ */ jsxs(
110
- "div",
111
- {
112
- ref,
113
- className: cn(
114
- "flex items-center gap-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-default)] p-4",
115
- className
116
- ),
117
- ...props,
118
- children: [
119
- /* @__PURE__ */ jsx(
120
- Avatar,
121
- {
122
- size,
123
- src: avatarSrc,
124
- name,
125
- fallback: avatarFallback
126
- }
127
- ),
128
- /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 flex flex-col gap-0.5", children: [
129
- /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-[var(--color-text-primary)] truncate", children: name }),
130
- role && /* @__PURE__ */ jsx("span", { className: "text-xs text-[var(--color-text-muted)] truncate", children: role }),
131
- email && /* @__PURE__ */ jsx("span", { className: "text-xs text-[var(--color-text-secondary)] truncate", children: email })
132
- ] }),
133
- actions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 shrink-0", children: actions })
134
- ]
135
- }
136
- );
137
- }
138
- );
139
- UserCard.displayName = "UserCard";
140
- function AuthCard({
141
- logo,
142
- title,
143
- description,
144
- children,
145
- footer,
146
- className
147
- }) {
148
- return /* @__PURE__ */ jsxs(
149
- "div",
150
- {
151
- className: cn(
152
- "mx-auto w-full max-w-[400px] flex flex-col gap-6",
153
- className
154
- ),
155
- children: [
156
- logo && /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: logo }),
157
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 text-center", children: [
158
- /* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold tracking-tight text-[var(--color-text-primary)]", children: title }),
159
- description && /* @__PURE__ */ jsx("p", { className: "text-sm text-[var(--color-text-muted)]", children: description })
160
- ] }),
161
- /* @__PURE__ */ jsx("div", { className: "rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-default)] p-6 flex flex-col gap-4", children }),
162
- footer && /* @__PURE__ */ jsx("div", { className: "flex flex-col items-center gap-2 text-sm text-[var(--color-text-muted)]", children: footer })
163
- ]
164
- }
165
- );
166
- }
167
- AuthCard.displayName = "AuthCard";
168
- var SettingsSection = React.forwardRef(
169
- ({ title, description, actions, children, className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col gap-8", className), ...props, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-6 md:flex-row md:gap-8", children: [
170
- /* @__PURE__ */ jsxs("div", { className: "md:w-1/3 flex flex-col gap-1", children: [
171
- /* @__PURE__ */ jsx("h2", { className: "text-base font-semibold text-[var(--color-text-primary)]", children: title }),
172
- description && /* @__PURE__ */ jsx("p", { className: "text-sm text-[var(--color-text-muted)]", children: description })
173
- ] }),
174
- /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col gap-4", children: [
175
- children,
176
- actions && /* @__PURE__ */ jsx("div", { className: "flex justify-end gap-2", children: actions })
177
- ] })
178
- ] }) })
179
- );
180
- SettingsSection.displayName = "SettingsSection";
181
- var Root2 = React.forwardRef(
182
- ({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(
183
- "dl",
184
- {
185
- ref,
186
- className: cn("divide-y divide-[var(--color-border-default)]", className),
187
- ...props,
188
- children
189
- }
190
- )
191
- );
192
- Root2.displayName = "InfoList.Root";
193
- var Item2 = ({ label, value, className }) => /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between py-3 gap-4", className), children: [
194
- /* @__PURE__ */ jsx("dt", { className: "text-sm text-[var(--color-text-muted)] shrink-0", children: label }),
195
- /* @__PURE__ */ jsx("dd", { className: "text-sm font-medium text-[var(--color-text-primary)] text-right", children: value })
196
- ] });
197
- Item2.displayName = "InfoList.Item";
198
- var InfoList = { Root: Root2, Item: Item2 };
199
- var PlanCard = React.forwardRef(
200
- ({
201
- name,
202
- price,
203
- period,
204
- description,
205
- features,
206
- cta,
207
- onSelect,
208
- highlighted = false,
209
- badge,
210
- className,
211
- ...props
212
- }, ref) => /* @__PURE__ */ jsxs(
213
- "div",
214
- {
215
- ref,
216
- className: cn(
217
- "relative flex flex-col gap-6 rounded-xl border bg-[var(--color-bg-default)] p-6",
218
- highlighted ? "border-[var(--color-brand-primary-500)] shadow-lg ring-1 ring-[var(--color-brand-primary-500)]" : "border-[var(--color-border-default)]",
219
- className
220
- ),
221
- ...props,
222
- children: [
223
- badge && /* @__PURE__ */ jsx("div", { className: "absolute -top-3 left-1/2 -translate-x-1/2", children: /* @__PURE__ */ jsx(Badge, { tone: "info", children: badge }) }),
224
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
225
- /* @__PURE__ */ jsx("p", { className: "text-base font-semibold text-[var(--color-text-primary)]", children: name }),
226
- /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-1", children: [
227
- /* @__PURE__ */ jsx("span", { className: "text-3xl font-bold text-[var(--color-text-primary)]", children: price }),
228
- period && /* @__PURE__ */ jsx("span", { className: "text-sm text-[var(--color-text-muted)]", children: period })
229
- ] }),
230
- description && /* @__PURE__ */ jsx("p", { className: "text-sm text-[var(--color-text-muted)]", children: description })
231
- ] }),
232
- /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-2", children: features.map((feature) => /* @__PURE__ */ jsxs(
233
- "li",
234
- {
235
- className: "flex items-center gap-2 text-sm text-[var(--color-text-secondary)]",
236
- children: [
237
- /* @__PURE__ */ jsx(Check, { size: "xs", className: "text-[var(--color-success-500)] shrink-0", "aria-hidden": "true" }),
238
- feature
239
- ]
240
- },
241
- feature
242
- )) }),
243
- /* @__PURE__ */ jsx(
244
- Button,
245
- {
246
- variant: highlighted ? "primary" : "outline",
247
- className: "mt-auto w-full",
248
- onClick: onSelect,
249
- children: cta
250
- }
251
- )
252
- ]
253
- }
254
- )
255
- );
256
- PlanCard.displayName = "PlanCard";
257
- var StepIndicator = React.forwardRef(
258
- ({ steps, currentStep, className, ...props }, ref) => /* @__PURE__ */ jsx("ol", { ref, className: cn("flex flex-col gap-0", className), ...props, children: steps.map((step, index) => {
259
- const status = index < currentStep ? "complete" : index === currentStep ? "current" : "upcoming";
260
- return /* @__PURE__ */ jsxs("li", { className: "relative flex gap-4 pb-6 last:pb-0", children: [
261
- index < steps.length - 1 && /* @__PURE__ */ jsx(
262
- "div",
263
- {
264
- className: "absolute left-4 top-8 h-full w-px bg-[var(--color-border-default)]",
265
- "aria-hidden": "true"
266
- }
267
- ),
268
- /* @__PURE__ */ jsx(
269
- "div",
270
- {
271
- className: cn(
272
- "relative z-10 flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-xs font-semibold",
273
- status === "complete" && "bg-[var(--color-brand-primary-500)] text-white",
274
- status === "current" && "border-2 border-[var(--color-brand-primary-500)] text-[var(--color-brand-primary-500)] bg-[var(--color-bg-default)]",
275
- status === "upcoming" && "border-2 border-[var(--color-border-default)] text-[var(--color-text-muted)] bg-[var(--color-bg-default)]"
276
- ),
277
- "aria-current": status === "current" ? "step" : void 0,
278
- children: status === "complete" ? /* @__PURE__ */ jsx(Check, { size: "xs", "aria-hidden": "true" }) : index + 1
279
- }
280
- ),
281
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5 pt-0.5", children: [
282
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-[var(--color-text-primary)]", children: step.label }),
283
- step.description && /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--color-text-muted)]", children: step.description })
284
- ] })
285
- ] }, step.label);
286
- }) })
287
- );
288
- StepIndicator.displayName = "StepIndicator";
289
- var NotificationItem = React.forwardRef(
290
- ({ title, description, timestamp, read = false, icon, onDismiss, className, ...props }, ref) => /* @__PURE__ */ jsxs(
291
- "div",
292
- {
293
- ref,
294
- className: cn(
295
- "flex items-start gap-3 p-3 rounded-lg transition-colors hover:bg-[var(--color-bg-subtle)]",
296
- !read && "bg-[var(--color-bg-subtle)]",
297
- className
298
- ),
299
- ...props,
300
- children: [
301
- !read && /* @__PURE__ */ jsx(
302
- "span",
303
- {
304
- className: "mt-1.5 h-2 w-2 shrink-0 rounded-full bg-[var(--color-brand-primary-500)]",
305
- "aria-label": "Unread"
306
- }
307
- ),
308
- icon && /* @__PURE__ */ jsx("div", { className: "shrink-0 mt-0.5", children: icon }),
309
- /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
310
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-[var(--color-text-primary)] truncate", children: title }),
311
- description && /* @__PURE__ */ jsx("p", { className: "text-sm text-[var(--color-text-muted)] mt-0.5 line-clamp-2", children: description }),
312
- timestamp && /* @__PURE__ */ jsx("time", { className: "text-xs text-[var(--color-text-muted)] mt-1 block", children: timestamp })
313
- ] }),
314
- onDismiss && /* @__PURE__ */ jsx(
315
- "button",
316
- {
317
- type: "button",
318
- onClick: onDismiss,
319
- "aria-label": "Dismiss notification",
320
- className: "shrink-0 text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)] p-1 rounded",
321
- children: "\xD7"
322
- }
323
- )
324
- ]
325
- }
326
- )
327
- );
328
- NotificationItem.displayName = "NotificationItem";
329
-
330
- export { ActivityFeed, AuthCard, FilterBar, InfoList, NotificationItem, PlanCard, SettingsSection, StatCard, StepIndicator, UserCard };
1
+ 'use client';
2
+ import {
3
+ StatCard
4
+ } from "./chunk-7GYTYFUD.js";
5
+ import {
6
+ StepIndicator
7
+ } from "./chunk-MXPRKZPB.js";
8
+ import {
9
+ UserCard
10
+ } from "./chunk-AEYLZU3F.js";
11
+ import {
12
+ ActivityFeed
13
+ } from "./chunk-YX7UO577.js";
14
+ import {
15
+ AuthCard
16
+ } from "./chunk-AOE6GQSH.js";
17
+ import {
18
+ FilterBar
19
+ } from "./chunk-EOA5C3Q4.js";
20
+ import {
21
+ InfoList
22
+ } from "./chunk-74JVLMLE.js";
23
+ import {
24
+ NotificationItem
25
+ } from "./chunk-Y3TNGDKC.js";
26
+ import {
27
+ PlanCard
28
+ } from "./chunk-QMYBXQG4.js";
29
+ import {
30
+ SettingsSection
31
+ } from "./chunk-OTNHVOPC.js";
32
+ export {
33
+ ActivityFeed,
34
+ AuthCard,
35
+ FilterBar,
36
+ InfoList,
37
+ NotificationItem,
38
+ PlanCard,
39
+ SettingsSection,
40
+ StatCard,
41
+ StepIndicator,
42
+ UserCard
43
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexub/patterns",
3
- "version": "0.0.2",
3
+ "version": "1.1.0",
4
4
  "description": "Composite UI patterns for Nexub Design System — pre-built, production-ready layouts and widgets built on @nexub/react.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -27,19 +27,18 @@
27
27
  "exports": {
28
28
  ".": {
29
29
  "types": "./dist/index.d.ts",
30
- "import": "./dist/index.js",
31
- "require": "./dist/index.cjs"
32
- }
30
+ "default": "./dist/index.js"
31
+ },
32
+ "./package.json": "./package.json"
33
33
  },
34
- "main": "./dist/index.cjs",
34
+ "main": "./dist/index.js",
35
35
  "types": "./dist/index.d.ts",
36
- "module": "./dist/index.js",
37
36
  "peerDependencies": {
38
37
  "react": ">=18 <20",
39
38
  "react-dom": ">=18 <20",
40
- "@nexub/react": "*",
41
- "@nexub/icons": "*",
42
- "@nexub/tokens": "*"
39
+ "@nexub/react": "^1.1.0",
40
+ "@nexub/icons": "^1.1.0",
41
+ "@nexub/tokens": "^1.1.0"
43
42
  },
44
43
  "peerDependenciesMeta": {
45
44
  "@nexub/icons": {
@@ -59,15 +58,16 @@
59
58
  "tsup": "^8.3.5",
60
59
  "typescript": "^5.6.3",
61
60
  "vitest": "^2.1.8",
62
- "@nexub/icons": "0.0.2",
63
- "@nexub/react": "0.0.2",
64
- "@nexub/tokens": "0.0.2"
61
+ "@nexub/icons": "1.1.0",
62
+ "@nexub/react": "1.1.0",
63
+ "@nexub/tokens": "1.1.0"
65
64
  },
66
65
  "scripts": {
67
66
  "build": "tsup",
68
67
  "dev": "tsup --watch",
69
68
  "clean": "rm -rf dist",
70
69
  "typecheck": "tsc --noEmit",
71
- "test": "vitest run"
70
+ "test": "vitest run",
71
+ "lint": "eslint src"
72
72
  }
73
73
  }