@almadar/ui 5.8.1 → 5.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/avl/index.cjs +314 -0
- package/dist/avl/index.js +314 -0
- package/dist/components/atoms/AnimatedGraphic.d.ts +2 -0
- package/dist/components/atoms/AnimatedReveal.d.ts +2 -0
- package/dist/components/atoms/Badge.d.ts +2 -0
- package/dist/components/atoms/Box.d.ts +2 -0
- package/dist/components/atoms/Button.d.ts +2 -0
- package/dist/components/atoms/Card.d.ts +2 -0
- package/dist/components/atoms/Checkbox.d.ts +2 -0
- package/dist/components/atoms/FilterPill.d.ts +2 -0
- package/dist/components/atoms/Input.d.ts +2 -0
- package/dist/components/atoms/Label.d.ts +2 -0
- package/dist/components/atoms/Radio.d.ts +2 -0
- package/dist/components/atoms/RangeSlider.d.ts +2 -0
- package/dist/components/atoms/Select.d.ts +2 -0
- package/dist/components/atoms/Spinner.d.ts +2 -0
- package/dist/components/atoms/StatusDot.d.ts +2 -0
- package/dist/components/atoms/Textarea.d.ts +2 -0
- package/dist/components/atoms/TrendIndicator.d.ts +2 -0
- package/dist/components/index.cjs +318 -2
- package/dist/components/index.js +318 -3
- package/dist/components/molecules/TableView.d.ts +107 -0
- package/dist/components/molecules/index.d.ts +1 -0
- package/dist/docs/index.d.cts +8 -0
- package/dist/marketing/index.d.cts +12 -0
- package/dist/providers/index.cjs +314 -0
- package/dist/providers/index.js +314 -0
- package/dist/runtime/index.cjs +314 -0
- package/dist/runtime/index.js +314 -0
- package/package.json +1 -1
|
@@ -2,6 +2,8 @@ import React from 'react';
|
|
|
2
2
|
export type RevealTrigger = 'scroll' | 'hover' | 'manual';
|
|
3
3
|
export type RevealAnimation = 'fade-up' | 'fade-down' | 'fade-in' | 'fade-left' | 'fade-right' | 'scale' | 'scale-up' | 'none';
|
|
4
4
|
export interface AnimatedRevealProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
5
|
+
/** Additional CSS classes applied to the root element. */
|
|
6
|
+
className?: string;
|
|
5
7
|
/** What triggers the animation */
|
|
6
8
|
trigger?: RevealTrigger;
|
|
7
9
|
/** Built-in animation preset */
|
|
@@ -2,6 +2,8 @@ import React from "react";
|
|
|
2
2
|
export type BadgeVariant = "default" | "primary" | "secondary" | "success" | "warning" | "danger" | "error" | "info" | "neutral";
|
|
3
3
|
export type BadgeSize = "sm" | "md" | "lg";
|
|
4
4
|
export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
5
|
+
/** Additional CSS classes applied to the root element. */
|
|
6
|
+
className?: string;
|
|
5
7
|
variant?: BadgeVariant;
|
|
6
8
|
size?: BadgeSize;
|
|
7
9
|
/** Numeric count or amount to display in badge */
|
|
@@ -12,6 +12,8 @@ export type BoxBg = "transparent" | "primary" | "secondary" | "muted" | "accent"
|
|
|
12
12
|
export type BoxRounded = "none" | "sm" | "md" | "lg" | "xl" | "2xl" | "full";
|
|
13
13
|
export type BoxShadow = "none" | "sm" | "md" | "lg" | "xl";
|
|
14
14
|
export interface BoxProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
15
|
+
/** Additional CSS classes applied to the root element. */
|
|
16
|
+
className?: string;
|
|
15
17
|
/** Padding on all sides */
|
|
16
18
|
padding?: BoxPadding;
|
|
17
19
|
/** Horizontal padding (overrides padding for x-axis) */
|
|
@@ -4,6 +4,8 @@ import { type LucideIcon } from "lucide-react";
|
|
|
4
4
|
export type ButtonVariant = "primary" | "secondary" | "ghost" | "danger" | "success" | "warning" | "default";
|
|
5
5
|
export type ButtonSize = "sm" | "md" | "lg";
|
|
6
6
|
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
7
|
+
/** Additional CSS classes applied to the root element. */
|
|
8
|
+
className?: string;
|
|
7
9
|
variant?: ButtonVariant;
|
|
8
10
|
size?: ButtonSize;
|
|
9
11
|
isLoading?: boolean;
|
|
@@ -6,6 +6,8 @@ export type CardShadow = "none" | "sm" | "md" | "lg";
|
|
|
6
6
|
*/
|
|
7
7
|
export type CardLook = "elevated" | "flat-bordered" | "borderless-divider" | "ticket" | "invoice" | "chip" | "tile-image-first";
|
|
8
8
|
export interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
9
|
+
/** Additional CSS classes applied to the root element. */
|
|
10
|
+
className?: string;
|
|
9
11
|
variant?: "default" | "bordered" | "elevated" | "interactive";
|
|
10
12
|
padding?: "none" | "sm" | "md" | "lg";
|
|
11
13
|
/** Card title - renders in header if provided */
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
export interface CheckboxProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "type"> {
|
|
3
|
+
/** Additional CSS classes applied to the root element. */
|
|
4
|
+
className?: string;
|
|
3
5
|
/** Whether the checkbox is checked */
|
|
4
6
|
checked?: boolean;
|
|
5
7
|
/** Default checked state (uncontrolled) */
|
|
@@ -3,6 +3,8 @@ import type { EventEmit } from "@almadar/core";
|
|
|
3
3
|
export type FilterPillVariant = "default" | "primary" | "secondary" | "success" | "warning" | "danger" | "info" | "neutral";
|
|
4
4
|
export type FilterPillSize = "sm" | "md" | "lg";
|
|
5
5
|
export interface FilterPillProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, "onClick"> {
|
|
6
|
+
/** Additional CSS classes applied to the root element. */
|
|
7
|
+
className?: string;
|
|
6
8
|
variant?: FilterPillVariant;
|
|
7
9
|
size?: FilterPillSize;
|
|
8
10
|
/** Pill label text (alternative to children for schema-driven rendering). */
|
|
@@ -6,6 +6,8 @@ export interface SelectOption {
|
|
|
6
6
|
label: string;
|
|
7
7
|
}
|
|
8
8
|
export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "onChange"> {
|
|
9
|
+
/** Additional CSS classes applied to the root element. */
|
|
10
|
+
className?: string;
|
|
9
11
|
/** Placeholder text */
|
|
10
12
|
placeholder?: string;
|
|
11
13
|
/** Current value */
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
export interface LabelProps extends React.LabelHTMLAttributes<HTMLLabelElement> {
|
|
3
|
+
/** Additional CSS classes applied to the root element. */
|
|
4
|
+
className?: string;
|
|
3
5
|
/** Label text content */
|
|
4
6
|
text?: string;
|
|
5
7
|
/** Associated input element ID */
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
import React from "react";
|
|
7
7
|
import type { EventKey } from "@almadar/core";
|
|
8
8
|
export interface RadioProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "type" | "size"> {
|
|
9
|
+
/** Additional CSS classes applied to the root element. */
|
|
10
|
+
className?: string;
|
|
9
11
|
/** Radio options (string array or SelectOption array) */
|
|
10
12
|
options?: string[];
|
|
11
13
|
/** Current selected value */
|
|
@@ -2,6 +2,8 @@ import React from "react";
|
|
|
2
2
|
import type { EventKey, EventPayload } from "@almadar/core";
|
|
3
3
|
export type RangeSliderSize = "sm" | "md" | "lg";
|
|
4
4
|
export interface RangeSliderProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange"> {
|
|
5
|
+
/** Additional CSS classes applied to the root element. */
|
|
6
|
+
className?: string;
|
|
5
7
|
/** Minimum value */
|
|
6
8
|
min?: number;
|
|
7
9
|
/** Maximum value */
|
|
@@ -6,6 +6,8 @@ export interface SelectOption {
|
|
|
6
6
|
disabled?: boolean;
|
|
7
7
|
}
|
|
8
8
|
export interface SelectProps extends Omit<React.SelectHTMLAttributes<HTMLSelectElement>, "children"> {
|
|
9
|
+
/** Additional CSS classes applied to the root element. */
|
|
10
|
+
className?: string;
|
|
9
11
|
/** Select options */
|
|
10
12
|
options: SelectOption[];
|
|
11
13
|
/** Placeholder text */
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
export type SpinnerSize = "xs" | "sm" | "md" | "lg";
|
|
3
3
|
export interface SpinnerProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
|
+
/** Additional CSS classes applied to the root element. */
|
|
5
|
+
className?: string;
|
|
4
6
|
size?: SpinnerSize;
|
|
5
7
|
}
|
|
6
8
|
export declare const Spinner: React.ForwardRefExoticComponent<SpinnerProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -2,6 +2,8 @@ import React from "react";
|
|
|
2
2
|
export type StatusDotStatus = "online" | "offline" | "away" | "busy" | "warning" | "critical";
|
|
3
3
|
export type StatusDotSize = "sm" | "md" | "lg";
|
|
4
4
|
export interface StatusDotProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
5
|
+
/** Additional CSS classes applied to the root element. */
|
|
6
|
+
className?: string;
|
|
5
7
|
/** Status determines the dot color */
|
|
6
8
|
status?: StatusDotStatus;
|
|
7
9
|
/** Enable pulse animation for active/critical states */
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { EventKey } from "@almadar/core";
|
|
3
3
|
export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
|
|
4
|
+
/** Additional CSS classes applied to the root element. */
|
|
5
|
+
className?: string;
|
|
4
6
|
/** Placeholder text */
|
|
5
7
|
placeholder?: string;
|
|
6
8
|
/** Number of visible rows */
|
|
@@ -2,6 +2,8 @@ import React from "react";
|
|
|
2
2
|
export type TrendDirection = "up" | "down" | "flat";
|
|
3
3
|
export type TrendIndicatorSize = "sm" | "md" | "lg";
|
|
4
4
|
export interface TrendIndicatorProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
5
|
+
/** Additional CSS classes applied to the root element. */
|
|
6
|
+
className?: string;
|
|
5
7
|
/** Numeric value to display (e.g., 12.5 for +12.5%) */
|
|
6
8
|
value?: number;
|
|
7
9
|
/** Override automatic direction detection (positive=up, negative=down, zero=flat) */
|
|
@@ -28283,6 +28283,318 @@ var init_Lightbox = __esm({
|
|
|
28283
28283
|
exports.Lightbox.displayName = "Lightbox";
|
|
28284
28284
|
}
|
|
28285
28285
|
});
|
|
28286
|
+
function columnLabel(col) {
|
|
28287
|
+
return col.header ?? col.label ?? col.key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
28288
|
+
}
|
|
28289
|
+
function statusVariant4(value) {
|
|
28290
|
+
const v = value.toLowerCase();
|
|
28291
|
+
if (["active", "completed", "done", "approved", "published", "resolved", "open", "online", "ok"].includes(v)) return "success";
|
|
28292
|
+
if (["pending", "in_progress", "in-progress", "review", "draft", "processing", "warn", "warning"].includes(v)) return "warning";
|
|
28293
|
+
if (["inactive", "deleted", "rejected", "failed", "error", "blocked", "closed", "offline"].includes(v)) return "error";
|
|
28294
|
+
if (["new", "created", "scheduled", "queued", "info"].includes(v)) return "info";
|
|
28295
|
+
return "default";
|
|
28296
|
+
}
|
|
28297
|
+
function formatCell(value, format) {
|
|
28298
|
+
if (value === void 0 || value === null) return "";
|
|
28299
|
+
switch (format) {
|
|
28300
|
+
case "date": {
|
|
28301
|
+
const d = new Date(String(value));
|
|
28302
|
+
return isNaN(d.getTime()) ? String(value) : d.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
28303
|
+
}
|
|
28304
|
+
case "currency":
|
|
28305
|
+
return typeof value === "number" ? `$${value.toFixed(2)}` : String(value);
|
|
28306
|
+
case "number":
|
|
28307
|
+
return typeof value === "number" ? value.toLocaleString() : String(value);
|
|
28308
|
+
case "percent":
|
|
28309
|
+
return typeof value === "number" ? `${Math.round(value)}%` : String(value);
|
|
28310
|
+
case "boolean":
|
|
28311
|
+
return value ? "Yes" : "No";
|
|
28312
|
+
default:
|
|
28313
|
+
return String(value);
|
|
28314
|
+
}
|
|
28315
|
+
}
|
|
28316
|
+
function groupData2(items, field) {
|
|
28317
|
+
const groups = /* @__PURE__ */ new Map();
|
|
28318
|
+
for (const item of items) {
|
|
28319
|
+
const key = String(getNestedValue(item, field) ?? "");
|
|
28320
|
+
const group = groups.get(key);
|
|
28321
|
+
if (group) group.push(item);
|
|
28322
|
+
else groups.set(key, [item]);
|
|
28323
|
+
}
|
|
28324
|
+
return Array.from(groups.entries()).map(([label, groupItems]) => ({ label, items: groupItems }));
|
|
28325
|
+
}
|
|
28326
|
+
function TableView({
|
|
28327
|
+
entity,
|
|
28328
|
+
columns,
|
|
28329
|
+
fields,
|
|
28330
|
+
itemActions,
|
|
28331
|
+
selectable = false,
|
|
28332
|
+
selectEvent,
|
|
28333
|
+
selectedIds,
|
|
28334
|
+
sortEvent,
|
|
28335
|
+
sortColumn,
|
|
28336
|
+
sortDirection,
|
|
28337
|
+
className,
|
|
28338
|
+
emptyMessage,
|
|
28339
|
+
isLoading = false,
|
|
28340
|
+
error = null,
|
|
28341
|
+
groupBy,
|
|
28342
|
+
pageSize = 0,
|
|
28343
|
+
children,
|
|
28344
|
+
renderItem: _schemaRenderItem,
|
|
28345
|
+
look = "dense",
|
|
28346
|
+
// DnD props consumed by useDataDnd.
|
|
28347
|
+
dragGroup,
|
|
28348
|
+
accepts,
|
|
28349
|
+
sortable,
|
|
28350
|
+
dropEvent,
|
|
28351
|
+
reorderEvent,
|
|
28352
|
+
positionEvent,
|
|
28353
|
+
dndItemIdField,
|
|
28354
|
+
dndRoot
|
|
28355
|
+
}) {
|
|
28356
|
+
const eventBus = useEventBus();
|
|
28357
|
+
const { t } = useTranslate();
|
|
28358
|
+
const [visibleCount, setVisibleCount] = React80__namespace.default.useState(pageSize > 0 ? pageSize : Infinity);
|
|
28359
|
+
const [localSelected, setLocalSelected] = React80__namespace.default.useState(/* @__PURE__ */ new Set());
|
|
28360
|
+
const colDefs = columns ?? fields ?? [];
|
|
28361
|
+
const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
|
|
28362
|
+
const dnd = useDataDnd({
|
|
28363
|
+
items: allDataRaw,
|
|
28364
|
+
layout: "list",
|
|
28365
|
+
dragGroup,
|
|
28366
|
+
accepts,
|
|
28367
|
+
sortable,
|
|
28368
|
+
dropEvent,
|
|
28369
|
+
reorderEvent,
|
|
28370
|
+
positionEvent,
|
|
28371
|
+
dndItemIdField,
|
|
28372
|
+
dndRoot
|
|
28373
|
+
});
|
|
28374
|
+
const ordered = dnd.orderedItems;
|
|
28375
|
+
const data = pageSize > 0 ? ordered.slice(0, visibleCount) : ordered;
|
|
28376
|
+
const hasMore = pageSize > 0 && visibleCount < ordered.length;
|
|
28377
|
+
const hasRenderProp = typeof children === "function";
|
|
28378
|
+
const idField = dndItemIdField ?? "id";
|
|
28379
|
+
const selected = selectedIds ? new Set(selectedIds) : localSelected;
|
|
28380
|
+
const emitSelection = (next) => {
|
|
28381
|
+
if (!selectedIds) setLocalSelected(next);
|
|
28382
|
+
if (selectEvent) {
|
|
28383
|
+
const payload = { selectedIds: Array.from(next) };
|
|
28384
|
+
eventBus.emit(`UI:${selectEvent}`, payload);
|
|
28385
|
+
}
|
|
28386
|
+
};
|
|
28387
|
+
const allSelected = selectable && data.length > 0 && data.every((r, i) => selected.has(String(r[idField] ?? i)));
|
|
28388
|
+
const toggleAll = () => {
|
|
28389
|
+
if (allSelected) emitSelection(/* @__PURE__ */ new Set());
|
|
28390
|
+
else emitSelection(new Set(data.map((r, i) => String(r[idField] ?? i))));
|
|
28391
|
+
};
|
|
28392
|
+
const toggleRow = (id) => {
|
|
28393
|
+
const next = new Set(selected);
|
|
28394
|
+
if (next.has(id)) next.delete(id);
|
|
28395
|
+
else next.add(id);
|
|
28396
|
+
emitSelection(next);
|
|
28397
|
+
};
|
|
28398
|
+
const handleSort = (col) => {
|
|
28399
|
+
if (!col.sortable || !sortEvent) return;
|
|
28400
|
+
const dir = sortColumn === (col.field ?? col.key) && sortDirection === "asc" ? "desc" : "asc";
|
|
28401
|
+
eventBus.emit(`UI:${sortEvent}`, { column: col.field ?? col.key, direction: dir });
|
|
28402
|
+
};
|
|
28403
|
+
const handleActionClick = (action, row) => (e) => {
|
|
28404
|
+
e.stopPropagation();
|
|
28405
|
+
const payload = {
|
|
28406
|
+
id: row.id,
|
|
28407
|
+
row
|
|
28408
|
+
};
|
|
28409
|
+
eventBus.emit(`UI:${action.event}`, payload);
|
|
28410
|
+
};
|
|
28411
|
+
if (isLoading) {
|
|
28412
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "text-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", color: "secondary", children: t("loading.items") || "Loading\u2026" }) });
|
|
28413
|
+
}
|
|
28414
|
+
if (error) {
|
|
28415
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "text-center py-8", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", color: "error", children: error.message }) });
|
|
28416
|
+
}
|
|
28417
|
+
if (data.length === 0) {
|
|
28418
|
+
const emptyNode = /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "text-center py-12", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Typography, { variant: "body", color: "secondary", children: emptyMessage || t("empty.noItems") || "No records" }) });
|
|
28419
|
+
return dnd.enabled ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: dnd.wrapContainer(emptyNode) }) : emptyNode;
|
|
28420
|
+
}
|
|
28421
|
+
const lk = LOOKS[look];
|
|
28422
|
+
const hasActions = Boolean(itemActions && itemActions.length > 0);
|
|
28423
|
+
const gridTemplateColumns = [
|
|
28424
|
+
selectable ? "auto" : null,
|
|
28425
|
+
...colDefs.map((c) => c.width ?? "minmax(0, 1fr)"),
|
|
28426
|
+
hasActions ? "auto" : null
|
|
28427
|
+
].filter(Boolean).join(" ");
|
|
28428
|
+
const header = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
28429
|
+
exports.Box,
|
|
28430
|
+
{
|
|
28431
|
+
role: "row",
|
|
28432
|
+
style: { gridTemplateColumns },
|
|
28433
|
+
className: cn(
|
|
28434
|
+
"grid items-center gap-3 sticky top-0 z-10",
|
|
28435
|
+
"bg-[var(--color-surface-subtle)] border-b border-[var(--color-border)]",
|
|
28436
|
+
"text-[var(--color-text-muted)] uppercase text-xs font-semibold tracking-wide",
|
|
28437
|
+
lk.headPad
|
|
28438
|
+
),
|
|
28439
|
+
children: [
|
|
28440
|
+
selectable && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(exports.Checkbox, { checked: allSelected, onChange: toggleAll, "aria-label": "Select all rows" }) }),
|
|
28441
|
+
colDefs.map((col) => {
|
|
28442
|
+
const active = sortColumn === (col.field ?? col.key);
|
|
28443
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
28444
|
+
exports.Box,
|
|
28445
|
+
{
|
|
28446
|
+
role: "columnheader",
|
|
28447
|
+
onClick: () => handleSort(col),
|
|
28448
|
+
className: cn(
|
|
28449
|
+
"flex items-center gap-1 min-w-0",
|
|
28450
|
+
alignClass[col.align ?? "left"],
|
|
28451
|
+
col.sortable && sortEvent && "cursor-pointer select-none hover:text-foreground"
|
|
28452
|
+
),
|
|
28453
|
+
children: [
|
|
28454
|
+
col.icon && /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: col.icon, size: "xs" }),
|
|
28455
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: columnLabel(col) }),
|
|
28456
|
+
col.sortable && sortEvent && /* @__PURE__ */ jsxRuntime.jsx(
|
|
28457
|
+
exports.Icon,
|
|
28458
|
+
{
|
|
28459
|
+
name: active ? sortDirection === "asc" ? "chevron-up" : "chevron-down" : "chevrons-up-down",
|
|
28460
|
+
size: "xs",
|
|
28461
|
+
className: cn("flex-shrink-0", active ? "text-foreground" : "opacity-40")
|
|
28462
|
+
}
|
|
28463
|
+
)
|
|
28464
|
+
]
|
|
28465
|
+
},
|
|
28466
|
+
col.key
|
|
28467
|
+
);
|
|
28468
|
+
}),
|
|
28469
|
+
hasActions && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { "aria-hidden": true })
|
|
28470
|
+
]
|
|
28471
|
+
}
|
|
28472
|
+
);
|
|
28473
|
+
const renderRow = (row, index) => {
|
|
28474
|
+
const id = String(row[idField] ?? index);
|
|
28475
|
+
const rowInner = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
28476
|
+
exports.Box,
|
|
28477
|
+
{
|
|
28478
|
+
role: "row",
|
|
28479
|
+
"data-entity-row": true,
|
|
28480
|
+
"data-entity-id": id,
|
|
28481
|
+
style: !hasRenderProp ? { gridTemplateColumns } : void 0,
|
|
28482
|
+
className: cn(
|
|
28483
|
+
"group items-center gap-3 transition-colors duration-fast",
|
|
28484
|
+
hasRenderProp ? "flex" : "grid",
|
|
28485
|
+
lk.rowPad,
|
|
28486
|
+
lk.divider && "border-b border-[var(--color-border)]",
|
|
28487
|
+
lk.striped && index % 2 === 1 && "bg-[var(--color-surface-subtle)]",
|
|
28488
|
+
"hover:bg-[var(--color-surface-subtle)]",
|
|
28489
|
+
look === "bordered" && "[&>*]:border-r [&>*]:border-[var(--color-border)] [&>*:last-child]:border-r-0"
|
|
28490
|
+
),
|
|
28491
|
+
children: [
|
|
28492
|
+
selectable && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
28493
|
+
exports.Checkbox,
|
|
28494
|
+
{
|
|
28495
|
+
checked: selected.has(id),
|
|
28496
|
+
onChange: () => toggleRow(id),
|
|
28497
|
+
"aria-label": `Select row ${id}`
|
|
28498
|
+
}
|
|
28499
|
+
) }),
|
|
28500
|
+
hasRenderProp ? /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "flex-1 min-w-0", children: children(row, index) }) : colDefs.map((col) => {
|
|
28501
|
+
const raw = getNestedValue(row, col.field ?? col.key);
|
|
28502
|
+
const cellBase = cn(
|
|
28503
|
+
"flex items-center min-w-0",
|
|
28504
|
+
alignClass[col.align ?? "left"],
|
|
28505
|
+
weightClass[col.weight ?? "normal"],
|
|
28506
|
+
col.className
|
|
28507
|
+
);
|
|
28508
|
+
if (col.format === "badge" && raw != null && raw !== "") {
|
|
28509
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx(exports.Badge, { variant: statusVariant4(String(raw)), size: "sm", children: String(raw) }) }, col.key);
|
|
28510
|
+
}
|
|
28511
|
+
return /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: formatCell(raw, col.format) }) }, col.key);
|
|
28512
|
+
}),
|
|
28513
|
+
itemActions && itemActions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(exports.HStack, { gap: "xs", className: "flex-shrink-0 opacity-60 group-hover:opacity-100 transition-opacity", children: itemActions.map((action, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
28514
|
+
exports.Button,
|
|
28515
|
+
{
|
|
28516
|
+
variant: action.variant ?? "ghost",
|
|
28517
|
+
size: "sm",
|
|
28518
|
+
onClick: handleActionClick(action, row),
|
|
28519
|
+
"data-testid": `action-${action.event}`,
|
|
28520
|
+
"data-row-id": String(row.id),
|
|
28521
|
+
className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
|
|
28522
|
+
children: [
|
|
28523
|
+
action.icon && /* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: action.icon, size: "xs", className: "mr-1" }),
|
|
28524
|
+
action.label
|
|
28525
|
+
]
|
|
28526
|
+
},
|
|
28527
|
+
i
|
|
28528
|
+
)) })
|
|
28529
|
+
]
|
|
28530
|
+
}
|
|
28531
|
+
);
|
|
28532
|
+
return dnd.isZone ? /* @__PURE__ */ jsxRuntime.jsx(dnd.SortableItem, { id: row[idField] ?? id, children: rowInner }, id) : /* @__PURE__ */ jsxRuntime.jsx(React80__namespace.default.Fragment, { children: rowInner }, id);
|
|
28533
|
+
};
|
|
28534
|
+
const items = data.map((row) => row);
|
|
28535
|
+
const groups = groupBy ? groupData2(items, groupBy) : [{ label: "", items }];
|
|
28536
|
+
let runningIndex = 0;
|
|
28537
|
+
const body = /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { role: "rowgroup", children: groups.map((group, gi) => /* @__PURE__ */ jsxRuntime.jsxs(React80__namespace.default.Fragment, { children: [
|
|
28538
|
+
group.label && /* @__PURE__ */ jsxRuntime.jsx(exports.Divider, { label: group.label, className: gi > 0 ? "mt-3" : "mt-0" }),
|
|
28539
|
+
group.items.map((row) => renderRow(row, runningIndex++))
|
|
28540
|
+
] }, gi)) });
|
|
28541
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
28542
|
+
exports.Box,
|
|
28543
|
+
{
|
|
28544
|
+
role: "table",
|
|
28545
|
+
className: cn("w-full text-sm", className),
|
|
28546
|
+
children: [
|
|
28547
|
+
header,
|
|
28548
|
+
dnd.wrapContainer(body),
|
|
28549
|
+
hasMore && /* @__PURE__ */ jsxRuntime.jsx(exports.Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxRuntime.jsxs(exports.Button, { variant: "ghost", size: "sm", onClick: () => setVisibleCount((p2) => p2 + (pageSize || 5)), children: [
|
|
28550
|
+
/* @__PURE__ */ jsxRuntime.jsx(exports.Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
|
|
28551
|
+
t("common.showMore"),
|
|
28552
|
+
" (",
|
|
28553
|
+
ordered.length - visibleCount,
|
|
28554
|
+
" remaining)"
|
|
28555
|
+
] }) })
|
|
28556
|
+
]
|
|
28557
|
+
}
|
|
28558
|
+
);
|
|
28559
|
+
}
|
|
28560
|
+
var alignClass, weightClass, LOOKS;
|
|
28561
|
+
var init_TableView = __esm({
|
|
28562
|
+
"components/molecules/TableView.tsx"() {
|
|
28563
|
+
"use client";
|
|
28564
|
+
init_cn();
|
|
28565
|
+
init_getNestedValue();
|
|
28566
|
+
init_useEventBus();
|
|
28567
|
+
init_useTranslate();
|
|
28568
|
+
init_Box();
|
|
28569
|
+
init_Stack();
|
|
28570
|
+
init_Typography();
|
|
28571
|
+
init_Badge();
|
|
28572
|
+
init_Button();
|
|
28573
|
+
init_Icon();
|
|
28574
|
+
init_Checkbox();
|
|
28575
|
+
init_Divider();
|
|
28576
|
+
init_useDataDnd();
|
|
28577
|
+
logger.createLogger("almadar:ui:table-view");
|
|
28578
|
+
alignClass = {
|
|
28579
|
+
left: "justify-start text-left",
|
|
28580
|
+
center: "justify-center text-center",
|
|
28581
|
+
right: "justify-end text-right"
|
|
28582
|
+
};
|
|
28583
|
+
weightClass = {
|
|
28584
|
+
normal: "",
|
|
28585
|
+
medium: "font-medium",
|
|
28586
|
+
semibold: "font-semibold"
|
|
28587
|
+
};
|
|
28588
|
+
LOOKS = {
|
|
28589
|
+
dense: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: false, divider: true },
|
|
28590
|
+
spacious: { rowPad: "px-5 py-4", headPad: "px-5 py-3", striped: false, divider: true },
|
|
28591
|
+
striped: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: true, divider: false },
|
|
28592
|
+
borderless: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: false, divider: false },
|
|
28593
|
+
bordered: { rowPad: "px-3 py-2", headPad: "px-3 py-2", striped: false, divider: true }
|
|
28594
|
+
};
|
|
28595
|
+
TableView.displayName = "TableView";
|
|
28596
|
+
}
|
|
28597
|
+
});
|
|
28286
28598
|
function formatNumber(value, format) {
|
|
28287
28599
|
if (value == null) return "0";
|
|
28288
28600
|
const v = typeof value === "number" ? value : value;
|
|
@@ -33973,6 +34285,7 @@ var init_molecules = __esm({
|
|
|
33973
34285
|
init_Lightbox();
|
|
33974
34286
|
init_DataGrid();
|
|
33975
34287
|
init_DataList();
|
|
34288
|
+
init_TableView();
|
|
33976
34289
|
init_StatDisplay();
|
|
33977
34290
|
init_Meter();
|
|
33978
34291
|
init_SwipeableRow();
|
|
@@ -45974,6 +46287,7 @@ var init_component_registry_generated = __esm({
|
|
|
45974
46287
|
init_Switch();
|
|
45975
46288
|
init_TabbedContainer();
|
|
45976
46289
|
init_Table();
|
|
46290
|
+
init_TableView();
|
|
45977
46291
|
init_Tabs();
|
|
45978
46292
|
init_TagCloud();
|
|
45979
46293
|
init_TagInput();
|
|
@@ -46291,6 +46605,7 @@ var init_component_registry_generated = __esm({
|
|
|
46291
46605
|
"Switch": exports.Switch,
|
|
46292
46606
|
"TabbedContainer": exports.TabbedContainer,
|
|
46293
46607
|
"Table": exports.Table,
|
|
46608
|
+
"TableView": TableView,
|
|
46294
46609
|
"Tabs": exports.Tabs,
|
|
46295
46610
|
"TagCloud": exports.TagCloud,
|
|
46296
46611
|
"TagInput": exports.TagInput,
|
|
@@ -47407,7 +47722,7 @@ var FormActions = ({
|
|
|
47407
47722
|
align = "right",
|
|
47408
47723
|
className
|
|
47409
47724
|
}) => {
|
|
47410
|
-
const
|
|
47725
|
+
const alignClass2 = {
|
|
47411
47726
|
left: "justify-start",
|
|
47412
47727
|
right: "justify-end",
|
|
47413
47728
|
between: "justify-between",
|
|
@@ -47420,7 +47735,7 @@ var FormActions = ({
|
|
|
47420
47735
|
align: "center",
|
|
47421
47736
|
className: cn(
|
|
47422
47737
|
"pt-6 border-t border-border",
|
|
47423
|
-
|
|
47738
|
+
alignClass2,
|
|
47424
47739
|
sticky && "sticky bottom-0 bg-card py-4 -mx-6 px-6 shadow-[0_-4px_6px_-1px_rgb(0,0,0,0.05)]",
|
|
47425
47740
|
className
|
|
47426
47741
|
),
|
|
@@ -50297,6 +50612,7 @@ exports.StateNode = StateNode2;
|
|
|
50297
50612
|
exports.StatusBar = StatusBar;
|
|
50298
50613
|
exports.StatusEffect = StatusEffect;
|
|
50299
50614
|
exports.TERRAIN_COLORS = TERRAIN_COLORS;
|
|
50615
|
+
exports.TableView = TableView;
|
|
50300
50616
|
exports.TerrainPalette = TerrainPalette;
|
|
50301
50617
|
exports.TimeSlotCell = TimeSlotCell;
|
|
50302
50618
|
exports.TimerDisplay = TimerDisplay;
|