@morze/ui 0.1.0 → 0.2.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/README.md +112 -10
- package/dist/index.cjs +114 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +78 -63
- package/dist/index.d.ts +78 -63
- package/dist/index.js +114 -34
- package/dist/index.js.map +1 -1
- package/dist/locales/en.cjs +73 -0
- package/dist/locales/en.cjs.map +1 -0
- package/dist/locales/en.d.cts +7 -0
- package/dist/locales/en.d.ts +7 -0
- package/dist/locales/en.js +66 -0
- package/dist/locales/en.js.map +1 -0
- package/dist/locales/ru.cjs +70 -0
- package/dist/locales/ru.cjs.map +1 -0
- package/dist/locales/ru.d.cts +16 -0
- package/dist/locales/ru.d.ts +16 -0
- package/dist/locales/ru.js +63 -0
- package/dist/locales/ru.js.map +1 -0
- package/dist/morze-ui-tokens.css +1 -1
- package/dist/morze-ui.css +1 -1
- package/dist/types-B8jz2FF9.d.cts +75 -0
- package/dist/types-B8jz2FF9.d.ts +75 -0
- package/package.json +13 -2
package/dist/index.js
CHANGED
|
@@ -217,7 +217,6 @@ function Button({
|
|
|
217
217
|
asChild = false,
|
|
218
218
|
tone,
|
|
219
219
|
loading = false,
|
|
220
|
-
dot = false,
|
|
221
220
|
disabled,
|
|
222
221
|
children,
|
|
223
222
|
...props
|
|
@@ -225,7 +224,6 @@ function Button({
|
|
|
225
224
|
const Comp = asChild ? Slot.Root : "button";
|
|
226
225
|
const isDisabled = disabled || loading;
|
|
227
226
|
const decorate = (label) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
228
|
-
dot ? /* @__PURE__ */ jsx("span", { className: "mz-btn__dot", "aria-hidden": "true" }) : null,
|
|
229
227
|
label,
|
|
230
228
|
loading ? /* @__PURE__ */ jsx("span", { className: "mz-btn__spinner", "aria-hidden": "true", children: /* @__PURE__ */ jsx(SpinnerIcon, {}) }) : null
|
|
231
229
|
] });
|
|
@@ -269,7 +267,6 @@ function Badge({
|
|
|
269
267
|
className,
|
|
270
268
|
variant = "solid",
|
|
271
269
|
tone,
|
|
272
|
-
dot = false,
|
|
273
270
|
asChild = false,
|
|
274
271
|
children,
|
|
275
272
|
...props
|
|
@@ -283,10 +280,7 @@ function Badge({
|
|
|
283
280
|
"data-tone": tone,
|
|
284
281
|
className: cn(badgeVariants({ variant }), className),
|
|
285
282
|
...props,
|
|
286
|
-
children
|
|
287
|
-
dot ? /* @__PURE__ */ jsx("span", { className: "mz-badge__dot", "aria-hidden": "true" }) : null,
|
|
288
|
-
children
|
|
289
|
-
] })
|
|
283
|
+
children
|
|
290
284
|
}
|
|
291
285
|
);
|
|
292
286
|
}
|
|
@@ -1824,6 +1818,8 @@ var defaultDataTableLabels = {
|
|
|
1824
1818
|
previousPage: "Previous page",
|
|
1825
1819
|
nextPage: "Next page",
|
|
1826
1820
|
lastPage: "Last page",
|
|
1821
|
+
loadMore: "Load more",
|
|
1822
|
+
loadingMore: "Loading\u2026",
|
|
1827
1823
|
selectedCount: (count) => `Selected: ${count}`,
|
|
1828
1824
|
allMatchingSuffix: " (all matching)",
|
|
1829
1825
|
selectAllMatching: (total) => `Select all ${total}`,
|
|
@@ -1848,6 +1844,8 @@ function isFilterActive(value) {
|
|
|
1848
1844
|
return Boolean(value.from || value.to);
|
|
1849
1845
|
case "boolean":
|
|
1850
1846
|
return true;
|
|
1847
|
+
case "custom":
|
|
1848
|
+
return !(value.value === void 0 || value.value === null || value.value === "" || Array.isArray(value.value) && value.value.length === 0);
|
|
1851
1849
|
}
|
|
1852
1850
|
}
|
|
1853
1851
|
function activeFilters(filters) {
|
|
@@ -1918,10 +1916,11 @@ function ColumnFilter({ columnLabel, def, value, onApply, labels: labelsProp })
|
|
|
1918
1916
|
draft,
|
|
1919
1917
|
setDraft,
|
|
1920
1918
|
labels,
|
|
1921
|
-
onSubmit: () => commit(draft)
|
|
1919
|
+
onSubmit: () => commit(draft),
|
|
1920
|
+
onCommit: commit
|
|
1922
1921
|
}
|
|
1923
1922
|
),
|
|
1924
|
-
/* @__PURE__ */ jsxs("div", { className: "mz-dt__filter-actions", children: [
|
|
1923
|
+
def.type === "custom" && def.actions === false ? null : /* @__PURE__ */ jsxs("div", { className: "mz-dt__filter-actions", children: [
|
|
1925
1924
|
/* @__PURE__ */ jsx(Button, { size: "sm", variant: "ghost", onClick: () => commit(void 0), children: labels.reset }),
|
|
1926
1925
|
/* @__PURE__ */ jsx(Button, { size: "sm", onClick: () => commit(draft), children: labels.apply })
|
|
1927
1926
|
] })
|
|
@@ -1933,7 +1932,8 @@ function FilterBody({
|
|
|
1933
1932
|
draft,
|
|
1934
1933
|
setDraft,
|
|
1935
1934
|
labels,
|
|
1936
|
-
onSubmit
|
|
1935
|
+
onSubmit,
|
|
1936
|
+
onCommit
|
|
1937
1937
|
}) {
|
|
1938
1938
|
const submitOnEnter = (event) => {
|
|
1939
1939
|
if (event.key === "Enter") {
|
|
@@ -2041,6 +2041,17 @@ function FilterBody({
|
|
|
2041
2041
|
)
|
|
2042
2042
|
] });
|
|
2043
2043
|
}
|
|
2044
|
+
if (def.type === "custom") {
|
|
2045
|
+
const staged = draft?.type === "custom" ? draft : void 0;
|
|
2046
|
+
const wrap = (value, label) => value === void 0 ? void 0 : { type: "custom", value, label };
|
|
2047
|
+
return /* @__PURE__ */ jsx(Fragment, { children: def.render({
|
|
2048
|
+
value: staged?.value,
|
|
2049
|
+
label: staged?.label,
|
|
2050
|
+
onChange: (value, label) => setDraft(wrap(value, label)),
|
|
2051
|
+
commit: (value, label) => onCommit(wrap(value, label)),
|
|
2052
|
+
labels
|
|
2053
|
+
}) });
|
|
2054
|
+
}
|
|
2044
2055
|
const current = draft?.type === "boolean" ? draft.value : void 0;
|
|
2045
2056
|
return /* @__PURE__ */ jsx("div", { className: "mz-dt__filter-options", role: "radiogroup", children: [
|
|
2046
2057
|
{ value: true, label: def.trueLabel ?? labels.yes },
|
|
@@ -2183,6 +2194,7 @@ function DataTablePagination({
|
|
|
2183
2194
|
onQueryChange
|
|
2184
2195
|
}) {
|
|
2185
2196
|
const labels = resolveLabels(labelsProp);
|
|
2197
|
+
const sizes = pageSizeOptions === false ? [] : pageSizeOptions;
|
|
2186
2198
|
const pages = pageCount(total, query.pageSize);
|
|
2187
2199
|
const from = total === 0 ? 0 : (query.page - 1) * query.pageSize + 1;
|
|
2188
2200
|
const to = total === void 0 ? from + rowsOnPage - 1 : Math.min(query.page * query.pageSize, total);
|
|
@@ -2199,7 +2211,7 @@ function DataTablePagination({
|
|
|
2199
2211
|
total.toLocaleString(locale)
|
|
2200
2212
|
] }) : null
|
|
2201
2213
|
] }) }),
|
|
2202
|
-
/* @__PURE__ */ jsxs("div", { className: "mz-dt__pagination-size", children: [
|
|
2214
|
+
sizes.length > 1 ? /* @__PURE__ */ jsxs("div", { className: "mz-dt__pagination-size", children: [
|
|
2203
2215
|
/* @__PURE__ */ jsx("span", { children: labels.rowsPerPage }),
|
|
2204
2216
|
/* @__PURE__ */ jsxs(
|
|
2205
2217
|
Select,
|
|
@@ -2208,11 +2220,11 @@ function DataTablePagination({
|
|
|
2208
2220
|
onValueChange: (value) => onQueryChange({ ...query, pageSize: Number(value), page: 1 }),
|
|
2209
2221
|
children: [
|
|
2210
2222
|
/* @__PURE__ */ jsx(SelectTrigger, { size: "sm", className: "mz-dt__pagination-select", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
2211
|
-
/* @__PURE__ */ jsx(SelectContent, { children:
|
|
2223
|
+
/* @__PURE__ */ jsx(SelectContent, { children: sizes.map((size) => /* @__PURE__ */ jsx(SelectItem, { value: String(size), children: size }, size)) })
|
|
2212
2224
|
]
|
|
2213
2225
|
}
|
|
2214
2226
|
)
|
|
2215
|
-
] }),
|
|
2227
|
+
] }) : null,
|
|
2216
2228
|
/* @__PURE__ */ jsxs("div", { className: "mz-dt__pagination-nav", children: [
|
|
2217
2229
|
/* @__PURE__ */ jsxs("span", { className: "mz-dt__pagination-page", children: [
|
|
2218
2230
|
query.page,
|
|
@@ -2386,20 +2398,27 @@ function useColumnLayout({
|
|
|
2386
2398
|
() => controlled ? merge(baseline, controlled, baseline) : internal,
|
|
2387
2399
|
[controlled, internal, baseline]
|
|
2388
2400
|
);
|
|
2401
|
+
const onLayoutChangeRef = React39.useRef(onLayoutChange);
|
|
2402
|
+
React39.useEffect(() => {
|
|
2403
|
+
onLayoutChangeRef.current = onLayoutChange;
|
|
2404
|
+
});
|
|
2405
|
+
const internalRef = React39.useRef(internal);
|
|
2406
|
+
React39.useEffect(() => {
|
|
2407
|
+
internalRef.current = internal;
|
|
2408
|
+
}, [internal]);
|
|
2389
2409
|
const update = React39.useCallback(
|
|
2390
2410
|
(patch, options) => {
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
});
|
|
2411
|
+
const base = controlled ? merge(baseline, controlled, baseline) : internalRef.current;
|
|
2412
|
+
const next = patch(base);
|
|
2413
|
+
if (next === base) return;
|
|
2414
|
+
internalRef.current = next;
|
|
2415
|
+
setInternal(next);
|
|
2416
|
+
if (options?.persist !== false) {
|
|
2417
|
+
writeStored2(persistKey, next);
|
|
2418
|
+
onLayoutChangeRef.current?.(next);
|
|
2419
|
+
}
|
|
2401
2420
|
},
|
|
2402
|
-
[controlled, baseline, persistKey
|
|
2421
|
+
[controlled, baseline, persistKey]
|
|
2403
2422
|
);
|
|
2404
2423
|
const byId = React39.useMemo(
|
|
2405
2424
|
() => new Map(columns.map((c) => [c.id, c])),
|
|
@@ -2583,6 +2602,7 @@ function useRowSelection(options) {
|
|
|
2583
2602
|
}
|
|
2584
2603
|
var SELECT_WIDTH = 44;
|
|
2585
2604
|
var EXPAND_WIDTH = 40;
|
|
2605
|
+
var FIT_CYCLE_MS = 250;
|
|
2586
2606
|
function DataTable({
|
|
2587
2607
|
columns,
|
|
2588
2608
|
data,
|
|
@@ -2598,6 +2618,8 @@ function DataTable({
|
|
|
2598
2618
|
bulkActions,
|
|
2599
2619
|
renderExpanded,
|
|
2600
2620
|
onRowClick,
|
|
2621
|
+
rowClassName,
|
|
2622
|
+
rowProps,
|
|
2601
2623
|
layout: controlledLayout,
|
|
2602
2624
|
onLayoutChange,
|
|
2603
2625
|
persistKey = null,
|
|
@@ -2607,6 +2629,10 @@ function DataTable({
|
|
|
2607
2629
|
stickyHeader = true,
|
|
2608
2630
|
emptyState,
|
|
2609
2631
|
pageSizeOptions,
|
|
2632
|
+
pagination,
|
|
2633
|
+
onLoadMore,
|
|
2634
|
+
hasMore,
|
|
2635
|
+
autoLoadMore = true,
|
|
2610
2636
|
labels: labelsProp,
|
|
2611
2637
|
locale,
|
|
2612
2638
|
caption,
|
|
@@ -2640,28 +2666,38 @@ function DataTable({
|
|
|
2640
2666
|
}),
|
|
2641
2667
|
pageKeys
|
|
2642
2668
|
});
|
|
2643
|
-
const
|
|
2669
|
+
const recentFits = React39.useRef([]);
|
|
2670
|
+
const hiddenKey = layout.hidden.join("\0");
|
|
2671
|
+
const orderKey = layout.order.join("\0");
|
|
2644
2672
|
React39.useEffect(() => {
|
|
2645
2673
|
const scroller = scrollerRef.current;
|
|
2646
2674
|
if (!scroller || !autoFit) return;
|
|
2647
2675
|
const controls = (selectable ? SELECT_WIDTH : 0) + (renderExpanded ? EXPAND_WIDTH : 0);
|
|
2676
|
+
recentFits.current = [];
|
|
2648
2677
|
const run = () => {
|
|
2649
2678
|
const available = scroller.clientWidth - controls - 2;
|
|
2650
|
-
|
|
2651
|
-
|
|
2679
|
+
const now = Date.now();
|
|
2680
|
+
const recent = recentFits.current.filter((entry) => now - entry.at < FIT_CYCLE_MS);
|
|
2681
|
+
recentFits.current = recent;
|
|
2682
|
+
if (recent.some((entry) => Math.abs(available - entry.width) < 1)) return;
|
|
2683
|
+
recent.push({ width: available, at: now });
|
|
2652
2684
|
fitTo(available);
|
|
2653
2685
|
};
|
|
2654
2686
|
run();
|
|
2655
2687
|
const observer = new ResizeObserver(run);
|
|
2656
2688
|
observer.observe(scroller);
|
|
2657
2689
|
return () => observer.disconnect();
|
|
2658
|
-
}, [autoFit, fitTo, selectable, renderExpanded,
|
|
2690
|
+
}, [autoFit, fitTo, selectable, renderExpanded, hiddenKey, orderKey]);
|
|
2659
2691
|
React39.useEffect(() => {
|
|
2660
2692
|
const scroller = scrollerRef.current;
|
|
2661
2693
|
if (!scroller) return;
|
|
2662
2694
|
const update = () => {
|
|
2663
2695
|
const max = scroller.scrollWidth - scroller.clientWidth;
|
|
2664
|
-
|
|
2696
|
+
const left = scroller.scrollLeft > 1;
|
|
2697
|
+
const right = scroller.scrollLeft < max - 1;
|
|
2698
|
+
setScrolled(
|
|
2699
|
+
(current) => current.left === left && current.right === right ? current : { left, right }
|
|
2700
|
+
);
|
|
2665
2701
|
};
|
|
2666
2702
|
update();
|
|
2667
2703
|
scroller.addEventListener("scroll", update, { passive: true });
|
|
@@ -2672,6 +2708,34 @@ function DataTable({
|
|
|
2672
2708
|
observer.disconnect();
|
|
2673
2709
|
};
|
|
2674
2710
|
}, [visible.length, data.length]);
|
|
2711
|
+
const moreRef = React39.useRef(null);
|
|
2712
|
+
const onLoadMoreRef = React39.useRef(onLoadMore);
|
|
2713
|
+
React39.useEffect(() => {
|
|
2714
|
+
onLoadMoreRef.current = onLoadMore;
|
|
2715
|
+
});
|
|
2716
|
+
const askedAt = React39.useRef(-1);
|
|
2717
|
+
const canLoadMore = Boolean(onLoadMore) && (hasMore ?? (total === void 0 || data.length < total));
|
|
2718
|
+
const showLoadMore = canLoadMore && !error && data.length > 0;
|
|
2719
|
+
const showPager = pagination ?? !onLoadMore;
|
|
2720
|
+
const askForMore = () => {
|
|
2721
|
+
if (askedAt.current === data.length) return;
|
|
2722
|
+
askedAt.current = data.length;
|
|
2723
|
+
onLoadMoreRef.current?.();
|
|
2724
|
+
};
|
|
2725
|
+
React39.useEffect(() => {
|
|
2726
|
+
const sentinel = moreRef.current;
|
|
2727
|
+
const scroller = scrollerRef.current;
|
|
2728
|
+
if (!sentinel || !scroller || !showLoadMore || !autoLoadMore || loading) return;
|
|
2729
|
+
if (typeof IntersectionObserver === "undefined") return;
|
|
2730
|
+
const observer = new IntersectionObserver(
|
|
2731
|
+
(entries) => {
|
|
2732
|
+
if (entries.some((entry) => entry.isIntersecting)) askForMore();
|
|
2733
|
+
},
|
|
2734
|
+
{ root: scroller, rootMargin: "120px" }
|
|
2735
|
+
);
|
|
2736
|
+
observer.observe(sentinel);
|
|
2737
|
+
return () => observer.disconnect();
|
|
2738
|
+
}, [showLoadMore, autoLoadMore, loading, data.length]);
|
|
2675
2739
|
const offsets = React39.useMemo(() => {
|
|
2676
2740
|
const result = /* @__PURE__ */ new Map();
|
|
2677
2741
|
let leftParts = selectable ? [`${SELECT_WIDTH}px`] : [];
|
|
@@ -2923,14 +2987,21 @@ function DataTable({
|
|
|
2923
2987
|
/* @__PURE__ */ jsx("tbody", { children: loading && data.length === 0 ? Array.from({ length: Math.min(query.pageSize, 8) }, (_, index) => /* @__PURE__ */ jsx("tr", { className: "mz-dt__row", children: /* @__PURE__ */ jsx("td", { className: "mz-dt__td", colSpan, children: /* @__PURE__ */ jsx(Skeleton, { style: { height: 14, width: `${60 + index * 13 % 35}%` } }) }) }, `skeleton-${index}`)) : data.map((row, rowIndex) => {
|
|
2924
2988
|
const key = rowKey(row);
|
|
2925
2989
|
const isOpen = expanded.has(key);
|
|
2990
|
+
const context = { rowIndex };
|
|
2991
|
+
const hostClass = rowClassName?.(row, context);
|
|
2992
|
+
const hostProps = rowProps?.(row, context);
|
|
2926
2993
|
return /* @__PURE__ */ jsxs(React39.Fragment, { children: [
|
|
2927
2994
|
/* @__PURE__ */ jsxs(
|
|
2928
2995
|
"tr",
|
|
2929
2996
|
{
|
|
2930
|
-
|
|
2997
|
+
...hostProps,
|
|
2998
|
+
className: cn("mz-dt__row", hostClass, hostProps?.className),
|
|
2931
2999
|
"data-selected": rows.selected.has(key) || rows.allMatching || void 0,
|
|
2932
3000
|
"data-clickable": onRowClick ? true : void 0,
|
|
2933
|
-
onClick: onRowClick ? () =>
|
|
3001
|
+
onClick: onRowClick || hostProps?.onClick ? (event) => {
|
|
3002
|
+
hostProps?.onClick?.(event);
|
|
3003
|
+
onRowClick?.(row);
|
|
3004
|
+
} : void 0,
|
|
2934
3005
|
children: [
|
|
2935
3006
|
selectable ? /* @__PURE__ */ jsx(
|
|
2936
3007
|
"td",
|
|
@@ -2979,7 +3050,11 @@ function DataTable({
|
|
|
2979
3050
|
]
|
|
2980
3051
|
}
|
|
2981
3052
|
),
|
|
2982
|
-
isOpen && renderExpanded ?
|
|
3053
|
+
isOpen && renderExpanded ? (
|
|
3054
|
+
// The detail panel belongs to the same record, so a row
|
|
3055
|
+
// tint carries onto it; the attributes do not.
|
|
3056
|
+
/* @__PURE__ */ jsx("tr", { className: cn("mz-dt__row mz-dt__row--expanded", hostClass), children: /* @__PURE__ */ jsx("td", { className: "mz-dt__td mz-dt__td--expanded", colSpan, children: renderExpanded(row) }) })
|
|
3057
|
+
) : null
|
|
2983
3058
|
] }, key);
|
|
2984
3059
|
}) })
|
|
2985
3060
|
] }),
|
|
@@ -3001,11 +3076,12 @@ function DataTable({
|
|
|
3001
3076
|
/* @__PURE__ */ jsx("p", { children: error }),
|
|
3002
3077
|
onRetry ? /* @__PURE__ */ jsx(Button, { size: "sm", variant: "secondary", onClick: onRetry, children: labels.retry }) : null
|
|
3003
3078
|
] }) : null,
|
|
3079
|
+
showLoadMore ? /* @__PURE__ */ jsx("div", { ref: moreRef, className: "mz-dt__more", "data-slot": "data-table-load-more", children: /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "sm", disabled: loading, onClick: askForMore, children: loading ? labels.loadingMore : labels.loadMore }) }) : null,
|
|
3004
3080
|
loading && data.length > 0 ? /* @__PURE__ */ jsx("div", { className: "mz-dt__loading-bar", "aria-hidden": "true" }) : null
|
|
3005
3081
|
]
|
|
3006
3082
|
}
|
|
3007
3083
|
),
|
|
3008
|
-
/* @__PURE__ */ jsx(
|
|
3084
|
+
showPager ? /* @__PURE__ */ jsx(
|
|
3009
3085
|
DataTablePagination,
|
|
3010
3086
|
{
|
|
3011
3087
|
query,
|
|
@@ -3016,7 +3092,7 @@ function DataTable({
|
|
|
3016
3092
|
locale,
|
|
3017
3093
|
onQueryChange
|
|
3018
3094
|
}
|
|
3019
|
-
),
|
|
3095
|
+
) : null,
|
|
3020
3096
|
selectable && (rows.count ?? 0) > 0 ? /* @__PURE__ */ jsxs("div", { className: "mz-dt__bulkbar", role: "region", "aria-label": labels.bulkActions, children: [
|
|
3021
3097
|
/* @__PURE__ */ jsxs("span", { className: "mz-dt__bulkbar-count", children: [
|
|
3022
3098
|
labels.selectedCount(
|
|
@@ -3051,6 +3127,10 @@ function describeFilter(value, def, labels) {
|
|
|
3051
3127
|
return `: ${value.from ?? "\u2026"} \u2013 ${value.to ?? "\u2026"}`;
|
|
3052
3128
|
case "boolean":
|
|
3053
3129
|
return `: ${value.value ? labels.yes.toLowerCase() : labels.no.toLowerCase()}`;
|
|
3130
|
+
case "custom": {
|
|
3131
|
+
const text = (def?.type === "custom" ? def.describe?.(value.value) : void 0) ?? value.label;
|
|
3132
|
+
return text ? `: ${text}` : "";
|
|
3133
|
+
}
|
|
3054
3134
|
}
|
|
3055
3135
|
}
|
|
3056
3136
|
|