@mihcm/ui 0.14.1 → 0.15.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/CheckboxGrid.native.d.ts.map +1 -1
- package/dist/CheckboxGrid.native.js +2 -1
- package/dist/CheckboxGrid.native.js.map +1 -1
- package/dist/Combobox.native.d.ts.map +1 -1
- package/dist/Combobox.native.js +2 -1
- package/dist/Combobox.native.js.map +1 -1
- package/dist/DataTable/column-filter.d.ts +8 -0
- package/dist/DataTable/column-filter.d.ts.map +1 -0
- package/dist/DataTable/column-filter.js +67 -0
- package/dist/DataTable/column-filter.js.map +1 -0
- package/dist/DataTable/column-header.d.ts +16 -0
- package/dist/DataTable/column-header.d.ts.map +1 -0
- package/dist/DataTable/column-header.js +11 -0
- package/dist/DataTable/column-header.js.map +1 -0
- package/dist/DataTable/column-visibility.d.ts +7 -0
- package/dist/DataTable/column-visibility.d.ts.map +1 -0
- package/dist/DataTable/column-visibility.js +35 -0
- package/dist/DataTable/column-visibility.js.map +1 -0
- package/dist/DataTable/index.d.ts +5 -0
- package/dist/DataTable/index.d.ts.map +1 -0
- package/dist/DataTable/index.js +5 -0
- package/dist/DataTable/index.js.map +1 -0
- package/dist/DataTable/pinning.d.ts +13 -0
- package/dist/DataTable/pinning.d.ts.map +1 -0
- package/dist/DataTable/pinning.js +29 -0
- package/dist/DataTable/pinning.js.map +1 -0
- package/dist/DataTable.d.ts +3 -7
- package/dist/DataTable.d.ts.map +1 -1
- package/dist/DataTable.js +7 -126
- package/dist/DataTable.js.map +1 -1
- package/dist/Dialog.native.d.ts +3 -1
- package/dist/Dialog.native.d.ts.map +1 -1
- package/dist/Dialog.native.js +2 -2
- package/dist/Dialog.native.js.map +1 -1
- package/dist/Form/building-blocks.d.ts +26 -0
- package/dist/Form/building-blocks.d.ts.map +1 -0
- package/dist/Form/building-blocks.js +29 -0
- package/dist/Form/building-blocks.js.map +1 -0
- package/dist/Form/fields-choice.d.ts +72 -0
- package/dist/Form/fields-choice.d.ts.map +1 -0
- package/dist/Form/fields-choice.js +69 -0
- package/dist/Form/fields-choice.js.map +1 -0
- package/dist/Form/fields-complex.d.ts +28 -0
- package/dist/Form/fields-complex.d.ts.map +1 -0
- package/dist/Form/fields-complex.js +38 -0
- package/dist/Form/fields-complex.js.map +1 -0
- package/dist/Form/fields-date.d.ts +46 -0
- package/dist/Form/fields-date.d.ts.map +1 -0
- package/dist/Form/fields-date.js +41 -0
- package/dist/Form/fields-date.js.map +1 -0
- package/dist/Form/fields-text.d.ts +47 -0
- package/dist/Form/fields-text.d.ts.map +1 -0
- package/dist/Form/fields-text.js +46 -0
- package/dist/Form/fields-text.js.map +1 -0
- package/dist/Form/fields-toggle.d.ts +24 -0
- package/dist/Form/fields-toggle.d.ts.map +1 -0
- package/dist/Form/fields-toggle.js +32 -0
- package/dist/Form/fields-toggle.js.map +1 -0
- package/dist/Form/helpers.d.ts +66 -0
- package/dist/Form/helpers.d.ts.map +1 -0
- package/dist/Form/helpers.js +44 -0
- package/dist/Form/helpers.js.map +1 -0
- package/dist/Form/types.d.ts +25 -0
- package/dist/Form/types.d.ts.map +1 -0
- package/dist/Form/types.js +8 -0
- package/dist/Form/types.js.map +1 -0
- package/dist/Form.d.ts +24 -298
- package/dist/Form.d.ts.map +1 -1
- package/dist/Form.js +30 -246
- package/dist/Form.js.map +1 -1
- package/dist/IconSidebar.d.ts +6 -46
- package/dist/IconSidebar.d.ts.map +1 -1
- package/dist/IconSidebar.js +6 -116
- package/dist/IconSidebar.js.map +1 -1
- package/dist/MainSidebar/back-button.d.ts +14 -0
- package/dist/MainSidebar/back-button.d.ts.map +1 -0
- package/dist/MainSidebar/back-button.js +14 -0
- package/dist/MainSidebar/back-button.js.map +1 -0
- package/dist/MainSidebar/breadcrumb.d.ts +10 -0
- package/dist/MainSidebar/breadcrumb.d.ts.map +1 -0
- package/dist/MainSidebar/breadcrumb.js +24 -0
- package/dist/MainSidebar/breadcrumb.js.map +1 -0
- package/dist/MainSidebar/columns.d.ts +3 -0
- package/dist/MainSidebar/columns.d.ts.map +1 -0
- package/dist/MainSidebar/columns.js +198 -0
- package/dist/MainSidebar/columns.js.map +1 -0
- package/dist/MainSidebar/command.d.ts +3 -0
- package/dist/MainSidebar/command.d.ts.map +1 -0
- package/dist/MainSidebar/command.js +193 -0
- package/dist/MainSidebar/command.js.map +1 -0
- package/dist/MainSidebar/drilldown.d.ts +3 -0
- package/dist/MainSidebar/drilldown.d.ts.map +1 -0
- package/dist/MainSidebar/drilldown.js +154 -0
- package/dist/MainSidebar/drilldown.js.map +1 -0
- package/dist/MainSidebar/expanded.d.ts +7 -0
- package/dist/MainSidebar/expanded.d.ts.map +1 -0
- package/dist/MainSidebar/expanded.js +102 -0
- package/dist/MainSidebar/expanded.js.map +1 -0
- package/dist/MainSidebar/floating.d.ts +3 -0
- package/dist/MainSidebar/floating.d.ts.map +1 -0
- package/dist/MainSidebar/floating.js +116 -0
- package/dist/MainSidebar/floating.js.map +1 -0
- package/dist/MainSidebar/helpers.d.ts +50 -0
- package/dist/MainSidebar/helpers.d.ts.map +1 -0
- package/dist/MainSidebar/helpers.js +148 -0
- package/dist/MainSidebar/helpers.js.map +1 -0
- package/dist/MainSidebar/hover.d.ts +3 -0
- package/dist/MainSidebar/hover.d.ts.map +1 -0
- package/dist/MainSidebar/hover.js +177 -0
- package/dist/MainSidebar/hover.js.map +1 -0
- package/dist/MainSidebar/index.d.ts +6 -0
- package/dist/MainSidebar/index.d.ts.map +1 -0
- package/dist/MainSidebar/index.js +108 -0
- package/dist/MainSidebar/index.js.map +1 -0
- package/dist/MainSidebar/mobile.d.ts +29 -0
- package/dist/MainSidebar/mobile.d.ts.map +1 -0
- package/dist/MainSidebar/mobile.js +38 -0
- package/dist/MainSidebar/mobile.js.map +1 -0
- package/dist/MainSidebar/motion.d.ts +23 -0
- package/dist/MainSidebar/motion.d.ts.map +1 -0
- package/dist/MainSidebar/motion.js +40 -0
- package/dist/MainSidebar/motion.js.map +1 -0
- package/dist/MainSidebar/rail.d.ts +24 -0
- package/dist/MainSidebar/rail.d.ts.map +1 -0
- package/dist/MainSidebar/rail.js +29 -0
- package/dist/MainSidebar/rail.js.map +1 -0
- package/dist/MainSidebar/search.d.ts +19 -0
- package/dist/MainSidebar/search.d.ts.map +1 -0
- package/dist/MainSidebar/search.js +33 -0
- package/dist/MainSidebar/search.js.map +1 -0
- package/dist/MainSidebar/types.d.ts +161 -0
- package/dist/MainSidebar/types.d.ts.map +1 -0
- package/dist/MainSidebar/types.js +2 -0
- package/dist/MainSidebar/types.js.map +1 -0
- package/dist/MainSidebar.d.ts +6 -1
- package/dist/MainSidebar.d.ts.map +1 -1
- package/dist/MainSidebar.js +6 -1
- package/dist/MainSidebar.js.map +1 -1
- package/dist/NavigationMenu.js +1 -1
- package/dist/NavigationMenu.js.map +1 -1
- package/dist/RichTextEditor/theme.d.ts +44 -0
- package/dist/RichTextEditor/theme.d.ts.map +1 -0
- package/dist/RichTextEditor/theme.js +41 -0
- package/dist/RichTextEditor/theme.js.map +1 -0
- package/dist/RichTextEditor/toolbar-icons.d.ts +21 -0
- package/dist/RichTextEditor/toolbar-icons.d.ts.map +1 -0
- package/dist/RichTextEditor/toolbar-icons.js +21 -0
- package/dist/RichTextEditor/toolbar-icons.js.map +1 -0
- package/dist/RichTextEditor/toolbar.d.ts +5 -0
- package/dist/RichTextEditor/toolbar.d.ts.map +1 -0
- package/dist/RichTextEditor/toolbar.js +116 -0
- package/dist/RichTextEditor/toolbar.js.map +1 -0
- package/dist/RichTextEditor.d.ts +16 -9
- package/dist/RichTextEditor.d.ts.map +1 -1
- package/dist/RichTextEditor.js +18 -164
- package/dist/RichTextEditor.js.map +1 -1
- package/dist/Select/content.d.ts +9 -0
- package/dist/Select/content.d.ts.map +1 -0
- package/dist/Select/content.js +80 -0
- package/dist/Select/content.js.map +1 -0
- package/dist/Select/context.d.ts +27 -0
- package/dist/Select/context.d.ts.map +1 -0
- package/dist/Select/context.js +35 -0
- package/dist/Select/context.js.map +1 -0
- package/dist/Select/item.d.ts +13 -0
- package/dist/Select/item.d.ts.map +1 -0
- package/dist/Select/item.js +39 -0
- package/dist/Select/item.js.map +1 -0
- package/dist/Select/parts.d.ts +14 -0
- package/dist/Select/parts.d.ts.map +1 -0
- package/dist/Select/parts.js +17 -0
- package/dist/Select/parts.js.map +1 -0
- package/dist/Select/react-select.d.ts +25 -0
- package/dist/Select/react-select.d.ts.map +1 -0
- package/dist/Select/react-select.js +66 -0
- package/dist/Select/react-select.js.map +1 -0
- package/dist/Select/root.d.ts +15 -0
- package/dist/Select/root.d.ts.map +1 -0
- package/dist/Select/root.js +41 -0
- package/dist/Select/root.js.map +1 -0
- package/dist/Select/trigger.d.ts +15 -0
- package/dist/Select/trigger.d.ts.map +1 -0
- package/dist/Select/trigger.js +61 -0
- package/dist/Select/trigger.js.map +1 -0
- package/dist/Select.d.ts +14 -62
- package/dist/Select.d.ts.map +1 -1
- package/dist/Select.js +14 -293
- package/dist/Select.js.map +1 -1
- package/dist/Sidebar/context.d.ts +28 -0
- package/dist/Sidebar/context.d.ts.map +1 -0
- package/dist/Sidebar/context.js +37 -0
- package/dist/Sidebar/context.js.map +1 -0
- package/dist/Sidebar/group.d.ts +13 -0
- package/dist/Sidebar/group.d.ts.map +1 -0
- package/dist/Sidebar/group.js +20 -0
- package/dist/Sidebar/group.js.map +1 -0
- package/dist/Sidebar/icons.d.ts +7 -0
- package/dist/Sidebar/icons.d.ts.map +1 -0
- package/dist/Sidebar/icons.js +12 -0
- package/dist/Sidebar/icons.js.map +1 -0
- package/dist/Sidebar/layout.d.ts +9 -0
- package/dist/Sidebar/layout.d.ts.map +1 -0
- package/dist/Sidebar/layout.js +21 -0
- package/dist/Sidebar/layout.js.map +1 -0
- package/dist/Sidebar/menu.d.ts +29 -0
- package/dist/Sidebar/menu.d.ts.map +1 -0
- package/dist/Sidebar/menu.js +55 -0
- package/dist/Sidebar/menu.js.map +1 -0
- package/dist/Sidebar/provider.d.ts +33 -0
- package/dist/Sidebar/provider.d.ts.map +1 -0
- package/dist/Sidebar/provider.js +110 -0
- package/dist/Sidebar/provider.js.map +1 -0
- package/dist/Sidebar/sidebar.d.ts +17 -0
- package/dist/Sidebar/sidebar.d.ts.map +1 -0
- package/dist/Sidebar/sidebar.js +51 -0
- package/dist/Sidebar/sidebar.js.map +1 -0
- package/dist/Sidebar/submenu.d.ts +13 -0
- package/dist/Sidebar/submenu.d.ts.map +1 -0
- package/dist/Sidebar/submenu.js +17 -0
- package/dist/Sidebar/submenu.js.map +1 -0
- package/dist/Sidebar/trigger.d.ts +9 -0
- package/dist/Sidebar/trigger.d.ts.map +1 -0
- package/dist/Sidebar/trigger.js +33 -0
- package/dist/Sidebar/trigger.js.map +1 -0
- package/dist/Sidebar.d.ts +14 -104
- package/dist/Sidebar.d.ts.map +1 -1
- package/dist/Sidebar.js +14 -300
- package/dist/Sidebar.js.map +1 -1
- package/dist/StatCard.d.ts +67 -9
- package/dist/StatCard.d.ts.map +1 -1
- package/dist/StatCard.js +111 -9
- package/dist/StatCard.js.map +1 -1
- package/dist/TransferList.native.d.ts.map +1 -1
- package/dist/TransferList.native.js +2 -1
- package/dist/TransferList.native.js.map +1 -1
- package/package.json +2 -2
- package/src/CheckboxGrid.native.tsx +2 -1
- package/src/Combobox.native.tsx +2 -1
- package/src/DataTable/column-filter.tsx +134 -0
- package/src/DataTable/column-header.tsx +67 -0
- package/src/DataTable/column-visibility.tsx +87 -0
- package/src/DataTable/index.ts +4 -0
- package/src/DataTable/pinning.ts +40 -0
- package/src/DataTable.tsx +14 -297
- package/src/Dialog.native.tsx +4 -2
- package/src/Form/building-blocks.tsx +97 -0
- package/src/Form/fields-choice.tsx +312 -0
- package/src/Form/fields-complex.tsx +195 -0
- package/src/Form/fields-date.tsx +195 -0
- package/src/Form/fields-text.tsx +218 -0
- package/src/Form/fields-toggle.tsx +123 -0
- package/src/Form/helpers.tsx +189 -0
- package/src/Form/types.ts +26 -0
- package/src/Form.tsx +91 -1308
- package/src/IconSidebar.tsx +20 -442
- package/src/MainSidebar/back-button.tsx +58 -0
- package/src/MainSidebar/breadcrumb.tsx +53 -0
- package/src/MainSidebar/columns.tsx +350 -0
- package/src/MainSidebar/command.tsx +404 -0
- package/src/MainSidebar/drilldown.tsx +373 -0
- package/src/MainSidebar/expanded.tsx +414 -0
- package/src/MainSidebar/floating.tsx +268 -0
- package/src/MainSidebar/helpers.ts +164 -0
- package/src/MainSidebar/hover.tsx +334 -0
- package/src/MainSidebar/index.tsx +191 -0
- package/src/MainSidebar/mobile.tsx +117 -0
- package/src/MainSidebar/motion.ts +64 -0
- package/src/MainSidebar/rail.tsx +137 -0
- package/src/MainSidebar/search.tsx +99 -0
- package/src/MainSidebar/types.ts +208 -0
- package/src/MainSidebar.tsx +15 -4
- package/src/NavigationMenu.tsx +1 -1
- package/src/RichTextEditor/theme.ts +43 -0
- package/src/RichTextEditor/toolbar-icons.tsx +40 -0
- package/src/RichTextEditor/toolbar.tsx +271 -0
- package/src/RichTextEditor.tsx +23 -371
- package/src/Select/content.tsx +111 -0
- package/src/Select/context.tsx +66 -0
- package/src/Select/item.tsx +97 -0
- package/src/Select/parts.tsx +43 -0
- package/src/Select/react-select.tsx +216 -0
- package/src/Select/root.tsx +75 -0
- package/src/Select/trigger.tsx +122 -0
- package/src/Select.tsx +34 -692
- package/src/Sidebar/context.tsx +72 -0
- package/src/Sidebar/group.tsx +69 -0
- package/src/Sidebar/icons.tsx +42 -0
- package/src/Sidebar/layout.tsx +64 -0
- package/src/Sidebar/menu.tsx +171 -0
- package/src/Sidebar/provider.tsx +224 -0
- package/src/Sidebar/sidebar.tsx +178 -0
- package/src/Sidebar/submenu.tsx +58 -0
- package/src/Sidebar/trigger.tsx +104 -0
- package/src/Sidebar.tsx +44 -927
- package/src/StatCard.tsx +365 -20
- package/src/TransferList.native.tsx +2 -1
- package/dist/TiptapEditor.d.ts +0 -24
- package/dist/TiptapEditor.d.ts.map +0 -1
- package/dist/TiptapEditor.js +0 -84
- package/dist/TiptapEditor.js.map +0 -1
package/dist/StatCard.js
CHANGED
|
@@ -3,18 +3,28 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
/**
|
|
4
4
|
* StatCard (web variant — React DOM).
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* Seven layout variants for product KPI surfaces:
|
|
7
|
+
*
|
|
8
|
+
* - `default` — Centered icon tile + big number + label (original layout)
|
|
9
|
+
* - `inline` — Icon left, value + label stacked right (compact rows)
|
|
10
|
+
* - `delta` — Value + ↑/↓ percentage in a semantic tone
|
|
11
|
+
* - `trend` — Value + delta + inline SparkChart trend (Stripe / Tremor)
|
|
12
|
+
* - `progress` — Value + thin progress bar (current / max goal)
|
|
13
|
+
* - `distribution` — Value + segmented CategoryBar breakdown
|
|
14
|
+
* - `hero` — Single huge number, no chrome (marketing / summary callouts)
|
|
15
|
+
*
|
|
16
|
+
* All variants share `value`, `label`, optional `icon`, and the 6-tone palette.
|
|
17
|
+
* Variant-specific props (`delta`, `sparkline`, `max`, `segments`) are typed
|
|
18
|
+
* via a discriminated union so consumers can't mix prop sets by mistake.
|
|
10
19
|
*
|
|
11
20
|
* Wiki: docs/components/StatCard.md
|
|
12
21
|
*/
|
|
13
22
|
import { forwardRef } from 'react';
|
|
14
|
-
import { cva } from 'class-variance-authority';
|
|
15
|
-
import { Text } from './Text.js';
|
|
16
23
|
import { cn } from './internal/cn.js';
|
|
17
|
-
|
|
24
|
+
import { Text } from './Text.js';
|
|
25
|
+
import { CategoryBar } from './CategoryBar.js';
|
|
26
|
+
import { SparkChart } from './SparkChart.js';
|
|
27
|
+
/* ── Tone tokens ──────────────────────────────────────────────────── */
|
|
18
28
|
const TILE_TONE = {
|
|
19
29
|
primary: 'bg-primary-50 text-primary dark:bg-primary-950 dark:text-primary-300',
|
|
20
30
|
accent: 'bg-accent-50 text-accent',
|
|
@@ -31,7 +41,99 @@ const VALUE_TONE = {
|
|
|
31
41
|
danger: 'text-destructive',
|
|
32
42
|
neutral: 'text-foreground',
|
|
33
43
|
};
|
|
34
|
-
|
|
35
|
-
|
|
44
|
+
const SEGMENT_TONE = {
|
|
45
|
+
primary: 'bg-primary',
|
|
46
|
+
accent: 'bg-accent',
|
|
47
|
+
success: 'bg-success',
|
|
48
|
+
warning: 'bg-warning',
|
|
49
|
+
danger: 'bg-destructive',
|
|
50
|
+
neutral: 'bg-muted-foreground',
|
|
51
|
+
};
|
|
52
|
+
function deltaToneClass(delta) {
|
|
53
|
+
if (delta.direction === 'flat')
|
|
54
|
+
return 'text-muted-foreground';
|
|
55
|
+
const positiveIsGood = delta.positiveIsGood ?? true;
|
|
56
|
+
const isGood = (delta.direction === 'up') === positiveIsGood;
|
|
57
|
+
return isGood ? 'text-success' : 'text-destructive';
|
|
58
|
+
}
|
|
59
|
+
function deltaDisplay(delta) {
|
|
60
|
+
if (delta.formatted)
|
|
61
|
+
return delta.formatted;
|
|
62
|
+
const sign = delta.direction === 'up' ? '+' : delta.direction === 'down' ? '-' : '±';
|
|
63
|
+
return `${sign}${Math.abs(delta.value)}%`;
|
|
64
|
+
}
|
|
65
|
+
function DeltaIndicator({ delta }) {
|
|
66
|
+
const Arrow = delta.direction === 'up' ? UpArrow : delta.direction === 'down' ? DownArrow : null;
|
|
67
|
+
return (_jsxs("span", { className: cn('inline-flex items-center gap-0.5 text-xs font-medium tabular-nums', deltaToneClass(delta)), children: [Arrow ? _jsx(Arrow, {}) : null, deltaDisplay(delta)] }));
|
|
68
|
+
}
|
|
69
|
+
function UpArrow() {
|
|
70
|
+
return (_jsx("svg", { viewBox: "0 0 12 12", className: "size-3", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: _jsx("path", { d: "M6 10V2M3 5l3-3 3 3", strokeLinecap: "round", strokeLinejoin: "round" }) }));
|
|
71
|
+
}
|
|
72
|
+
function DownArrow() {
|
|
73
|
+
return (_jsx("svg", { viewBox: "0 0 12 12", className: "size-3", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", children: _jsx("path", { d: "M6 2v8M3 7l3 3 3-3", strokeLinecap: "round", strokeLinejoin: "round" }) }));
|
|
74
|
+
}
|
|
75
|
+
/* ── Shared shell ─────────────────────────────────────────────────── */
|
|
76
|
+
const cardShell = 'rounded-card border border-secondary bg-card';
|
|
77
|
+
/* ── Component dispatch ───────────────────────────────────────────── */
|
|
78
|
+
export const StatCard = forwardRef(function StatCard(props, ref) {
|
|
79
|
+
switch (props.variant) {
|
|
80
|
+
case 'inline':
|
|
81
|
+
return _jsx(InlineCard, { ref: ref, ...props });
|
|
82
|
+
case 'delta':
|
|
83
|
+
return _jsx(DeltaCard, { ref: ref, ...props });
|
|
84
|
+
case 'trend':
|
|
85
|
+
return _jsx(TrendCard, { ref: ref, ...props });
|
|
86
|
+
case 'progress':
|
|
87
|
+
return _jsx(ProgressCard, { ref: ref, ...props });
|
|
88
|
+
case 'distribution':
|
|
89
|
+
return _jsx(DistributionCard, { ref: ref, ...props });
|
|
90
|
+
case 'hero':
|
|
91
|
+
return _jsx(HeroCard, { ref: ref, ...props });
|
|
92
|
+
case 'default':
|
|
93
|
+
case undefined:
|
|
94
|
+
default:
|
|
95
|
+
return _jsx(DefaultCard, { ref: ref, ...props });
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
/* ── 1. Default — centered icon tile ──────────────────────────────── */
|
|
99
|
+
const DefaultCard = forwardRef(function DefaultCard({ className, value, label, icon, tone = 'primary', variant: _v, ...rest }, ref) {
|
|
100
|
+
return (_jsxs("div", { ref: ref, className: cn(cardShell, 'px-3 py-4 text-center', className), ...rest, children: [icon ? (_jsx("div", { className: cn('mx-auto mb-2 grid h-9 w-9 place-items-center rounded-card', TILE_TONE[tone]), children: _jsx("span", { className: "grid size-4.5 place-items-center [&_svg]:size-full", children: icon }) })) : null, _jsx(Text, { as: "div", size: "stat", weight: "bold", className: cn(VALUE_TONE[tone]), children: value }), _jsx(Text, { as: "div", size: "label", tone: "muted", className: "mt-0.5", children: label })] }));
|
|
101
|
+
});
|
|
102
|
+
/* ── 2. Inline — horizontal icon + stacked value/label ────────────── */
|
|
103
|
+
const InlineCard = forwardRef(function InlineCard({ className, value, label, icon, tone = 'primary', variant: _v, ...rest }, ref) {
|
|
104
|
+
return (_jsxs("div", { ref: ref, className: cn(cardShell, 'flex items-center gap-3 px-4 py-3', className), ...rest, children: [icon ? (_jsx("div", { className: cn('grid size-10 shrink-0 place-items-center rounded-card', TILE_TONE[tone]), children: _jsx("span", { className: "grid size-5 place-items-center [&_svg]:size-full", children: icon }) })) : null, _jsxs("div", { className: "flex min-w-0 flex-col", children: [_jsx(Text, { as: "div", size: "stat-sm", weight: "bold", className: cn('truncate', VALUE_TONE[tone]), children: value }), _jsx(Text, { as: "div", size: "label", tone: "muted", className: "truncate", children: label })] })] }));
|
|
105
|
+
});
|
|
106
|
+
/* ── 3. Delta — value + ↑/↓ percentage ────────────────────────────── */
|
|
107
|
+
const DeltaCard = forwardRef(function DeltaCard({ className, value, label, tone = 'neutral', delta, variant: _v, icon: _i, ...rest }, ref) {
|
|
108
|
+
return (_jsxs("div", { ref: ref, className: cn(cardShell, 'px-4 py-3', className), ...rest, children: [_jsx(Text, { as: "div", size: "label", tone: "muted", className: "uppercase tracking-wider", children: label }), _jsxs("div", { className: "mt-1 flex items-baseline gap-2", children: [_jsx(Text, { as: "span", size: "stat", weight: "bold", className: cn('tabular-nums leading-tight', VALUE_TONE[tone]), children: value }), _jsx(DeltaIndicator, { delta: delta })] })] }));
|
|
109
|
+
});
|
|
110
|
+
/* ── 4. Trend — value + delta + SparkChart ────────────────────────── */
|
|
111
|
+
const SPARK_TONE_FOR = {
|
|
112
|
+
primary: 'primary',
|
|
113
|
+
accent: 'accent',
|
|
114
|
+
success: 'success',
|
|
115
|
+
warning: 'warning',
|
|
116
|
+
danger: 'danger',
|
|
117
|
+
};
|
|
118
|
+
const TrendCard = forwardRef(function TrendCard({ className, value, label, tone = 'primary', delta, sparkline, sparklineTone, variant: _v, icon: _i, ...rest }, ref) {
|
|
119
|
+
const resolvedSparkTone = sparklineTone ?? SPARK_TONE_FOR[tone] ?? 'primary';
|
|
120
|
+
return (_jsxs("div", { ref: ref, className: cn(cardShell, 'flex items-center gap-4 px-4 py-3', className), ...rest, children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx(Text, { as: "div", size: "label", tone: "muted", className: "uppercase tracking-wider", children: label }), _jsxs("div", { className: "mt-1 flex items-baseline gap-2", children: [_jsx(Text, { as: "span", size: "stat", weight: "bold", className: cn('tabular-nums leading-tight', VALUE_TONE[tone]), children: value }), delta ? _jsx(DeltaIndicator, { delta: delta }) : null] })] }), _jsx(SparkChart, { data: sparkline, tone: resolvedSparkTone, showArea: true, width: 96, height: 40, className: "shrink-0", "aria-hidden": "true" })] }));
|
|
121
|
+
});
|
|
122
|
+
/* ── 5. Progress — value of max + thin bar ────────────────────────── */
|
|
123
|
+
const ProgressCard = forwardRef(function ProgressCard({ className, value, label, tone = 'primary', max, valueLabel, variant: _v, icon: _i, ...rest }, ref) {
|
|
124
|
+
const numericValue = typeof value === 'number' ? value : Number(value) || 0;
|
|
125
|
+
const pct = max > 0 ? Math.max(0, Math.min(100, (numericValue / max) * 100)) : 0;
|
|
126
|
+
const display = valueLabel ?? `${value} / ${max}`;
|
|
127
|
+
return (_jsxs("div", { ref: ref, className: cn(cardShell, 'space-y-2.5 px-4 py-3', className), ...rest, children: [_jsxs("div", { className: "flex items-baseline justify-between gap-2", children: [_jsx(Text, { as: "div", size: "label", tone: "muted", className: "uppercase tracking-wider", children: label }), _jsxs(Text, { as: "span", size: "label", tone: "muted", className: "tabular-nums", children: [Math.round(pct), "%"] })] }), _jsx(Text, { as: "div", size: "stat", weight: "bold", className: cn('tabular-nums leading-tight', VALUE_TONE[tone]), children: display }), _jsx("div", { role: "progressbar", "aria-valuemin": 0, "aria-valuemax": max, "aria-valuenow": numericValue, "aria-label": typeof label === 'string' ? label : undefined, className: "h-1.5 w-full overflow-hidden rounded-full bg-muted", children: _jsx("div", { className: cn('h-full rounded-full transition-[width] duration-500', SEGMENT_TONE[tone]), style: { width: `${pct}%` } }) })] }));
|
|
128
|
+
});
|
|
129
|
+
/* ── 6. Distribution — value + segmented CategoryBar ──────────────── */
|
|
130
|
+
const DistributionCard = forwardRef(function DistributionCard({ className, value, label, tone = 'primary', segments, variant: _v, icon: _i, ...rest }, ref) {
|
|
131
|
+
return (_jsxs("div", { ref: ref, className: cn(cardShell, 'space-y-3 px-4 py-3', className), ...rest, children: [_jsxs("div", { children: [_jsx(Text, { as: "div", size: "label", tone: "muted", className: "uppercase tracking-wider", children: label }), _jsx(Text, { as: "div", size: "stat", weight: "bold", className: cn('mt-1 tabular-nums leading-tight', VALUE_TONE[tone]), children: value })] }), _jsx(CategoryBar, { data: segments, legendPosition: "bottom" })] }));
|
|
132
|
+
});
|
|
133
|
+
/* ── 7. Hero — single huge number ─────────────────────────────────── */
|
|
134
|
+
const HeroCard = forwardRef(function HeroCard({ className, value, label, tone = 'primary', variant: _v, icon: _i, ...rest }, ref) {
|
|
135
|
+
return (_jsxs("div", { ref: ref, className: cn(cardShell, 'px-6 py-8 text-center', className), ...rest, children: [_jsx(Text, { as: "div", size: "5xl", weight: "bold", className: cn('tabular-nums leading-none', VALUE_TONE[tone]), children: value }), _jsx(Text, { as: "div", size: "sm", tone: "muted", className: "mt-2 uppercase tracking-wider", children: label })] }));
|
|
36
136
|
});
|
|
137
|
+
/* ── Backward-compat re-export for any consumer pulling the cva ──── */
|
|
138
|
+
export const statCardVariants = () => 'rounded-card border border-secondary bg-card py-4 px-3 text-center';
|
|
37
139
|
//# sourceMappingURL=StatCard.js.map
|
package/dist/StatCard.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StatCard.js","sourceRoot":"","sources":["../src/StatCard.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb
|
|
1
|
+
{"version":3,"file":"StatCard.js","sourceRoot":"","sources":["../src/StatCard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransferList.native.d.ts","sourceRoot":"","sources":["../src/TransferList.native.tsx"],"names":[],"mappings":"AAWA,OAAO,EAAwC,IAAI,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"TransferList.native.d.ts","sourceRoot":"","sources":["../src/TransferList.native.tsx"],"names":[],"mappings":"AAWA,OAAO,EAAwC,IAAI,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAI1F,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE7D,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC;IACjE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,sBAAsB,CAAC;IACjC,gBAAgB,EAAE,CAAC,IAAI,EAAE,sBAAsB,KAAK,IAAI,CAAC;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,YAAY,oGAwJxB,CAAC"}
|
|
@@ -11,6 +11,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
11
11
|
*/
|
|
12
12
|
import { forwardRef, useMemo, useState } from 'react';
|
|
13
13
|
import { FlatList, Pressable, Text, TextInput, View } from 'react-native';
|
|
14
|
+
import { NATIVE_PLACEHOLDER_COLOR } from '@mihcm/theme';
|
|
14
15
|
import { cn } from './internal/cn.js';
|
|
15
16
|
export const TransferList = forwardRef(function TransferList({ className, items, assigned, onAssignedChange, leftLabel = 'Available', rightLabel = 'Assigned', filterPlaceholder = 'Filter…', maxHeight = 200, ...props }, ref) {
|
|
16
17
|
const [leftFilter, setLeftFilter] = useState('');
|
|
@@ -49,7 +50,7 @@ export const TransferList = forwardRef(function TransferList({ className, items,
|
|
|
49
50
|
onAssignedChange(next);
|
|
50
51
|
};
|
|
51
52
|
const moveAllLeft = () => onAssignedChange({});
|
|
52
|
-
const renderPane = (label, total, filtered, filterValue, onFilterChange, isAssigned) => (_jsxs(View, { className: "rounded-lg border border-border bg-card overflow-hidden", children: [_jsxs(View, { className: "border-b border-border bg-muted/40 px-3 py-2", children: [_jsx(Text, { className: "text-sm font-semibold text-foreground", children: label }), _jsxs(Text, { className: "text-xs text-muted-foreground", children: [total, " ", total === 1 ? 'item' : 'items'] })] }), _jsx(View, { className: "border-b border-border px-3 py-2", children: _jsx(TextInput, { value: filterValue, onChangeText: onFilterChange, placeholder: filterPlaceholder, accessibilityLabel: `Filter ${label}`, className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground", placeholderTextColor:
|
|
53
|
+
const renderPane = (label, total, filtered, filterValue, onFilterChange, isAssigned) => (_jsxs(View, { className: "rounded-lg border border-border bg-card overflow-hidden", children: [_jsxs(View, { className: "border-b border-border bg-muted/40 px-3 py-2", children: [_jsx(Text, { className: "text-sm font-semibold text-foreground", children: label }), _jsxs(Text, { className: "text-xs text-muted-foreground", children: [total, " ", total === 1 ? 'item' : 'items'] })] }), _jsx(View, { className: "border-b border-border px-3 py-2", children: _jsx(TextInput, { value: filterValue, onChangeText: onFilterChange, placeholder: filterPlaceholder, accessibilityLabel: `Filter ${label}`, className: "rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground", placeholderTextColor: NATIVE_PLACEHOLDER_COLOR }) }), _jsx(FlatList, { data: filtered, keyExtractor: (item) => item, style: { maxHeight }, ListEmptyComponent: _jsx(View, { className: "items-center py-4", children: _jsx(Text, { className: "text-xs text-muted-foreground", children: total === 0 ? (isAssigned ? 'None assigned' : 'No items') : 'No matches' }) }), renderItem: ({ item }) => (_jsxs(Pressable, { accessibilityRole: "button", accessibilityLabel: isAssigned ? `Remove ${item}` : `Assign ${item}`, onPress: () => toggleItem(item), className: "flex-row items-center gap-3 border-b border-border/50 px-3 py-3", children: [_jsx(View, { className: cn('h-5 w-5 items-center justify-center rounded-full', isAssigned
|
|
53
54
|
? 'bg-primary'
|
|
54
55
|
: 'border-2 border-muted-foreground bg-background'), children: isAssigned && (_jsx(Text, { className: "text-xs text-primary-foreground", children: '✓' })) }), _jsx(Text, { className: "text-sm text-foreground flex-1", numberOfLines: 1, children: item })] })) })] }));
|
|
55
56
|
return (_jsxs(View, { ref: ref, className: cn('gap-3', className), ...props, children: [renderPane(leftLabel, leftItems.length, filteredLeft, leftFilter, setLeftFilter, false), _jsxs(View, { className: "flex-row items-center justify-center gap-3", children: [_jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: "Move all to assigned", disabled: leftItems.length === 0, onPress: moveAllRight, className: cn('rounded border border-border bg-card px-4 py-2', leftItems.length === 0 && 'opacity-40'), children: _jsx(Text, { className: "text-xs font-medium text-foreground", children: "Assign All \u2193" }) }), _jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: "Remove all from assigned", disabled: rightItems.length === 0, onPress: moveAllLeft, className: cn('rounded border border-border bg-card px-4 py-2', rightItems.length === 0 && 'opacity-40'), children: _jsx(Text, { className: "text-xs font-medium text-foreground", children: "Remove All \u2191" }) })] }), renderPane(rightLabel, rightItems.length, filteredRight, rightFilter, setRightFilter, true)] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransferList.native.js","sourceRoot":"","sources":["../src/TransferList.native.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"TransferList.native.js","sourceRoot":"","sources":["../src/TransferList.native.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAkB,MAAM,cAAc,CAAC;AAC1F,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAetC,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CACpC,SAAS,YAAY,CACnB,EACE,SAAS,EACT,KAAK,EACL,QAAQ,EACR,gBAAgB,EAChB,SAAS,GAAG,WAAW,EACvB,UAAU,GAAG,UAAU,EACvB,iBAAiB,GAAG,SAAS,EAC7B,SAAS,GAAG,GAAG,EACf,GAAG,KAAK,EACT,EACD,GAAG;IAEH,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IACjD,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IAEnD,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE;QAC7C,MAAM,IAAI,GAAa,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;YACvB,IAAI,QAAQ,CAAC,EAAE,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;;gBAC5B,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrB,CAAC;QACD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IAChD,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEtB,MAAM,UAAU,GAAG,CAAC,IAAuB,EAAE,CAAS,EAAE,EAAE;QACxD,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QACpB,MAAM,MAAM,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IACvD,MAAM,aAAa,GAAG,UAAU,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IAE1D,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,EAAE;QAClC,MAAM,IAAI,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC;;YAC7B,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QACvB,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,GAAG,EAAE;QACxB,MAAM,IAAI,GAA2B,EAAE,GAAG,QAAQ,EAAE,CAAC;QACrD,KAAK,MAAM,EAAE,IAAI,KAAK;YAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;QACxC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC,CAAC;IAEF,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAE/C,MAAM,UAAU,GAAG,CACjB,KAAa,EACb,KAAa,EACb,QAA2B,EAC3B,WAAmB,EACnB,cAAmC,EACnC,UAAmB,EACnB,EAAE,CAAC,CACH,MAAC,IAAI,IAAC,SAAS,EAAC,yDAAyD,aACvE,MAAC,IAAI,IAAC,SAAS,EAAC,8CAA8C,aAC5D,KAAC,IAAI,IAAC,SAAS,EAAC,uCAAuC,YAAE,KAAK,GAAQ,EACtE,MAAC,IAAI,IAAC,SAAS,EAAC,+BAA+B,aAC5C,KAAK,OAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,IAClC,IACF,EACP,KAAC,IAAI,IAAC,SAAS,EAAC,kCAAkC,YAChD,KAAC,SAAS,IACR,KAAK,EAAE,WAAW,EAClB,YAAY,EAAE,cAAc,EAC5B,WAAW,EAAE,iBAAiB,EAC9B,kBAAkB,EAAE,UAAU,KAAK,EAAE,EACrC,SAAS,EAAC,iFAAiF,EAC3F,oBAAoB,EAAE,wBAAwB,GAC9C,GACG,EACP,KAAC,QAAQ,IACP,IAAI,EAAE,QAAoB,EAC1B,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAC5B,KAAK,EAAE,EAAE,SAAS,EAAE,EACpB,kBAAkB,EAChB,KAAC,IAAI,IAAC,SAAS,EAAC,mBAAmB,YACjC,KAAC,IAAI,IAAC,SAAS,EAAC,+BAA+B,YAC5C,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,YAAY,GACpE,GACF,EAET,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CACxB,MAAC,SAAS,IACR,iBAAiB,EAAC,QAAQ,EAC1B,kBAAkB,EAAE,UAAU,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,EACpE,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAC/B,SAAS,EAAC,iEAAiE,aAE3E,KAAC,IAAI,IACH,SAAS,EAAE,EAAE,CACX,kDAAkD,EAClD,UAAU;gCACR,CAAC,CAAC,YAAY;gCACd,CAAC,CAAC,gDAAgD,CACrD,YAEA,UAAU,IAAI,CACb,KAAC,IAAI,IAAC,SAAS,EAAC,iCAAiC,YAAE,GAAG,GAAQ,CAC/D,GACI,EACP,KAAC,IAAI,IAAC,SAAS,EAAC,gCAAgC,EAAC,aAAa,EAAE,CAAC,YAC9D,IAAI,GACA,IACG,CACb,GACD,IACG,CACR,CAAC;IAEF,OAAO,CACL,MAAC,IAAI,IAAC,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,KAAM,KAAK,aACzD,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,KAAK,CAAC,EAGxF,MAAC,IAAI,IAAC,SAAS,EAAC,4CAA4C,aAC1D,KAAC,SAAS,IACR,iBAAiB,EAAC,QAAQ,EAC1B,kBAAkB,EAAC,sBAAsB,EACzC,QAAQ,EAAE,SAAS,CAAC,MAAM,KAAK,CAAC,EAChC,OAAO,EAAE,YAAY,EACrB,SAAS,EAAE,EAAE,CACX,gDAAgD,EAChD,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,YAAY,CACvC,YAED,KAAC,IAAI,IAAC,SAAS,EAAC,qCAAqC,kCAAoB,GAC/D,EACZ,KAAC,SAAS,IACR,iBAAiB,EAAC,QAAQ,EAC1B,kBAAkB,EAAC,0BAA0B,EAC7C,QAAQ,EAAE,UAAU,CAAC,MAAM,KAAK,CAAC,EACjC,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,EAAE,CACX,gDAAgD,EAChD,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,YAAY,CACxC,YAED,KAAC,IAAI,IAAC,SAAS,EAAC,qCAAqC,kCAAoB,GAC/D,IACP,EAEN,UAAU,CAAC,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAE,IAAI,CAAC,IACvF,CACR,CAAC;AACJ,CAAC,CACF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mihcm/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Universal primitives (Button, Input, ...) for React, Next.js, and React Native. Tailwind 4 + NativeWind v5.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -457,7 +457,7 @@
|
|
|
457
457
|
"tailwind-merge": "^3.6.0",
|
|
458
458
|
"tailwind-variants": "3.2.2",
|
|
459
459
|
"vaul": "1.1.2",
|
|
460
|
-
"@mihcm/theme": "0.2.
|
|
460
|
+
"@mihcm/theme": "0.2.10",
|
|
461
461
|
"@mihcm/tokens": "0.6.3"
|
|
462
462
|
},
|
|
463
463
|
"peerDependencies": {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { forwardRef, useMemo, useState } from 'react';
|
|
12
12
|
import { FlatList, Pressable, Text, TextInput, View, type ViewProps } from 'react-native';
|
|
13
|
+
import { NATIVE_PLACEHOLDER_COLOR } from '@mihcm/theme';
|
|
13
14
|
import { cn } from './internal/cn.js';
|
|
14
15
|
|
|
15
16
|
export type CheckboxGridSelection = Record<string, boolean>;
|
|
@@ -108,7 +109,7 @@ export const CheckboxGrid = forwardRef<View, CheckboxGridProps>(
|
|
|
108
109
|
placeholder={searchPlaceholder}
|
|
109
110
|
accessibilityLabel="Filter items"
|
|
110
111
|
className="rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground"
|
|
111
|
-
placeholderTextColor=
|
|
112
|
+
placeholderTextColor={NATIVE_PLACEHOLDER_COLOR}
|
|
112
113
|
/>
|
|
113
114
|
</View>
|
|
114
115
|
|
package/src/Combobox.native.tsx
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
View,
|
|
17
17
|
type ViewProps,
|
|
18
18
|
} from 'react-native';
|
|
19
|
+
import { NATIVE_PLACEHOLDER_COLOR } from '@mihcm/theme';
|
|
19
20
|
import { cn } from './internal/cn.js';
|
|
20
21
|
|
|
21
22
|
type ClassedViewProps = Omit<ViewProps, 'style'> & { className?: string };
|
|
@@ -119,7 +120,7 @@ export const Combobox = forwardRef<View, ComboboxProps>(
|
|
|
119
120
|
<View className="flex-row items-center border-b border-border px-3">
|
|
120
121
|
<TextInput
|
|
121
122
|
placeholder={searchPlaceholder}
|
|
122
|
-
placeholderTextColor=
|
|
123
|
+
placeholderTextColor={NATIVE_PLACEHOLDER_COLOR}
|
|
123
124
|
value={query}
|
|
124
125
|
onChangeText={setQuery}
|
|
125
126
|
className="flex-1 py-3 text-sm text-foreground"
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Column filter input for `@mihcm/ui/DataTable`.
|
|
5
|
+
*
|
|
6
|
+
* Three modes depending on the column's faceted metadata:
|
|
7
|
+
* 1. Faceted + number column → twin min/max inputs.
|
|
8
|
+
* 2. Faceted + string column → text input with sorted unique-values
|
|
9
|
+
* autosuggest dropdown that closes on outside click.
|
|
10
|
+
* 3. Default → plain text filter input.
|
|
11
|
+
*/
|
|
12
|
+
import { useEffect, useRef, useState } from 'react';
|
|
13
|
+
import type { Column } from '@tanstack/react-table';
|
|
14
|
+
import { Input } from '../Input.js';
|
|
15
|
+
|
|
16
|
+
interface ColumnFilterInputProps<TData> {
|
|
17
|
+
column: Column<TData, unknown>;
|
|
18
|
+
faceted: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function ColumnFilterInput<TData>({
|
|
22
|
+
column,
|
|
23
|
+
faceted,
|
|
24
|
+
}: ColumnFilterInputProps<TData>) {
|
|
25
|
+
const columnFilterValue = column.getFilterValue();
|
|
26
|
+
const [open, setOpen] = useState(false);
|
|
27
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (!open) return;
|
|
31
|
+
function handleClick(e: MouseEvent) {
|
|
32
|
+
if (ref.current && !ref.current.contains(e.target as Node)) {
|
|
33
|
+
setOpen(false);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
document.addEventListener('mousedown', handleClick);
|
|
37
|
+
return () => document.removeEventListener('mousedown', handleClick);
|
|
38
|
+
}, [open]);
|
|
39
|
+
|
|
40
|
+
if (faceted) {
|
|
41
|
+
const facetedMinMax = column.getFacetedMinMaxValues?.();
|
|
42
|
+
const isNumberColumn =
|
|
43
|
+
facetedMinMax !== undefined &&
|
|
44
|
+
facetedMinMax[0] !== undefined &&
|
|
45
|
+
typeof facetedMinMax[0] === 'number';
|
|
46
|
+
|
|
47
|
+
if (isNumberColumn) {
|
|
48
|
+
const [min, max] = facetedMinMax as [number, number];
|
|
49
|
+
const currentRange = (columnFilterValue as [number, number] | undefined) ?? [
|
|
50
|
+
undefined,
|
|
51
|
+
undefined,
|
|
52
|
+
];
|
|
53
|
+
return (
|
|
54
|
+
<div className="grid min-w-[10rem] grid-cols-2 gap-1">
|
|
55
|
+
<Input
|
|
56
|
+
type="number"
|
|
57
|
+
value={currentRange[0] ?? ''}
|
|
58
|
+
onChange={(e) => {
|
|
59
|
+
const val = e.target.value ? Number(e.target.value) : undefined;
|
|
60
|
+
column.setFilterValue((old: [number, number] | undefined) => [
|
|
61
|
+
val,
|
|
62
|
+
old?.[1],
|
|
63
|
+
]);
|
|
64
|
+
}}
|
|
65
|
+
placeholder={`Min (${min})`}
|
|
66
|
+
className="h-8 min-w-0 bg-background px-2 text-xs shadow-mi-input"
|
|
67
|
+
/>
|
|
68
|
+
<Input
|
|
69
|
+
type="number"
|
|
70
|
+
value={currentRange[1] ?? ''}
|
|
71
|
+
onChange={(e) => {
|
|
72
|
+
const val = e.target.value ? Number(e.target.value) : undefined;
|
|
73
|
+
column.setFilterValue((old: [number, number] | undefined) => [
|
|
74
|
+
old?.[0],
|
|
75
|
+
val,
|
|
76
|
+
]);
|
|
77
|
+
}}
|
|
78
|
+
placeholder={`Max (${max})`}
|
|
79
|
+
className="h-8 min-w-0 bg-background px-2 text-xs shadow-mi-input"
|
|
80
|
+
/>
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const uniqueValues = column.getFacetedUniqueValues?.();
|
|
86
|
+
if (uniqueValues && uniqueValues.size > 0) {
|
|
87
|
+
const sortedValues = Array.from(uniqueValues.keys())
|
|
88
|
+
.filter((v): v is string => typeof v === 'string')
|
|
89
|
+
.sort();
|
|
90
|
+
return (
|
|
91
|
+
<div ref={ref} className="relative">
|
|
92
|
+
<Input
|
|
93
|
+
type="text"
|
|
94
|
+
value={(columnFilterValue as string) ?? ''}
|
|
95
|
+
onChange={(e) => column.setFilterValue(e.target.value || undefined)}
|
|
96
|
+
onFocus={() => setOpen(true)}
|
|
97
|
+
placeholder="Filter..."
|
|
98
|
+
className="h-8 min-w-[8rem] bg-background px-2 text-xs shadow-mi-input"
|
|
99
|
+
/>
|
|
100
|
+
{open && sortedValues.length > 0 && (
|
|
101
|
+
<div className="absolute left-0 top-full z-50 mt-1 max-h-40 min-w-full overflow-y-auto rounded-md border border-border bg-card p-1 shadow-mi-modal">
|
|
102
|
+
{sortedValues.map((val) => (
|
|
103
|
+
<button
|
|
104
|
+
key={val}
|
|
105
|
+
type="button"
|
|
106
|
+
className="block w-full rounded px-2 py-1 text-left text-xs hover:bg-muted transition-colors duration-150"
|
|
107
|
+
onClick={() => {
|
|
108
|
+
column.setFilterValue(val);
|
|
109
|
+
setOpen(false);
|
|
110
|
+
}}
|
|
111
|
+
>
|
|
112
|
+
{val}{' '}
|
|
113
|
+
<span className="text-muted-foreground">
|
|
114
|
+
({uniqueValues.get(val)})
|
|
115
|
+
</span>
|
|
116
|
+
</button>
|
|
117
|
+
))}
|
|
118
|
+
</div>
|
|
119
|
+
)}
|
|
120
|
+
</div>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<Input
|
|
127
|
+
type="text"
|
|
128
|
+
value={(columnFilterValue as string) ?? ''}
|
|
129
|
+
onChange={(e) => column.setFilterValue(e.target.value || undefined)}
|
|
130
|
+
placeholder="Filter..."
|
|
131
|
+
className="h-8 min-w-[8rem] bg-background px-2 text-xs shadow-mi-input"
|
|
132
|
+
/>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* DataTable column header with sort affordance.
|
|
5
|
+
*
|
|
6
|
+
* Renders an a11y-friendly button with twin arrow indicators when the
|
|
7
|
+
* column is sortable; falls back to a plain `<span>` for unsortable
|
|
8
|
+
* columns. Internal helper of `@mihcm/ui/DataTable`.
|
|
9
|
+
*/
|
|
10
|
+
import type { Column } from '@tanstack/react-table';
|
|
11
|
+
import { cn } from '../internal/cn.js';
|
|
12
|
+
|
|
13
|
+
interface DataTableColumnHeaderProps<TData, TValue> {
|
|
14
|
+
column: Column<TData, TValue>;
|
|
15
|
+
title: string;
|
|
16
|
+
className?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function DataTableColumnHeader<TData, TValue>({
|
|
20
|
+
column,
|
|
21
|
+
title,
|
|
22
|
+
className,
|
|
23
|
+
}: DataTableColumnHeaderProps<TData, TValue>) {
|
|
24
|
+
if (!column.getCanSort()) {
|
|
25
|
+
return <span className={className}>{title}</span>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const sorted = column.getIsSorted();
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<button
|
|
32
|
+
type="button"
|
|
33
|
+
className={cn(
|
|
34
|
+
'inline-flex items-center gap-1 -ml-1 px-1 py-0.5 rounded-md',
|
|
35
|
+
'hover:bg-muted transition-colors duration-150',
|
|
36
|
+
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
|
|
37
|
+
className,
|
|
38
|
+
)}
|
|
39
|
+
onClick={column.getToggleSortingHandler()}
|
|
40
|
+
aria-label={`Sort by ${title}`}
|
|
41
|
+
>
|
|
42
|
+
{title}
|
|
43
|
+
<span className="inline-flex flex-col" aria-hidden="true">
|
|
44
|
+
<svg
|
|
45
|
+
viewBox="0 0 8 4"
|
|
46
|
+
className={cn(
|
|
47
|
+
'h-1.5 w-2 transition-transform duration-200',
|
|
48
|
+
sorted === 'asc' ? 'text-foreground' : 'text-muted-foreground/40',
|
|
49
|
+
)}
|
|
50
|
+
fill="currentColor"
|
|
51
|
+
>
|
|
52
|
+
<path d="M4 0L8 4H0z" />
|
|
53
|
+
</svg>
|
|
54
|
+
<svg
|
|
55
|
+
viewBox="0 0 8 4"
|
|
56
|
+
className={cn(
|
|
57
|
+
'h-1.5 w-2 transition-transform duration-200',
|
|
58
|
+
sorted === 'desc' ? 'text-foreground' : 'text-muted-foreground/40',
|
|
59
|
+
)}
|
|
60
|
+
fill="currentColor"
|
|
61
|
+
>
|
|
62
|
+
<path d="M4 4L0 0h8z" />
|
|
63
|
+
</svg>
|
|
64
|
+
</span>
|
|
65
|
+
</button>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Column visibility toggle dropdown for `@mihcm/ui/DataTable`.
|
|
5
|
+
*
|
|
6
|
+
* Outside-click handling is local; the trigger uses the existing Button
|
|
7
|
+
* primitive and items are MiHCM Checkboxes so all theming tokens stay
|
|
8
|
+
* consistent with the rest of the data table chrome.
|
|
9
|
+
*/
|
|
10
|
+
import { useEffect, useRef, useState } from 'react';
|
|
11
|
+
import type { Table as TanStackTable } from '@tanstack/react-table';
|
|
12
|
+
import { Button } from '../Button.js';
|
|
13
|
+
import { Checkbox } from '../Checkbox.js';
|
|
14
|
+
|
|
15
|
+
interface ColumnVisibilityDropdownProps<TData> {
|
|
16
|
+
table: TanStackTable<TData>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function ColumnVisibilityDropdown<TData>({
|
|
20
|
+
table,
|
|
21
|
+
}: ColumnVisibilityDropdownProps<TData>) {
|
|
22
|
+
const [open, setOpen] = useState(false);
|
|
23
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!open) return;
|
|
27
|
+
function handleClick(e: MouseEvent) {
|
|
28
|
+
if (ref.current && !ref.current.contains(e.target as Node)) {
|
|
29
|
+
setOpen(false);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
document.addEventListener('mousedown', handleClick);
|
|
33
|
+
return () => document.removeEventListener('mousedown', handleClick);
|
|
34
|
+
}, [open]);
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<div ref={ref} className="relative">
|
|
38
|
+
<Button
|
|
39
|
+
variant="outline"
|
|
40
|
+
size="sm"
|
|
41
|
+
onClick={() => setOpen(!open)}
|
|
42
|
+
aria-expanded={open}
|
|
43
|
+
aria-haspopup="true"
|
|
44
|
+
>
|
|
45
|
+
<svg
|
|
46
|
+
aria-hidden="true"
|
|
47
|
+
viewBox="0 0 24 24"
|
|
48
|
+
fill="none"
|
|
49
|
+
stroke="currentColor"
|
|
50
|
+
strokeWidth={2}
|
|
51
|
+
className="h-4 w-4"
|
|
52
|
+
>
|
|
53
|
+
<path
|
|
54
|
+
strokeLinecap="round"
|
|
55
|
+
strokeLinejoin="round"
|
|
56
|
+
d="M10.5 6h9.75M10.5 6a1.5 1.5 0 11-3 0m3 0a1.5 1.5 0 10-3 0M3.75 6H7.5m3 12h9.75m-9.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-3.75 0H7.5m9-6h3.75m-3.75 0a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m-9.75 0h9.75"
|
|
57
|
+
/>
|
|
58
|
+
</svg>
|
|
59
|
+
Columns
|
|
60
|
+
</Button>
|
|
61
|
+
{open && (
|
|
62
|
+
<div className="absolute right-0 top-full z-50 mt-1 min-w-[10rem] rounded-lg border border-border bg-card p-1 shadow-md">
|
|
63
|
+
{table.getAllLeafColumns().map((column) => {
|
|
64
|
+
if (column.id === 'select' || column.id === 'expand') return null;
|
|
65
|
+
return (
|
|
66
|
+
<label
|
|
67
|
+
key={column.id}
|
|
68
|
+
className="flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-muted transition-colors duration-150"
|
|
69
|
+
>
|
|
70
|
+
<Checkbox
|
|
71
|
+
size="sm"
|
|
72
|
+
checked={column.getIsVisible()}
|
|
73
|
+
onCheckedChange={(v) => column.toggleVisibility(!!v)}
|
|
74
|
+
/>
|
|
75
|
+
<span className="capitalize">
|
|
76
|
+
{typeof column.columnDef.header === 'string'
|
|
77
|
+
? column.columnDef.header
|
|
78
|
+
: column.id}
|
|
79
|
+
</span>
|
|
80
|
+
</label>
|
|
81
|
+
);
|
|
82
|
+
})}
|
|
83
|
+
</div>
|
|
84
|
+
)}
|
|
85
|
+
</div>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pinning style helpers for `@mihcm/ui/DataTable`.
|
|
3
|
+
*
|
|
4
|
+
* Returns `React.CSSProperties` for `position: sticky` left/right pinning
|
|
5
|
+
* with a card background so pinned columns occlude the scrolling body.
|
|
6
|
+
*/
|
|
7
|
+
import type { Column, Header } from '@tanstack/react-table';
|
|
8
|
+
import type { CSSProperties } from 'react';
|
|
9
|
+
|
|
10
|
+
export function getPinningStyles<TData>(
|
|
11
|
+
header: Header<TData, unknown>,
|
|
12
|
+
columnPinnable: boolean,
|
|
13
|
+
): CSSProperties {
|
|
14
|
+
if (!columnPinnable) return {};
|
|
15
|
+
const isPinned = header.column.getIsPinned();
|
|
16
|
+
if (!isPinned) return {};
|
|
17
|
+
return {
|
|
18
|
+
position: 'sticky',
|
|
19
|
+
left: isPinned === 'left' ? `${header.getStart('left')}px` : undefined,
|
|
20
|
+
right: isPinned === 'right' ? `${header.getStart('right')}px` : undefined,
|
|
21
|
+
zIndex: 1,
|
|
22
|
+
backgroundColor: 'var(--color-card)',
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function getCellPinningStyles<TData>(
|
|
27
|
+
cell: { column: Column<TData, unknown> },
|
|
28
|
+
columnPinnable: boolean,
|
|
29
|
+
): CSSProperties {
|
|
30
|
+
if (!columnPinnable) return {};
|
|
31
|
+
const isPinned = cell.column.getIsPinned();
|
|
32
|
+
if (!isPinned) return {};
|
|
33
|
+
return {
|
|
34
|
+
position: 'sticky',
|
|
35
|
+
left: isPinned === 'left' ? `${cell.column.getStart('left')}px` : undefined,
|
|
36
|
+
right: isPinned === 'right' ? `${cell.column.getStart('right')}px` : undefined,
|
|
37
|
+
zIndex: 1,
|
|
38
|
+
backgroundColor: 'var(--color-card)',
|
|
39
|
+
};
|
|
40
|
+
}
|