@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atoms/utils/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atoms/utils/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC"}
|
package/dist/index.es.js
CHANGED
|
@@ -9,7 +9,7 @@ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
|
9
9
|
import * as React from "react";
|
|
10
10
|
import React__default, { useRef, useState, useEffect, useMemo, forwardRef, useCallback, useContext, createContext, useId, Component } from "react";
|
|
11
11
|
import * as SheetPrimitive from "@radix-ui/react-dialog";
|
|
12
|
-
import { Map as Map$1, Calculator, Brain, User, Handshake, Truck, Building, HelpCircle, Info, AlertCircle, Check, ArrowDown, ArrowUp, ArrowLeft, ArrowRight, ChevronUp, ChevronLeft, ChevronDown, ChevronRight, Music, Video, Image, Folder, File, Flag, Tag, Bookmark, Heart, Star, MapPin, Clock, Calendar, Phone, Mail, Unlock, Lock, Share, Upload, Download, Eye, Trash2, Edit, Plus, Search, Bell, Settings, Home, Layout, TrendingUp, Database, BarChart3, Users, Shield, X, Menu, Palette,
|
|
12
|
+
import { Map as Map$1, Calculator, Brain, User, Handshake, Truck, Building, HelpCircle, Info, AlertCircle, Check, ArrowDown, ArrowUp, ArrowLeft, ArrowRight, ChevronUp, ChevronLeft, ChevronDown, ChevronRight, Music, Video, Image, Folder, File, Flag, Tag, Bookmark, Heart, Star, MapPin, Clock, Calendar, Phone, Mail, Unlock, Lock, Share, Upload, Download, Eye, Trash2, Edit, Plus, Search, Bell, Settings, Home, Layout, TrendingUp, Database, BarChart3, Users, Shield, X, Menu, Palette, Loader2, EyeOff, InfoIcon, Circle, ChevronsUpDown, AreaChart, LineChart, TrendingDown, Minus, AlertTriangle, Activity, WifiOff, CloudOff, Cloud, CheckCircle, FileX, Sun, Moon, LogOut, Square, Waves, Zap, TreePine, Sparkles, Sunset, Building2, DollarSign, ShoppingCart, Target, ExternalLink, MoreHorizontal, Filter, Edit2, Undo2, RefreshCw, FileText, History, Save, Copy, Grid3X3, Layers, XCircle, Briefcase } from "lucide-react";
|
|
13
13
|
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
14
14
|
import { cva } from "class-variance-authority";
|
|
15
15
|
import * as AvatarPrimitive from "@radix-ui/react-avatar";
|
|
@@ -2009,362 +2009,6 @@ function renderField(value, fieldName, fieldType, breakpoint, item, customRender
|
|
|
2009
2009
|
function cn(...inputs) {
|
|
2010
2010
|
return twMerge(clsx(inputs));
|
|
2011
2011
|
}
|
|
2012
|
-
const STATUS_COLOR_MAP = {
|
|
2013
|
-
// Success states
|
|
2014
|
-
active: "success",
|
|
2015
|
-
completed: "success",
|
|
2016
|
-
approved: "success",
|
|
2017
|
-
paid: "success",
|
|
2018
|
-
delivered: "success",
|
|
2019
|
-
resolved: "success",
|
|
2020
|
-
closed: "success",
|
|
2021
|
-
// Warning states
|
|
2022
|
-
pending: "warning",
|
|
2023
|
-
processing: "warning",
|
|
2024
|
-
review: "warning",
|
|
2025
|
-
draft: "warning",
|
|
2026
|
-
waiting: "warning",
|
|
2027
|
-
// Error states
|
|
2028
|
-
failed: "error",
|
|
2029
|
-
rejected: "error",
|
|
2030
|
-
cancelled: "error",
|
|
2031
|
-
overdue: "error",
|
|
2032
|
-
blocked: "error",
|
|
2033
|
-
// Info states
|
|
2034
|
-
new: "info",
|
|
2035
|
-
open: "info",
|
|
2036
|
-
in_progress: "info",
|
|
2037
|
-
scheduled: "info",
|
|
2038
|
-
// Neutral (default)
|
|
2039
|
-
inactive: "neutral",
|
|
2040
|
-
archived: "neutral",
|
|
2041
|
-
unknown: "neutral"
|
|
2042
|
-
};
|
|
2043
|
-
function getStatusColor(value) {
|
|
2044
|
-
if (typeof value !== "string") return "neutral";
|
|
2045
|
-
const normalized = value.toLowerCase().replace(/[_-]/g, "_");
|
|
2046
|
-
return STATUS_COLOR_MAP[normalized] ?? "neutral";
|
|
2047
|
-
}
|
|
2048
|
-
const CATEGORY_MAP = {
|
|
2049
|
-
account: 1,
|
|
2050
|
-
customer: 1,
|
|
2051
|
-
client: 1,
|
|
2052
|
-
user: 2,
|
|
2053
|
-
contact: 2,
|
|
2054
|
-
person: 2,
|
|
2055
|
-
order: 3,
|
|
2056
|
-
sale: 3,
|
|
2057
|
-
transaction: 3,
|
|
2058
|
-
product: 4,
|
|
2059
|
-
item: 4,
|
|
2060
|
-
inventory: 4,
|
|
2061
|
-
task: 5,
|
|
2062
|
-
activity: 5,
|
|
2063
|
-
event: 5,
|
|
2064
|
-
file: 6,
|
|
2065
|
-
document: 6,
|
|
2066
|
-
report: 6,
|
|
2067
|
-
tag: 7,
|
|
2068
|
-
category: 7,
|
|
2069
|
-
label: 7,
|
|
2070
|
-
default: 8
|
|
2071
|
-
};
|
|
2072
|
-
function getCategoryForEntity(entityType) {
|
|
2073
|
-
if (!entityType) return 8;
|
|
2074
|
-
const normalized = entityType.toLowerCase();
|
|
2075
|
-
for (const [key, value] of Object.entries(CATEGORY_MAP)) {
|
|
2076
|
-
if (normalized.includes(key)) return value;
|
|
2077
|
-
}
|
|
2078
|
-
return 8;
|
|
2079
|
-
}
|
|
2080
|
-
function getIconForEntity(entityType) {
|
|
2081
|
-
if (!entityType) return /* @__PURE__ */ jsx(Circle, { className: "w-4 h-4" });
|
|
2082
|
-
const normalized = entityType.toLowerCase();
|
|
2083
|
-
if (normalized.includes("account") || normalized.includes("customer") || normalized.includes("client")) {
|
|
2084
|
-
return /* @__PURE__ */ jsx(Building2, { className: "w-4 h-4" });
|
|
2085
|
-
}
|
|
2086
|
-
if (normalized.includes("user") || normalized.includes("contact") || normalized.includes("person")) {
|
|
2087
|
-
return /* @__PURE__ */ jsx(User, { className: "w-4 h-4" });
|
|
2088
|
-
}
|
|
2089
|
-
if (normalized.includes("product") || normalized.includes("item")) {
|
|
2090
|
-
return /* @__PURE__ */ jsx(Package, { className: "w-4 h-4" });
|
|
2091
|
-
}
|
|
2092
|
-
if (normalized.includes("file") || normalized.includes("document")) {
|
|
2093
|
-
return /* @__PURE__ */ jsx(FileText, { className: "w-4 h-4" });
|
|
2094
|
-
}
|
|
2095
|
-
if (normalized.includes("tag") || normalized.includes("category")) {
|
|
2096
|
-
return /* @__PURE__ */ jsx(Tag, { className: "w-4 h-4" });
|
|
2097
|
-
}
|
|
2098
|
-
return /* @__PURE__ */ jsx(Circle, { className: "w-4 h-4" });
|
|
2099
|
-
}
|
|
2100
|
-
function normalizeImportance(importance) {
|
|
2101
|
-
switch (importance) {
|
|
2102
|
-
case "critical":
|
|
2103
|
-
case "high":
|
|
2104
|
-
case "primary":
|
|
2105
|
-
return "primary";
|
|
2106
|
-
case "medium":
|
|
2107
|
-
case "secondary":
|
|
2108
|
-
return "secondary";
|
|
2109
|
-
default:
|
|
2110
|
-
return "tertiary";
|
|
2111
|
-
}
|
|
2112
|
-
}
|
|
2113
|
-
function isPrimaryImportance(importance) {
|
|
2114
|
-
return normalizeImportance(importance) === "primary";
|
|
2115
|
-
}
|
|
2116
|
-
function formatValueForCard(value, type, format) {
|
|
2117
|
-
if (value === null || value === void 0) return "—";
|
|
2118
|
-
switch (type) {
|
|
2119
|
-
case "money": {
|
|
2120
|
-
const num = Number(value);
|
|
2121
|
-
const currency = (format == null ? void 0 : format.currency) ?? "USD";
|
|
2122
|
-
if (num >= 1e6) {
|
|
2123
|
-
return new Intl.NumberFormat("en-US", {
|
|
2124
|
-
style: "currency",
|
|
2125
|
-
currency,
|
|
2126
|
-
notation: "compact",
|
|
2127
|
-
maximumFractionDigits: 1
|
|
2128
|
-
}).format(num);
|
|
2129
|
-
}
|
|
2130
|
-
if (num >= 1e3) {
|
|
2131
|
-
return new Intl.NumberFormat("en-US", {
|
|
2132
|
-
style: "currency",
|
|
2133
|
-
currency,
|
|
2134
|
-
notation: "compact",
|
|
2135
|
-
maximumFractionDigits: 1
|
|
2136
|
-
}).format(num);
|
|
2137
|
-
}
|
|
2138
|
-
return new Intl.NumberFormat("en-US", {
|
|
2139
|
-
style: "currency",
|
|
2140
|
-
currency,
|
|
2141
|
-
maximumFractionDigits: 0
|
|
2142
|
-
}).format(num);
|
|
2143
|
-
}
|
|
2144
|
-
case "percent": {
|
|
2145
|
-
const num = Number(value);
|
|
2146
|
-
return `${num.toFixed(0)}%`;
|
|
2147
|
-
}
|
|
2148
|
-
case "number": {
|
|
2149
|
-
const num = Number(value);
|
|
2150
|
-
if (num >= 1e6) return `${(num / 1e6).toFixed(1)}M`;
|
|
2151
|
-
if (num >= 1e3) return `${(num / 1e3).toFixed(1)}K`;
|
|
2152
|
-
return String(num);
|
|
2153
|
-
}
|
|
2154
|
-
case "date":
|
|
2155
|
-
case "datetime": {
|
|
2156
|
-
const date = new Date(String(value));
|
|
2157
|
-
if (isNaN(date.getTime())) return String(value);
|
|
2158
|
-
return date.toLocaleDateString("en-US", {
|
|
2159
|
-
month: "short",
|
|
2160
|
-
day: "numeric"
|
|
2161
|
-
});
|
|
2162
|
-
}
|
|
2163
|
-
case "boolean":
|
|
2164
|
-
return value ? "Yes" : "No";
|
|
2165
|
-
default:
|
|
2166
|
-
return String(value);
|
|
2167
|
-
}
|
|
2168
|
-
}
|
|
2169
|
-
function autoDetectMapping(columns) {
|
|
2170
|
-
var _a, _b, _c, _d, _e, _f;
|
|
2171
|
-
const primaryCols = columns.filter((c) => isPrimaryImportance(c.importance));
|
|
2172
|
-
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);
|
|
2173
|
-
const valueField = (_d = primaryCols.find((c) => c.type === "money")) == null ? void 0 : _d.field;
|
|
2174
|
-
const statusField = (_e = primaryCols.find(
|
|
2175
|
-
(c) => c.type === "status" || c.type === "badge"
|
|
2176
|
-
)) == null ? void 0 : _e.field;
|
|
2177
|
-
const usedForMain = new Set([titleField, valueField, statusField].filter(Boolean));
|
|
2178
|
-
const remainingPrimary = primaryCols.filter((c) => !usedForMain.has(c.field));
|
|
2179
|
-
const subtitleField = (_f = remainingPrimary[0]) == null ? void 0 : _f.field;
|
|
2180
|
-
const usedFields = new Set(
|
|
2181
|
-
[titleField, valueField, statusField, subtitleField].filter(Boolean)
|
|
2182
|
-
);
|
|
2183
|
-
const metadataFields = primaryCols.filter((c) => !usedFields.has(c.field)).slice(0, 3).map((c) => c.field);
|
|
2184
|
-
return {
|
|
2185
|
-
titleField: titleField ?? "id",
|
|
2186
|
-
subtitleField,
|
|
2187
|
-
valueField,
|
|
2188
|
-
statusField,
|
|
2189
|
-
metadataFields,
|
|
2190
|
-
iconConfig: void 0
|
|
2191
|
-
};
|
|
2192
|
-
}
|
|
2193
|
-
function entityToListCardProps(item, columns, mapping, entityType) {
|
|
2194
|
-
const autoMapping = autoDetectMapping(columns);
|
|
2195
|
-
const effectiveMapping = { ...autoMapping, ...mapping };
|
|
2196
|
-
const {
|
|
2197
|
-
titleField,
|
|
2198
|
-
subtitleField,
|
|
2199
|
-
valueField,
|
|
2200
|
-
statusField,
|
|
2201
|
-
metadataFields,
|
|
2202
|
-
iconConfig
|
|
2203
|
-
} = effectiveMapping;
|
|
2204
|
-
const getColumn = (field) => field ? columns.find((c) => c.field === field) : void 0;
|
|
2205
|
-
const title = item[titleField] != null ? String(item[titleField]) : "—";
|
|
2206
|
-
const subtitle = subtitleField && item[subtitleField] != null ? String(item[subtitleField]) : void 0;
|
|
2207
|
-
let value;
|
|
2208
|
-
if (valueField && item[valueField] != null) {
|
|
2209
|
-
const valueCol = getColumn(valueField);
|
|
2210
|
-
const formatted = formatValueForCard(
|
|
2211
|
-
item[valueField],
|
|
2212
|
-
(valueCol == null ? void 0 : valueCol.type) ?? "text",
|
|
2213
|
-
valueCol == null ? void 0 : valueCol.format
|
|
2214
|
-
);
|
|
2215
|
-
value = {
|
|
2216
|
-
text: formatted,
|
|
2217
|
-
variant: "success"
|
|
2218
|
-
// Money typically green
|
|
2219
|
-
};
|
|
2220
|
-
}
|
|
2221
|
-
let badge;
|
|
2222
|
-
if (statusField && item[statusField] != null) {
|
|
2223
|
-
const statusValue = String(item[statusField]);
|
|
2224
|
-
badge = {
|
|
2225
|
-
text: statusValue,
|
|
2226
|
-
variant: "status",
|
|
2227
|
-
status: getStatusColor(statusValue),
|
|
2228
|
-
size: "sm"
|
|
2229
|
-
};
|
|
2230
|
-
}
|
|
2231
|
-
const metadata = metadataFields == null ? void 0 : metadataFields.map((field) => {
|
|
2232
|
-
const col = getColumn(field);
|
|
2233
|
-
if (!col || item[field] == null) return null;
|
|
2234
|
-
return formatValueForCard(item[field], col.type, col.format);
|
|
2235
|
-
}).filter((v) => v !== null);
|
|
2236
|
-
let icon;
|
|
2237
|
-
if (iconConfig) {
|
|
2238
|
-
const iconValue = iconConfig.field ? item[iconConfig.field] : void 0;
|
|
2239
|
-
if (iconConfig.variant === "status" && iconValue) {
|
|
2240
|
-
icon = {
|
|
2241
|
-
icon: iconConfig.icon ?? getIconForEntity(entityType),
|
|
2242
|
-
variant: "status",
|
|
2243
|
-
status: getStatusColor(iconValue),
|
|
2244
|
-
size: "sm"
|
|
2245
|
-
};
|
|
2246
|
-
} else {
|
|
2247
|
-
icon = {
|
|
2248
|
-
icon: iconConfig.icon ?? getIconForEntity(entityType),
|
|
2249
|
-
variant: "category",
|
|
2250
|
-
category: getCategoryForEntity(entityType),
|
|
2251
|
-
size: "sm"
|
|
2252
|
-
};
|
|
2253
|
-
}
|
|
2254
|
-
} else {
|
|
2255
|
-
icon = {
|
|
2256
|
-
icon: getIconForEntity(entityType),
|
|
2257
|
-
variant: "category",
|
|
2258
|
-
category: getCategoryForEntity(entityType),
|
|
2259
|
-
size: "sm"
|
|
2260
|
-
};
|
|
2261
|
-
}
|
|
2262
|
-
return {
|
|
2263
|
-
icon,
|
|
2264
|
-
title,
|
|
2265
|
-
subtitle,
|
|
2266
|
-
metadata,
|
|
2267
|
-
value,
|
|
2268
|
-
badge
|
|
2269
|
-
};
|
|
2270
|
-
}
|
|
2271
|
-
const HEADER_ABBREVIATIONS = {
|
|
2272
|
-
customer: "Cust",
|
|
2273
|
-
account: "Acct",
|
|
2274
|
-
amount: "Amt",
|
|
2275
|
-
quantity: "Qty",
|
|
2276
|
-
priority: "Pri",
|
|
2277
|
-
status: "Status",
|
|
2278
|
-
created: "Created",
|
|
2279
|
-
updated: "Updated",
|
|
2280
|
-
description: "Desc",
|
|
2281
|
-
total: "Total",
|
|
2282
|
-
items: "Items",
|
|
2283
|
-
number: "#",
|
|
2284
|
-
date: "Date",
|
|
2285
|
-
time: "Time"
|
|
2286
|
-
};
|
|
2287
|
-
function abbreviateHeader(label) {
|
|
2288
|
-
const lower = label.toLowerCase();
|
|
2289
|
-
for (const [key, abbrev] of Object.entries(HEADER_ABBREVIATIONS)) {
|
|
2290
|
-
if (lower.includes(key)) return abbrev;
|
|
2291
|
-
}
|
|
2292
|
-
if (label.length > 8) return label.slice(0, 6) + "…";
|
|
2293
|
-
return label;
|
|
2294
|
-
}
|
|
2295
|
-
function generateCompactColumns(columns, options = {}) {
|
|
2296
|
-
const {
|
|
2297
|
-
maxColumns = 5,
|
|
2298
|
-
abbreviateHeaders = true,
|
|
2299
|
-
requiredFields = [],
|
|
2300
|
-
excludeFields = []
|
|
2301
|
-
} = options;
|
|
2302
|
-
const excludeSet = new Set(excludeFields);
|
|
2303
|
-
const requiredSet = new Set(requiredFields);
|
|
2304
|
-
const filteredColumns = columns.filter((col) => {
|
|
2305
|
-
if (excludeSet.has(col.field)) return false;
|
|
2306
|
-
return true;
|
|
2307
|
-
});
|
|
2308
|
-
const required = filteredColumns.filter((c) => requiredSet.has(c.field));
|
|
2309
|
-
const primary = filteredColumns.filter(
|
|
2310
|
-
(c) => !requiredSet.has(c.field) && normalizeImportance(c.importance) === "primary"
|
|
2311
|
-
);
|
|
2312
|
-
const secondary = filteredColumns.filter(
|
|
2313
|
-
(c) => !requiredSet.has(c.field) && normalizeImportance(c.importance) === "secondary"
|
|
2314
|
-
);
|
|
2315
|
-
const selectedColumns = [...required, ...primary, ...secondary].slice(
|
|
2316
|
-
0,
|
|
2317
|
-
maxColumns
|
|
2318
|
-
);
|
|
2319
|
-
return selectedColumns.map((col) => ({
|
|
2320
|
-
key: col.field,
|
|
2321
|
-
header: abbreviateHeaders ? abbreviateHeader(col.label) : col.label,
|
|
2322
|
-
sortable: col.sortable,
|
|
2323
|
-
type: col.type,
|
|
2324
|
-
format: col.format,
|
|
2325
|
-
// Compact widths
|
|
2326
|
-
width: getCompactWidth(col.type)
|
|
2327
|
-
}));
|
|
2328
|
-
}
|
|
2329
|
-
function getCompactWidth(type) {
|
|
2330
|
-
switch (type) {
|
|
2331
|
-
case "money":
|
|
2332
|
-
return "70px";
|
|
2333
|
-
case "number":
|
|
2334
|
-
case "percent":
|
|
2335
|
-
return "50px";
|
|
2336
|
-
case "status":
|
|
2337
|
-
case "badge":
|
|
2338
|
-
return "80px";
|
|
2339
|
-
case "date":
|
|
2340
|
-
return "70px";
|
|
2341
|
-
case "datetime":
|
|
2342
|
-
return "90px";
|
|
2343
|
-
case "boolean":
|
|
2344
|
-
return "50px";
|
|
2345
|
-
default:
|
|
2346
|
-
return "120px";
|
|
2347
|
-
}
|
|
2348
|
-
}
|
|
2349
|
-
function createMobileCardRenderer(columns, mapping, entityType) {
|
|
2350
|
-
const { ListCard: ListCard2 } = require("../components/data/ListCard");
|
|
2351
|
-
return ({ data, onItemClick }) => /* @__PURE__ */ jsx("div", { className: "space-y-2", children: data.map((item, index) => {
|
|
2352
|
-
const cardProps = entityToListCardProps(
|
|
2353
|
-
item,
|
|
2354
|
-
columns,
|
|
2355
|
-
mapping,
|
|
2356
|
-
entityType
|
|
2357
|
-
);
|
|
2358
|
-
return /* @__PURE__ */ jsx(
|
|
2359
|
-
ListCard2,
|
|
2360
|
-
{
|
|
2361
|
-
...cardProps,
|
|
2362
|
-
onClick: onItemClick ? () => onItemClick(item) : void 0
|
|
2363
|
-
},
|
|
2364
|
-
item.id ?? index
|
|
2365
|
-
);
|
|
2366
|
-
}) });
|
|
2367
|
-
}
|
|
2368
2012
|
let globalAuthService = null;
|
|
2369
2013
|
function setGlobalAuthService(authService) {
|
|
2370
2014
|
globalAuthService = authService;
|
|
@@ -17724,17 +17368,14 @@ export {
|
|
|
17724
17368
|
cn,
|
|
17725
17369
|
createAPIDataTemplate,
|
|
17726
17370
|
createApiClient,
|
|
17727
|
-
createMobileCardRenderer,
|
|
17728
17371
|
createReactApp,
|
|
17729
17372
|
createSimpleApp,
|
|
17730
17373
|
defaultFieldRenderers,
|
|
17731
17374
|
detectBulkOperationType,
|
|
17732
17375
|
detectUIConfig,
|
|
17733
|
-
entityToListCardProps,
|
|
17734
17376
|
env,
|
|
17735
17377
|
formatNumberWithTooltip,
|
|
17736
17378
|
generateBulkOperationName,
|
|
17737
|
-
generateCompactColumns,
|
|
17738
17379
|
getAnimationClasses,
|
|
17739
17380
|
getChartHeight,
|
|
17740
17381
|
getContainerHeightClass,
|