@pattern-stack/frontend-patterns 0.2.0-alpha.7 → 0.2.0-alpha.8
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/atoms/utils/index.d.ts +0 -1
- package/dist/atoms/utils/index.d.ts.map +1 -1
- package/dist/index.es.js +1 -360
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +0 -359
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2052,362 +2052,6 @@ function renderField(value, fieldName, fieldType, breakpoint, item, customRender
|
|
|
2052
2052
|
function cn(...inputs) {
|
|
2053
2053
|
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
2054
2054
|
}
|
|
2055
|
-
const STATUS_COLOR_MAP = {
|
|
2056
|
-
// Success states
|
|
2057
|
-
active: "success",
|
|
2058
|
-
completed: "success",
|
|
2059
|
-
approved: "success",
|
|
2060
|
-
paid: "success",
|
|
2061
|
-
delivered: "success",
|
|
2062
|
-
resolved: "success",
|
|
2063
|
-
closed: "success",
|
|
2064
|
-
// Warning states
|
|
2065
|
-
pending: "warning",
|
|
2066
|
-
processing: "warning",
|
|
2067
|
-
review: "warning",
|
|
2068
|
-
draft: "warning",
|
|
2069
|
-
waiting: "warning",
|
|
2070
|
-
// Error states
|
|
2071
|
-
failed: "error",
|
|
2072
|
-
rejected: "error",
|
|
2073
|
-
cancelled: "error",
|
|
2074
|
-
overdue: "error",
|
|
2075
|
-
blocked: "error",
|
|
2076
|
-
// Info states
|
|
2077
|
-
new: "info",
|
|
2078
|
-
open: "info",
|
|
2079
|
-
in_progress: "info",
|
|
2080
|
-
scheduled: "info",
|
|
2081
|
-
// Neutral (default)
|
|
2082
|
-
inactive: "neutral",
|
|
2083
|
-
archived: "neutral",
|
|
2084
|
-
unknown: "neutral"
|
|
2085
|
-
};
|
|
2086
|
-
function getStatusColor(value) {
|
|
2087
|
-
if (typeof value !== "string") return "neutral";
|
|
2088
|
-
const normalized = value.toLowerCase().replace(/[_-]/g, "_");
|
|
2089
|
-
return STATUS_COLOR_MAP[normalized] ?? "neutral";
|
|
2090
|
-
}
|
|
2091
|
-
const CATEGORY_MAP = {
|
|
2092
|
-
account: 1,
|
|
2093
|
-
customer: 1,
|
|
2094
|
-
client: 1,
|
|
2095
|
-
user: 2,
|
|
2096
|
-
contact: 2,
|
|
2097
|
-
person: 2,
|
|
2098
|
-
order: 3,
|
|
2099
|
-
sale: 3,
|
|
2100
|
-
transaction: 3,
|
|
2101
|
-
product: 4,
|
|
2102
|
-
item: 4,
|
|
2103
|
-
inventory: 4,
|
|
2104
|
-
task: 5,
|
|
2105
|
-
activity: 5,
|
|
2106
|
-
event: 5,
|
|
2107
|
-
file: 6,
|
|
2108
|
-
document: 6,
|
|
2109
|
-
report: 6,
|
|
2110
|
-
tag: 7,
|
|
2111
|
-
category: 7,
|
|
2112
|
-
label: 7,
|
|
2113
|
-
default: 8
|
|
2114
|
-
};
|
|
2115
|
-
function getCategoryForEntity(entityType) {
|
|
2116
|
-
if (!entityType) return 8;
|
|
2117
|
-
const normalized = entityType.toLowerCase();
|
|
2118
|
-
for (const [key, value] of Object.entries(CATEGORY_MAP)) {
|
|
2119
|
-
if (normalized.includes(key)) return value;
|
|
2120
|
-
}
|
|
2121
|
-
return 8;
|
|
2122
|
-
}
|
|
2123
|
-
function getIconForEntity(entityType) {
|
|
2124
|
-
if (!entityType) return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Circle, { className: "w-4 h-4" });
|
|
2125
|
-
const normalized = entityType.toLowerCase();
|
|
2126
|
-
if (normalized.includes("account") || normalized.includes("customer") || normalized.includes("client")) {
|
|
2127
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Building2, { className: "w-4 h-4" });
|
|
2128
|
-
}
|
|
2129
|
-
if (normalized.includes("user") || normalized.includes("contact") || normalized.includes("person")) {
|
|
2130
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.User, { className: "w-4 h-4" });
|
|
2131
|
-
}
|
|
2132
|
-
if (normalized.includes("product") || normalized.includes("item")) {
|
|
2133
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Package, { className: "w-4 h-4" });
|
|
2134
|
-
}
|
|
2135
|
-
if (normalized.includes("file") || normalized.includes("document")) {
|
|
2136
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "w-4 h-4" });
|
|
2137
|
-
}
|
|
2138
|
-
if (normalized.includes("tag") || normalized.includes("category")) {
|
|
2139
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Tag, { className: "w-4 h-4" });
|
|
2140
|
-
}
|
|
2141
|
-
return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Circle, { className: "w-4 h-4" });
|
|
2142
|
-
}
|
|
2143
|
-
function normalizeImportance(importance) {
|
|
2144
|
-
switch (importance) {
|
|
2145
|
-
case "critical":
|
|
2146
|
-
case "high":
|
|
2147
|
-
case "primary":
|
|
2148
|
-
return "primary";
|
|
2149
|
-
case "medium":
|
|
2150
|
-
case "secondary":
|
|
2151
|
-
return "secondary";
|
|
2152
|
-
default:
|
|
2153
|
-
return "tertiary";
|
|
2154
|
-
}
|
|
2155
|
-
}
|
|
2156
|
-
function isPrimaryImportance(importance) {
|
|
2157
|
-
return normalizeImportance(importance) === "primary";
|
|
2158
|
-
}
|
|
2159
|
-
function formatValueForCard(value, type, format) {
|
|
2160
|
-
if (value === null || value === void 0) return "—";
|
|
2161
|
-
switch (type) {
|
|
2162
|
-
case "money": {
|
|
2163
|
-
const num = Number(value);
|
|
2164
|
-
const currency = (format == null ? void 0 : format.currency) ?? "USD";
|
|
2165
|
-
if (num >= 1e6) {
|
|
2166
|
-
return new Intl.NumberFormat("en-US", {
|
|
2167
|
-
style: "currency",
|
|
2168
|
-
currency,
|
|
2169
|
-
notation: "compact",
|
|
2170
|
-
maximumFractionDigits: 1
|
|
2171
|
-
}).format(num);
|
|
2172
|
-
}
|
|
2173
|
-
if (num >= 1e3) {
|
|
2174
|
-
return new Intl.NumberFormat("en-US", {
|
|
2175
|
-
style: "currency",
|
|
2176
|
-
currency,
|
|
2177
|
-
notation: "compact",
|
|
2178
|
-
maximumFractionDigits: 1
|
|
2179
|
-
}).format(num);
|
|
2180
|
-
}
|
|
2181
|
-
return new Intl.NumberFormat("en-US", {
|
|
2182
|
-
style: "currency",
|
|
2183
|
-
currency,
|
|
2184
|
-
maximumFractionDigits: 0
|
|
2185
|
-
}).format(num);
|
|
2186
|
-
}
|
|
2187
|
-
case "percent": {
|
|
2188
|
-
const num = Number(value);
|
|
2189
|
-
return `${num.toFixed(0)}%`;
|
|
2190
|
-
}
|
|
2191
|
-
case "number": {
|
|
2192
|
-
const num = Number(value);
|
|
2193
|
-
if (num >= 1e6) return `${(num / 1e6).toFixed(1)}M`;
|
|
2194
|
-
if (num >= 1e3) return `${(num / 1e3).toFixed(1)}K`;
|
|
2195
|
-
return String(num);
|
|
2196
|
-
}
|
|
2197
|
-
case "date":
|
|
2198
|
-
case "datetime": {
|
|
2199
|
-
const date = new Date(String(value));
|
|
2200
|
-
if (isNaN(date.getTime())) return String(value);
|
|
2201
|
-
return date.toLocaleDateString("en-US", {
|
|
2202
|
-
month: "short",
|
|
2203
|
-
day: "numeric"
|
|
2204
|
-
});
|
|
2205
|
-
}
|
|
2206
|
-
case "boolean":
|
|
2207
|
-
return value ? "Yes" : "No";
|
|
2208
|
-
default:
|
|
2209
|
-
return String(value);
|
|
2210
|
-
}
|
|
2211
|
-
}
|
|
2212
|
-
function autoDetectMapping(columns) {
|
|
2213
|
-
var _a, _b, _c, _d, _e, _f;
|
|
2214
|
-
const primaryCols = columns.filter((c) => isPrimaryImportance(c.importance));
|
|
2215
|
-
const titleField = ((_a = primaryCols.find((c) => ["text", "entity", "user"].includes(c.type))) == null ? void 0 : _a.field) ?? ((_b = primaryCols[0]) == null ? void 0 : _b.field) ?? ((_c = columns[0]) == null ? void 0 : _c.field);
|
|
2216
|
-
const valueField = (_d = primaryCols.find((c) => c.type === "money")) == null ? void 0 : _d.field;
|
|
2217
|
-
const statusField = (_e = primaryCols.find(
|
|
2218
|
-
(c) => c.type === "status" || c.type === "badge"
|
|
2219
|
-
)) == null ? void 0 : _e.field;
|
|
2220
|
-
const usedForMain = new Set([titleField, valueField, statusField].filter(Boolean));
|
|
2221
|
-
const remainingPrimary = primaryCols.filter((c) => !usedForMain.has(c.field));
|
|
2222
|
-
const subtitleField = (_f = remainingPrimary[0]) == null ? void 0 : _f.field;
|
|
2223
|
-
const usedFields = new Set(
|
|
2224
|
-
[titleField, valueField, statusField, subtitleField].filter(Boolean)
|
|
2225
|
-
);
|
|
2226
|
-
const metadataFields = primaryCols.filter((c) => !usedFields.has(c.field)).slice(0, 3).map((c) => c.field);
|
|
2227
|
-
return {
|
|
2228
|
-
titleField: titleField ?? "id",
|
|
2229
|
-
subtitleField,
|
|
2230
|
-
valueField,
|
|
2231
|
-
statusField,
|
|
2232
|
-
metadataFields,
|
|
2233
|
-
iconConfig: void 0
|
|
2234
|
-
};
|
|
2235
|
-
}
|
|
2236
|
-
function entityToListCardProps(item, columns, mapping, entityType) {
|
|
2237
|
-
const autoMapping = autoDetectMapping(columns);
|
|
2238
|
-
const effectiveMapping = { ...autoMapping, ...mapping };
|
|
2239
|
-
const {
|
|
2240
|
-
titleField,
|
|
2241
|
-
subtitleField,
|
|
2242
|
-
valueField,
|
|
2243
|
-
statusField,
|
|
2244
|
-
metadataFields,
|
|
2245
|
-
iconConfig
|
|
2246
|
-
} = effectiveMapping;
|
|
2247
|
-
const getColumn = (field) => field ? columns.find((c) => c.field === field) : void 0;
|
|
2248
|
-
const title = item[titleField] != null ? String(item[titleField]) : "—";
|
|
2249
|
-
const subtitle = subtitleField && item[subtitleField] != null ? String(item[subtitleField]) : void 0;
|
|
2250
|
-
let value;
|
|
2251
|
-
if (valueField && item[valueField] != null) {
|
|
2252
|
-
const valueCol = getColumn(valueField);
|
|
2253
|
-
const formatted = formatValueForCard(
|
|
2254
|
-
item[valueField],
|
|
2255
|
-
(valueCol == null ? void 0 : valueCol.type) ?? "text",
|
|
2256
|
-
valueCol == null ? void 0 : valueCol.format
|
|
2257
|
-
);
|
|
2258
|
-
value = {
|
|
2259
|
-
text: formatted,
|
|
2260
|
-
variant: "success"
|
|
2261
|
-
// Money typically green
|
|
2262
|
-
};
|
|
2263
|
-
}
|
|
2264
|
-
let badge;
|
|
2265
|
-
if (statusField && item[statusField] != null) {
|
|
2266
|
-
const statusValue = String(item[statusField]);
|
|
2267
|
-
badge = {
|
|
2268
|
-
text: statusValue,
|
|
2269
|
-
variant: "status",
|
|
2270
|
-
status: getStatusColor(statusValue),
|
|
2271
|
-
size: "sm"
|
|
2272
|
-
};
|
|
2273
|
-
}
|
|
2274
|
-
const metadata = metadataFields == null ? void 0 : metadataFields.map((field) => {
|
|
2275
|
-
const col = getColumn(field);
|
|
2276
|
-
if (!col || item[field] == null) return null;
|
|
2277
|
-
return formatValueForCard(item[field], col.type, col.format);
|
|
2278
|
-
}).filter((v) => v !== null);
|
|
2279
|
-
let icon;
|
|
2280
|
-
if (iconConfig) {
|
|
2281
|
-
const iconValue = iconConfig.field ? item[iconConfig.field] : void 0;
|
|
2282
|
-
if (iconConfig.variant === "status" && iconValue) {
|
|
2283
|
-
icon = {
|
|
2284
|
-
icon: iconConfig.icon ?? getIconForEntity(entityType),
|
|
2285
|
-
variant: "status",
|
|
2286
|
-
status: getStatusColor(iconValue),
|
|
2287
|
-
size: "sm"
|
|
2288
|
-
};
|
|
2289
|
-
} else {
|
|
2290
|
-
icon = {
|
|
2291
|
-
icon: iconConfig.icon ?? getIconForEntity(entityType),
|
|
2292
|
-
variant: "category",
|
|
2293
|
-
category: getCategoryForEntity(entityType),
|
|
2294
|
-
size: "sm"
|
|
2295
|
-
};
|
|
2296
|
-
}
|
|
2297
|
-
} else {
|
|
2298
|
-
icon = {
|
|
2299
|
-
icon: getIconForEntity(entityType),
|
|
2300
|
-
variant: "category",
|
|
2301
|
-
category: getCategoryForEntity(entityType),
|
|
2302
|
-
size: "sm"
|
|
2303
|
-
};
|
|
2304
|
-
}
|
|
2305
|
-
return {
|
|
2306
|
-
icon,
|
|
2307
|
-
title,
|
|
2308
|
-
subtitle,
|
|
2309
|
-
metadata,
|
|
2310
|
-
value,
|
|
2311
|
-
badge
|
|
2312
|
-
};
|
|
2313
|
-
}
|
|
2314
|
-
const HEADER_ABBREVIATIONS = {
|
|
2315
|
-
customer: "Cust",
|
|
2316
|
-
account: "Acct",
|
|
2317
|
-
amount: "Amt",
|
|
2318
|
-
quantity: "Qty",
|
|
2319
|
-
priority: "Pri",
|
|
2320
|
-
status: "Status",
|
|
2321
|
-
created: "Created",
|
|
2322
|
-
updated: "Updated",
|
|
2323
|
-
description: "Desc",
|
|
2324
|
-
total: "Total",
|
|
2325
|
-
items: "Items",
|
|
2326
|
-
number: "#",
|
|
2327
|
-
date: "Date",
|
|
2328
|
-
time: "Time"
|
|
2329
|
-
};
|
|
2330
|
-
function abbreviateHeader(label) {
|
|
2331
|
-
const lower = label.toLowerCase();
|
|
2332
|
-
for (const [key, abbrev] of Object.entries(HEADER_ABBREVIATIONS)) {
|
|
2333
|
-
if (lower.includes(key)) return abbrev;
|
|
2334
|
-
}
|
|
2335
|
-
if (label.length > 8) return label.slice(0, 6) + "…";
|
|
2336
|
-
return label;
|
|
2337
|
-
}
|
|
2338
|
-
function generateCompactColumns(columns, options = {}) {
|
|
2339
|
-
const {
|
|
2340
|
-
maxColumns = 5,
|
|
2341
|
-
abbreviateHeaders = true,
|
|
2342
|
-
requiredFields = [],
|
|
2343
|
-
excludeFields = []
|
|
2344
|
-
} = options;
|
|
2345
|
-
const excludeSet = new Set(excludeFields);
|
|
2346
|
-
const requiredSet = new Set(requiredFields);
|
|
2347
|
-
const filteredColumns = columns.filter((col) => {
|
|
2348
|
-
if (excludeSet.has(col.field)) return false;
|
|
2349
|
-
return true;
|
|
2350
|
-
});
|
|
2351
|
-
const required = filteredColumns.filter((c) => requiredSet.has(c.field));
|
|
2352
|
-
const primary = filteredColumns.filter(
|
|
2353
|
-
(c) => !requiredSet.has(c.field) && normalizeImportance(c.importance) === "primary"
|
|
2354
|
-
);
|
|
2355
|
-
const secondary = filteredColumns.filter(
|
|
2356
|
-
(c) => !requiredSet.has(c.field) && normalizeImportance(c.importance) === "secondary"
|
|
2357
|
-
);
|
|
2358
|
-
const selectedColumns = [...required, ...primary, ...secondary].slice(
|
|
2359
|
-
0,
|
|
2360
|
-
maxColumns
|
|
2361
|
-
);
|
|
2362
|
-
return selectedColumns.map((col) => ({
|
|
2363
|
-
key: col.field,
|
|
2364
|
-
header: abbreviateHeaders ? abbreviateHeader(col.label) : col.label,
|
|
2365
|
-
sortable: col.sortable,
|
|
2366
|
-
type: col.type,
|
|
2367
|
-
format: col.format,
|
|
2368
|
-
// Compact widths
|
|
2369
|
-
width: getCompactWidth(col.type)
|
|
2370
|
-
}));
|
|
2371
|
-
}
|
|
2372
|
-
function getCompactWidth(type) {
|
|
2373
|
-
switch (type) {
|
|
2374
|
-
case "money":
|
|
2375
|
-
return "70px";
|
|
2376
|
-
case "number":
|
|
2377
|
-
case "percent":
|
|
2378
|
-
return "50px";
|
|
2379
|
-
case "status":
|
|
2380
|
-
case "badge":
|
|
2381
|
-
return "80px";
|
|
2382
|
-
case "date":
|
|
2383
|
-
return "70px";
|
|
2384
|
-
case "datetime":
|
|
2385
|
-
return "90px";
|
|
2386
|
-
case "boolean":
|
|
2387
|
-
return "50px";
|
|
2388
|
-
default:
|
|
2389
|
-
return "120px";
|
|
2390
|
-
}
|
|
2391
|
-
}
|
|
2392
|
-
function createMobileCardRenderer(columns, mapping, entityType) {
|
|
2393
|
-
const { ListCard: ListCard2 } = require("../components/data/ListCard");
|
|
2394
|
-
return ({ data, onItemClick }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: data.map((item, index) => {
|
|
2395
|
-
const cardProps = entityToListCardProps(
|
|
2396
|
-
item,
|
|
2397
|
-
columns,
|
|
2398
|
-
mapping,
|
|
2399
|
-
entityType
|
|
2400
|
-
);
|
|
2401
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2402
|
-
ListCard2,
|
|
2403
|
-
{
|
|
2404
|
-
...cardProps,
|
|
2405
|
-
onClick: onItemClick ? () => onItemClick(item) : void 0
|
|
2406
|
-
},
|
|
2407
|
-
item.id ?? index
|
|
2408
|
-
);
|
|
2409
|
-
}) });
|
|
2410
|
-
}
|
|
2411
2055
|
let globalAuthService = null;
|
|
2412
2056
|
function setGlobalAuthService(authService) {
|
|
2413
2057
|
globalAuthService = authService;
|
|
@@ -17766,17 +17410,14 @@ exports.breakpoints = breakpoints;
|
|
|
17766
17410
|
exports.cn = cn;
|
|
17767
17411
|
exports.createAPIDataTemplate = createAPIDataTemplate;
|
|
17768
17412
|
exports.createApiClient = createApiClient;
|
|
17769
|
-
exports.createMobileCardRenderer = createMobileCardRenderer;
|
|
17770
17413
|
exports.createReactApp = createReactApp;
|
|
17771
17414
|
exports.createSimpleApp = createSimpleApp;
|
|
17772
17415
|
exports.defaultFieldRenderers = defaultFieldRenderers;
|
|
17773
17416
|
exports.detectBulkOperationType = detectBulkOperationType;
|
|
17774
17417
|
exports.detectUIConfig = detectUIConfig;
|
|
17775
|
-
exports.entityToListCardProps = entityToListCardProps;
|
|
17776
17418
|
exports.env = env;
|
|
17777
17419
|
exports.formatNumberWithTooltip = formatNumberWithTooltip;
|
|
17778
17420
|
exports.generateBulkOperationName = generateBulkOperationName;
|
|
17779
|
-
exports.generateCompactColumns = generateCompactColumns;
|
|
17780
17421
|
exports.getAnimationClasses = getAnimationClasses;
|
|
17781
17422
|
exports.getChartHeight = getChartHeight;
|
|
17782
17423
|
exports.getContainerHeightClass = getContainerHeightClass;
|