@plexui/ui 0.7.36 → 0.7.38

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.
Files changed (35) hide show
  1. package/dist/es/components/DataTable/DataTable.js +59 -0
  2. package/dist/es/components/DataTable/DataTable.js.map +1 -0
  3. package/dist/es/components/DataTable/DataTable.module.css +94 -0
  4. package/dist/es/components/DataTable/DataTableColumnHeader.js +14 -0
  5. package/dist/es/components/DataTable/DataTableColumnHeader.js.map +1 -0
  6. package/dist/es/components/DataTable/DataTablePagination.js +14 -0
  7. package/dist/es/components/DataTable/DataTablePagination.js.map +1 -0
  8. package/dist/es/components/DataTable/index.js +4 -0
  9. package/dist/es/components/DataTable/index.js.map +1 -0
  10. package/dist/es/components/Icon/index.js +1 -0
  11. package/dist/es/components/Icon/index.js.map +1 -1
  12. package/dist/es/components/Icon/svg/Fingerprint.js +4 -0
  13. package/dist/es/components/Icon/svg/Fingerprint.js.map +1 -0
  14. package/dist/es/components/StatCard/StatCard.js +39 -0
  15. package/dist/es/components/StatCard/StatCard.js.map +1 -0
  16. package/dist/es/components/StatCard/StatCard.module.css +234 -0
  17. package/dist/es/components/StatCard/index.js +2 -0
  18. package/dist/es/components/StatCard/index.js.map +1 -0
  19. package/dist/es/components/Table/Table.js +14 -0
  20. package/dist/es/components/Table/Table.js.map +1 -0
  21. package/dist/es/components/Table/Table.module.css +55 -0
  22. package/dist/es/components/Table/index.js +2 -0
  23. package/dist/es/components/Table/index.js.map +1 -0
  24. package/dist/es/styles/variables-components.css +65 -0
  25. package/dist/types/components/DataTable/DataTable.d.ts +45 -0
  26. package/dist/types/components/DataTable/DataTableColumnHeader.d.ts +7 -0
  27. package/dist/types/components/DataTable/DataTablePagination.d.ts +5 -0
  28. package/dist/types/components/DataTable/index.d.ts +4 -0
  29. package/dist/types/components/Icon/index.d.ts +1 -0
  30. package/dist/types/components/Icon/svg/Fingerprint.d.ts +3 -0
  31. package/dist/types/components/StatCard/StatCard.d.ts +64 -0
  32. package/dist/types/components/StatCard/index.d.ts +1 -0
  33. package/dist/types/components/Table/Table.d.ts +17 -0
  34. package/dist/types/components/Table/index.d.ts +1 -0
  35. package/package.json +2 -1
@@ -0,0 +1,234 @@
1
+ @layer components {.StatCard {
2
+ display: flex;
3
+ flex-direction: column;
4
+ width: 100%;
5
+ min-width: 0;
6
+ padding: var(--stat-card-padding);
7
+ border-radius: var(--stat-card-radius);
8
+ background: var(--stat-card-background);
9
+ box-shadow: 0 0 0 1px var(--stat-card-border-color) inset;
10
+ font-size: var(--stat-card-label-font-size);
11
+ line-height: var(--font-text-sm-line-height);
12
+ }
13
+
14
+ .StatCard:where([data-size="sm"]) {
15
+ padding: var(--stat-card-sm-padding-block) var(--stat-card-sm-padding-inline);
16
+ }
17
+
18
+ .StatCard:where([data-size="sm"]) .Label {
19
+ font-size: var(--stat-card-sm-label-font-size);
20
+ line-height: var(--font-text-xs-line-height);
21
+ }
22
+
23
+ .StatCard:where([data-size="sm"]) .InfoIcon svg {
24
+ width: var(--stat-card-sm-info-icon-size);
25
+ height: var(--stat-card-sm-info-icon-size);
26
+ }
27
+
28
+ .StatCard:where([data-size="sm"]) .Value {
29
+ font-size: var(--stat-card-sm-value-font-size);
30
+ line-height: var(--font-heading-md-line-height);
31
+ letter-spacing: var(--font-heading-md-tracking);
32
+ }
33
+
34
+ .StatCard:where([data-size="sm"]) .Trend {
35
+ font-size: var(--stat-card-sm-trend-font-size);
36
+ line-height: var(--font-text-xs-line-height);
37
+ }
38
+
39
+ .StatCard:where([data-size="sm"]) .ValueRow {
40
+ margin-block-start: calc(var(--spacing) * 1.5);
41
+ }
42
+
43
+ .StatCard:where([data-size="sm"]) .Footer {
44
+ margin-block-start: calc(var(--spacing) * 0.5);
45
+ }
46
+
47
+ .StatCard:where([data-size="sm"]) .Description {
48
+ font-size: var(--stat-card-sm-description-font-size);
49
+ line-height: var(--font-text-xs-line-height);
50
+ }
51
+
52
+ .StatCard:where([data-size="sm"]) .TrendLabel {
53
+ font-size: var(--stat-card-sm-description-font-size);
54
+ line-height: var(--font-text-xs-line-height);
55
+ }
56
+
57
+ .StatCard:where([data-size="sm"]) .IconWrapper {
58
+ border-radius: var(--stat-card-sm-icon-wrapper-radius);
59
+ }
60
+
61
+ .StatCard:where([data-size="sm"]) .IconWrapper svg {
62
+ width: var(--stat-card-sm-icon-size);
63
+ height: var(--stat-card-sm-icon-size);
64
+ }
65
+
66
+ .StatCard:where([data-size="sm"]) .Body {
67
+ gap: calc(var(--spacing) * 2.5);
68
+ }
69
+
70
+ .StatCard:where([data-variant="accent"]) {
71
+ border-inline-start: var(--stat-card-accent-width) solid
72
+ var(--stat-card-accent-color, var(--color-background-primary-solid));
73
+ }
74
+
75
+ .StatCard:where([data-variant="accent"]):where([data-accent-color="primary"]) {
76
+ --stat-card-accent-color: var(--color-background-primary-solid);
77
+ }
78
+
79
+ .StatCard:where([data-variant="accent"]):where([data-accent-color="info"]) {
80
+ --stat-card-accent-color: var(--color-background-info-solid);
81
+ }
82
+
83
+ .StatCard:where([data-variant="accent"]):where([data-accent-color="success"]) {
84
+ --stat-card-accent-color: var(--color-background-success-solid);
85
+ }
86
+
87
+ .StatCard:where([data-variant="accent"]):where([data-accent-color="warning"]) {
88
+ --stat-card-accent-color: var(--color-background-warning-solid);
89
+ }
90
+
91
+ .StatCard:where([data-variant="accent"]):where([data-accent-color="danger"]) {
92
+ --stat-card-accent-color: var(--color-background-danger-solid);
93
+ }
94
+
95
+ .StatCard:where([data-variant="accent"]):where([data-accent-color="secondary"]) {
96
+ --stat-card-accent-color: var(--color-background-secondary-solid);
97
+ }
98
+
99
+ .StatCard:where([data-variant="accent"]):where([data-accent-color="discovery"]) {
100
+ --stat-card-accent-color: var(--color-background-discovery-solid);
101
+ }
102
+
103
+ .StatCard:where([data-variant="accent"]):where([data-accent-color="caution"]) {
104
+ --stat-card-accent-color: var(--color-background-caution-solid);
105
+ }.Header {
106
+ display: flex;
107
+ align-items: center;
108
+ justify-content: space-between;
109
+ gap: calc(var(--spacing) * 6);
110
+ }.LabelRow {
111
+ display: flex;
112
+ align-items: center;
113
+ gap: calc(var(--spacing) * 1);
114
+ min-width: 0;
115
+ }.Label {
116
+ min-width: 0;
117
+ overflow: hidden;
118
+ color: var(--stat-card-label-color);
119
+ font-size: var(--stat-card-label-font-size);
120
+ line-height: var(--font-text-sm-line-height);
121
+ text-overflow: ellipsis;
122
+ white-space: nowrap;
123
+ }.InfoIcon {
124
+ display: inline-flex;
125
+ flex-shrink: 0;
126
+ color: var(--color-text-tertiary);
127
+ cursor: help;
128
+ }
129
+
130
+ .InfoIcon svg {
131
+ width: var(--stat-card-info-icon-size);
132
+ height: var(--stat-card-info-icon-size);
133
+ }.Body {
134
+ display: flex;
135
+ align-items: flex-start;
136
+ gap: calc(var(--spacing) * 3);
137
+ }.Content {
138
+ flex: 1;
139
+ min-width: 0;
140
+ }
141
+
142
+ .Content .ValueRow {
143
+ margin-block-start: calc(var(--spacing) * 0.5);
144
+ }.IconWrapper {
145
+ display: flex;
146
+ align-items: center;
147
+ justify-content: center;
148
+ flex-shrink: 0;
149
+ align-self: stretch;
150
+ aspect-ratio: 1;
151
+ border-radius: var(--stat-card-icon-wrapper-radius);
152
+ background: var(--stat-card-icon-wrapper-background);
153
+ color: var(--stat-card-icon-color);
154
+ }
155
+
156
+ .IconWrapper svg {
157
+ width: var(--stat-card-icon-size);
158
+ height: var(--stat-card-icon-size);
159
+ }.HeaderEnd {
160
+ display: flex;
161
+ align-items: center;
162
+ gap: calc(var(--spacing) * 2);
163
+ flex-shrink: 0;
164
+ }.ValueRow {
165
+ display: flex;
166
+ align-items: baseline;
167
+ gap: calc(var(--spacing) * 2);
168
+ margin-block-start: calc(var(--spacing) * 3);
169
+ }.Value {
170
+ min-width: 0;
171
+ color: var(--stat-card-value-color);
172
+ font-size: var(--stat-card-value-font-size);
173
+ font-weight: var(--stat-card-value-font-weight);
174
+ line-height: var(--font-heading-xl-line-height);
175
+ letter-spacing: var(--font-heading-xl-tracking);
176
+ }.Trend {
177
+ display: inline-flex;
178
+ flex-shrink: 0;
179
+ font-size: var(--stat-card-trend-font-size);
180
+ font-weight: var(--stat-card-trend-font-weight);
181
+ line-height: var(--font-text-sm-line-height);
182
+ white-space: nowrap;
183
+ }.TrendPositive {
184
+ color: var(--stat-card-trend-positive-color);
185
+ }.TrendNegative {
186
+ color: var(--stat-card-trend-negative-color);
187
+ }.TrendNeutral {
188
+ color: var(--stat-card-trend-neutral-color);
189
+ }.Footer {
190
+ display: flex;
191
+ flex-direction: column;
192
+ gap: calc(var(--spacing) * 0.5);
193
+ margin-block-start: calc(var(--spacing) * 2);
194
+ }.TrendLabel {
195
+ color: var(--stat-card-description-color);
196
+ font-size: var(--stat-card-description-font-size);
197
+ font-weight: var(--font-weight-normal);
198
+ line-height: var(--font-text-sm-line-height);
199
+ }.Description {
200
+ color: var(--stat-card-description-color);
201
+ font-size: var(--stat-card-description-font-size);
202
+ line-height: var(--font-text-sm-line-height);
203
+ text-wrap: pretty;
204
+ }.Progress {
205
+ display: flex;
206
+ align-items: center;
207
+ gap: calc(var(--spacing) * 2);
208
+ margin-block-start: calc(var(--spacing) * 3);
209
+ }.ProgressTrack {
210
+ flex: 1;
211
+ height: var(--stat-card-progress-height);
212
+ border-radius: var(--stat-card-progress-radius);
213
+ background: var(--stat-card-progress-background);
214
+ overflow: hidden;
215
+ }.ProgressBar {
216
+ height: 100%;
217
+ border-radius: inherit;
218
+ background: var(--stat-card-progress-fill);
219
+ }.ProgressLabel {
220
+ color: var(--stat-card-description-color);
221
+ font-size: var(--stat-card-description-font-size);
222
+ line-height: var(--font-text-sm-line-height);
223
+ white-space: nowrap;
224
+ }.Sparkline {
225
+ margin-block-start: calc(var(--spacing) * 3);
226
+ color: var(--color-text-tertiary);
227
+ }
228
+
229
+ .Sparkline svg {
230
+ display: block;
231
+ width: 100%;
232
+ height: auto;
233
+ }
234
+ }
@@ -0,0 +1,2 @@
1
+ export { StatCard } from "./StatCard";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/StatCard/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAsB,MAAM,YAAY,CAAA","sourcesContent":["export { StatCard, type StatCardProps } from \"./StatCard\"\n"]}
@@ -0,0 +1,14 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import clsx from "clsx";
4
+ import {} from "react";
5
+ import s from "./Table.module.css";
6
+ export const Table = ({ className, ...props }) => (_jsx("div", { className: s.TableWrapper, children: _jsx("table", { className: clsx(s.Table, className), ...props }) }));
7
+ export const TableHeader = ({ className, ...props }) => (_jsx("thead", { className: clsx(s.TableHeader, className), ...props }));
8
+ export const TableBody = ({ className, ...props }) => (_jsx("tbody", { className: clsx(s.TableBody, className), ...props }));
9
+ export const TableFooter = ({ className, ...props }) => (_jsx("tfoot", { className: clsx(s.TableFooter, className), ...props }));
10
+ export const TableRow = ({ className, ...props }) => (_jsx("tr", { className: clsx(s.TableRow, className), ...props }));
11
+ export const TableHead = ({ className, ...props }) => (_jsx("th", { className: clsx(s.TableHead, className), ...props }));
12
+ export const TableCell = ({ className, ...props }) => (_jsx("td", { className: clsx(s.TableCell, className), ...props }));
13
+ export const TableCaption = ({ className, ...props }) => (_jsx("caption", { className: clsx(s.TableCaption, className), ...props }));
14
+ //# sourceMappingURL=Table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Table.js","sourceRoot":"","sources":["../../../../src/components/Table/Table.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAA8B,MAAM,OAAO,CAAA;AAClD,OAAO,CAAC,MAAM,oBAAoB,CAAA;AAGlC,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAc,EAAE,EAAE,CAAC,CAC5D,cAAK,SAAS,EAAE,CAAC,CAAC,YAAY,YAC5B,gBAAO,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,GACrD,CACP,CAAA;AAGD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAoB,EAAE,EAAE,CAAC,CACxE,gBAAO,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CAChE,CAAA;AAGD,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAkB,EAAE,EAAE,CAAC,CACpE,gBAAO,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CAC9D,CAAA;AAGD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAoB,EAAE,EAAE,CAAC,CACxE,gBAAO,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CAChE,CAAA;AAGD,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAiB,EAAE,EAAE,CAAC,CAClE,aAAI,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CAC1D,CAAA;AAGD,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAkB,EAAE,EAAE,CAAC,CACpE,aAAI,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CAC3D,CAAA;AAGD,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAkB,EAAE,EAAE,CAAC,CACpE,aAAI,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CAC3D,CAAA;AAGD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAqB,EAAE,EAAE,CAAC,CAC1E,kBAAS,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,YAAY,EAAE,SAAS,CAAC,KAAM,KAAK,GAAI,CACnE,CAAA","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { type ComponentPropsWithRef } from \"react\"\nimport s from \"./Table.module.css\"\n\nexport type TableProps = ComponentPropsWithRef<\"table\">\nexport const Table = ({ className, ...props }: TableProps) => (\n <div className={s.TableWrapper}>\n <table className={clsx(s.Table, className)} {...props} />\n </div>\n)\n\nexport type TableHeaderProps = ComponentPropsWithRef<\"thead\">\nexport const TableHeader = ({ className, ...props }: TableHeaderProps) => (\n <thead className={clsx(s.TableHeader, className)} {...props} />\n)\n\nexport type TableBodyProps = ComponentPropsWithRef<\"tbody\">\nexport const TableBody = ({ className, ...props }: TableBodyProps) => (\n <tbody className={clsx(s.TableBody, className)} {...props} />\n)\n\nexport type TableFooterProps = ComponentPropsWithRef<\"tfoot\">\nexport const TableFooter = ({ className, ...props }: TableFooterProps) => (\n <tfoot className={clsx(s.TableFooter, className)} {...props} />\n)\n\nexport type TableRowProps = ComponentPropsWithRef<\"tr\">\nexport const TableRow = ({ className, ...props }: TableRowProps) => (\n <tr className={clsx(s.TableRow, className)} {...props} />\n)\n\nexport type TableHeadProps = ComponentPropsWithRef<\"th\">\nexport const TableHead = ({ className, ...props }: TableHeadProps) => (\n <th className={clsx(s.TableHead, className)} {...props} />\n)\n\nexport type TableCellProps = ComponentPropsWithRef<\"td\">\nexport const TableCell = ({ className, ...props }: TableCellProps) => (\n <td className={clsx(s.TableCell, className)} {...props} />\n)\n\nexport type TableCaptionProps = ComponentPropsWithRef<\"caption\">\nexport const TableCaption = ({ className, ...props }: TableCaptionProps) => (\n <caption className={clsx(s.TableCaption, className)} {...props} />\n)\n"]}
@@ -0,0 +1,55 @@
1
+ @layer components {.TableWrapper {
2
+ position: relative;
3
+ width: 100%;
4
+ overflow: auto;
5
+ }.Table {
6
+ width: 100%;
7
+ border-collapse: collapse;
8
+ font-size: var(--table-cell-font-size);
9
+ line-height: var(--table-cell-line-height);
10
+ color: var(--table-cell-color);
11
+ text-align: left;
12
+ }.TableHeader {
13
+ background: var(--table-header-background);
14
+ }
15
+
16
+ .TableHeader :where(.TableRow) {
17
+ border-bottom: 1px solid var(--table-border-color);
18
+ }.TableHead {
19
+ height: var(--control-size-md);
20
+ padding: var(--table-cell-padding);
21
+ font-weight: var(--table-header-font-weight);
22
+ color: var(--table-header-color);
23
+ white-space: nowrap;
24
+ vertical-align: middle;
25
+ }
26
+ .TableBody :where(.TableRow) {
27
+ border-bottom: 1px solid var(--table-border-color);
28
+ transition: background-color 0.1s ease;
29
+ }
30
+
31
+ .TableBody :where(.TableRow):last-child {
32
+ border-bottom: none;
33
+ }
34
+
35
+ .TableBody :where(.TableRow):hover {
36
+ background-color: var(--table-row-hover-background);
37
+ }.TableRow {}.TableCell {
38
+ padding: var(--table-cell-padding);
39
+ vertical-align: middle;
40
+ }.TableFooter {
41
+ border-top: 1px solid var(--table-border-color);
42
+ background: var(--table-footer-background);
43
+ font-weight: var(--table-footer-font-weight);
44
+ }
45
+
46
+ .TableFooter :where(.TableRow:last-child) {
47
+ border-bottom: none;
48
+ }.TableCaption {
49
+ padding: var(--table-cell-padding);
50
+ font-size: var(--table-caption-font-size);
51
+ color: var(--table-caption-color);
52
+ caption-side: bottom;
53
+ text-align: left;
54
+ }
55
+ }
@@ -0,0 +1,2 @@
1
+ export { Table, TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell, TableCaption, } from "./Table";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/Table/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,WAAW,EACX,SAAS,EACT,WAAW,EACX,QAAQ,EACR,SAAS,EACT,SAAS,EACT,YAAY,GASb,MAAM,SAAS,CAAA","sourcesContent":["export {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableRow,\n TableHead,\n TableCell,\n TableCaption,\n type TableProps,\n type TableHeaderProps,\n type TableBodyProps,\n type TableFooterProps,\n type TableRowProps,\n type TableHeadProps,\n type TableCellProps,\n type TableCaptionProps,\n} from \"./Table\"\n"]}
@@ -390,6 +390,67 @@
390
390
  --sidebar-card-shadow-hover: var(--shadow-400), var(--shadow-hairline);
391
391
  --sidebar-card-active-scale: 0.98;
392
392
 
393
+ /* =============================================
394
+ StatCard
395
+ ============================================= */
396
+ --stat-card-padding: calc(var(--spacing) * 5);
397
+ --stat-card-radius: var(--radius-xl);
398
+ /* spacing is per-section: mt-3 (12px) label→value, mt-2 (8px) value→footer */
399
+ --stat-card-background: var(--color-surface);
400
+ --stat-card-border-color: var(--color-border);
401
+ --stat-card-label-font-size: var(--font-text-sm-size);
402
+ --stat-card-label-color: var(--color-text-secondary);
403
+ --stat-card-value-font-size: var(--font-heading-xl-size);
404
+ --stat-card-value-font-weight: var(--font-weight-semibold);
405
+ --stat-card-value-color: var(--color-text);
406
+ --stat-card-description-font-size: var(--font-text-sm-size);
407
+ --stat-card-description-color: var(--color-text-tertiary);
408
+ --stat-card-trend-font-size: var(--font-text-sm-size);
409
+ --stat-card-trend-font-weight: var(--font-weight-semibold);
410
+ --stat-card-trend-positive-color: var(--color-text-success-soft);
411
+ --stat-card-trend-negative-color: var(--color-text-danger-soft);
412
+ --stat-card-trend-neutral-color: var(--color-text-tertiary);
413
+ --stat-card-progress-height: 4px;
414
+ --stat-card-progress-radius: var(--radius-full);
415
+ --stat-card-progress-fill: var(--color-background-primary-solid);
416
+ --stat-card-icon-size: 24px;
417
+ --stat-card-icon-color: var(--color-text-primary);
418
+ /* label line-height (20) + gap spacing(0.5) (2) + value line-height (38) = 60 */
419
+ --stat-card-icon-wrapper-size: 60px;
420
+ --stat-card-icon-wrapper-radius: var(--radius-md);
421
+ --stat-card-icon-wrapper-background: var(--color-background-primary-soft-alpha);
422
+ --stat-card-accent-width: 3px;
423
+ --stat-card-info-icon-size: 16px;
424
+
425
+ /* sm size overrides */
426
+ --stat-card-sm-padding-block: calc(var(--spacing) * 3);
427
+ --stat-card-sm-padding-inline: calc(var(--spacing) * 4);
428
+ --stat-card-sm-label-font-size: var(--font-text-xs-size);
429
+ --stat-card-sm-value-font-size: var(--font-heading-md-size);
430
+ --stat-card-sm-trend-font-size: var(--font-text-xs-size);
431
+ --stat-card-sm-description-font-size: var(--font-text-xs-size);
432
+ --stat-card-sm-icon-size: 20px;
433
+ /* label line-height (18) + gap spacing(0.5) (2) + value line-height (26) = 46 */
434
+ --stat-card-sm-icon-wrapper-size: 46px;
435
+ --stat-card-sm-icon-wrapper-radius: var(--radius-sm);
436
+ --stat-card-sm-info-icon-size: 14px;
437
+
438
+ /* =============================================
439
+ Table
440
+ ============================================= */
441
+ --table-border-color: var(--color-border);
442
+ --table-header-background: transparent;
443
+ --table-header-font-weight: var(--font-weight-medium);
444
+ --table-header-color: var(--color-text-secondary);
445
+ --table-cell-padding: calc(var(--spacing) * 3) calc(var(--spacing) * 4);
446
+ --table-cell-font-size: var(--font-text-sm-size);
447
+ --table-cell-line-height: var(--font-text-sm-line-height);
448
+ --table-cell-color: var(--color-text);
449
+ --table-footer-background: transparent;
450
+ --table-footer-font-weight: var(--font-weight-medium);
451
+ --table-caption-font-size: var(--font-text-sm-size);
452
+ --table-caption-color: var(--color-text-tertiary);
453
+
393
454
  /* =============================================
394
455
  Skeleton
395
456
  ============================================= */
@@ -428,6 +489,8 @@
428
489
  --sidebar-menu-text: var(--gray-750);
429
490
  --sidebar-mobile-backdrop-color: rgb(0 0 0 / 15%);
430
491
  --sidebar-footer-shadow: 0 -2px 10px rgb(0 0 0 / 6%);
492
+ --stat-card-progress-background: var(--alpha-08);
493
+ --table-row-hover-background: var(--alpha-02);
431
494
  --skeleton-background: var(--alpha-08);
432
495
  }
433
496
  :where([data-theme="dark"]) {
@@ -463,6 +526,8 @@
463
526
  --sidebar-menu-text: var(--gray-850);
464
527
  --sidebar-mobile-backdrop-color: rgb(0 0 0 / 35%);
465
528
  --sidebar-footer-shadow: 0 -2px 10px rgb(0 0 0 / 35%);
529
+ --stat-card-progress-background: var(--alpha-12);
530
+ --table-row-hover-background: var(--alpha-04);
466
531
  --skeleton-background: var(--alpha-12);
467
532
  }
468
533
  }
@@ -0,0 +1,45 @@
1
+ import { type ColumnDef, type RowSelectionState, type SortingState, type VisibilityState } from "@tanstack/react-table";
2
+ import { type ReactNode } from "react";
3
+ export type DataTableProps<TData> = {
4
+ /** Column definitions following TanStack Table v8 ColumnDef API */
5
+ columns: ColumnDef<TData, unknown>[];
6
+ /** Data array to display */
7
+ data: TData[];
8
+ /** External search/filter string (controlled) */
9
+ globalFilter?: string;
10
+ /** Callback when global filter changes */
11
+ onGlobalFilterChange?: (value: string) => void;
12
+ /** Click handler for rows */
13
+ onRowClick?: (row: TData) => void;
14
+ /** Number of rows per page. Set to 0 or Infinity to disable pagination.
15
+ * @default 10
16
+ */
17
+ pageSize?: number;
18
+ /** Initial sorting state */
19
+ initialSorting?: SortingState;
20
+ /** Controlled column visibility */
21
+ columnVisibility?: VisibilityState;
22
+ /** Callback when column visibility changes */
23
+ onColumnVisibilityChange?: (visibility: VisibilityState) => void;
24
+ /** Enable row selection checkboxes
25
+ * @default false
26
+ */
27
+ enableRowSelection?: boolean;
28
+ /** Controlled row selection state */
29
+ rowSelection?: RowSelectionState;
30
+ /** Callback when row selection changes */
31
+ onRowSelectionChange?: (selection: RowSelectionState) => void;
32
+ /** Custom row ID accessor */
33
+ getRowId?: (row: TData) => string;
34
+ /** Message shown when there are no rows
35
+ * @default "No results."
36
+ */
37
+ emptyMessage?: ReactNode;
38
+ /** Class applied to the outermost wrapper */
39
+ className?: string;
40
+ /** Whether to show pagination controls. Auto-hidden when all rows fit.
41
+ * @default true
42
+ */
43
+ showPagination?: boolean;
44
+ };
45
+ export declare const DataTable: <TData>({ columns, data, globalFilter, onGlobalFilterChange, onRowClick, pageSize, initialSorting, columnVisibility, onColumnVisibilityChange, enableRowSelection, rowSelection, onRowSelectionChange, getRowId, emptyMessage, className, showPagination, }: DataTableProps<TData>) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { type Column } from "@tanstack/react-table";
2
+ export type DataTableColumnHeaderProps<TData, TValue> = {
3
+ column: Column<TData, TValue>;
4
+ title: string;
5
+ className?: string;
6
+ };
7
+ export declare const DataTableColumnHeader: <TData, TValue>({ column, title, className, }: DataTableColumnHeaderProps<TData, TValue>) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import { type Table } from "@tanstack/react-table";
2
+ export type DataTablePaginationProps<TData> = {
3
+ table: Table<TData>;
4
+ };
5
+ export declare const DataTablePagination: <TData>({ table }: DataTablePaginationProps<TData>) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,4 @@
1
+ export { DataTable, type DataTableProps } from "./DataTable";
2
+ export { DataTablePagination, type DataTablePaginationProps } from "./DataTablePagination";
3
+ export { DataTableColumnHeader, type DataTableColumnHeaderProps } from "./DataTableColumnHeader";
4
+ export type { ColumnDef, RowSelectionState, SortingState, VisibilityState, } from "@tanstack/react-table";
@@ -222,6 +222,7 @@ export { default as FileUpload } from "./svg/FileUpload";
222
222
  export { default as FileVideo } from "./svg/FileVideo";
223
223
  export { default as FileZip } from "./svg/FileZip";
224
224
  export { default as Filter } from "./svg/Filter";
225
+ export { default as Fingerprint } from "./svg/Fingerprint";
225
226
  export { default as Flag } from "./svg/Flag";
226
227
  export { default as Flask } from "./svg/Flask";
227
228
  export { default as FlaskFilled } from "./svg/FlaskFilled";
@@ -0,0 +1,3 @@
1
+ import type { SVGProps } from "react";
2
+ declare const Fingerprint: (props: SVGProps<SVGSVGElement>) => import("react/jsx-runtime").JSX.Element;
3
+ export default Fingerprint;
@@ -0,0 +1,64 @@
1
+ import { type ReactNode, type Ref } from "react";
2
+ export type StatCardProps = {
3
+ /** Label describing the metric */
4
+ label: string;
5
+ /** The primary metric value (e.g. "1,234" or "$50K") */
6
+ value: ReactNode;
7
+ /** Optional description or subtitle below the value */
8
+ description?: string;
9
+ /** Trend indicator with percentage change */
10
+ trend?: {
11
+ /** The percentage change value (e.g. 12.5 for +12.5%) */
12
+ value: number;
13
+ /** Optional label for the trend (e.g. "vs last month") */
14
+ label?: string;
15
+ };
16
+ /** When true, a positive trend is bad (red) and negative is good (green). Use for metrics like "Error Rate" or "Avg Completion Time". */
17
+ invertTrend?: boolean;
18
+ /** Icon displayed on the left side with a soft background */
19
+ icon?: ReactNode;
20
+ /** Optional ReactNode for a sparkline/chart rendered at the bottom */
21
+ sparkline?: ReactNode;
22
+ /** Progress value from 0 to 100. Shows a progress bar at the bottom. */
23
+ progress?: number;
24
+ /** Label displayed next to the progress bar */
25
+ progressLabel?: string;
26
+ /** Tooltip text — renders an (i) icon next to the label with a tooltip on hover */
27
+ tooltip?: string;
28
+ /**
29
+ * Where the trend indicator is positioned
30
+ * - `"value"` — next to the value (default)
31
+ * - `"header"` — right-aligned in the header row
32
+ * @default "value"
33
+ */
34
+ trendPosition?: "value" | "header";
35
+ /**
36
+ * Visual style of the trend indicator
37
+ * - `"text"` — plain colored text (default)
38
+ * - `"badge"` — wrapped in a Badge component
39
+ * @default "text"
40
+ */
41
+ trendVariant?: "text" | "badge";
42
+ /**
43
+ * Size of the card
44
+ * - `"default"` — standard dashboard card
45
+ * - `"sm"` — compact card for dense layouts
46
+ * @default "default"
47
+ */
48
+ size?: "default" | "sm";
49
+ /**
50
+ * Visual variant of the card
51
+ * @default "default"
52
+ */
53
+ variant?: "default" | "accent";
54
+ /**
55
+ * Accent border color for the "accent" variant
56
+ * @default "primary"
57
+ */
58
+ accentColor?: "primary" | "secondary" | "info" | "success" | "warning" | "danger" | "discovery" | "caution";
59
+ /** Class applied to the card container */
60
+ className?: string;
61
+ /** Ref applied to the card container */
62
+ ref?: Ref<HTMLDivElement>;
63
+ };
64
+ export declare const StatCard: ({ label, value, description, trend, invertTrend, icon, sparkline, progress, progressLabel, tooltip, trendPosition, trendVariant, size, variant, accentColor, className, ref, ...restProps }: StatCardProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { StatCard, type StatCardProps } from "./StatCard";
@@ -0,0 +1,17 @@
1
+ import { type ComponentPropsWithRef } from "react";
2
+ export type TableProps = ComponentPropsWithRef<"table">;
3
+ export declare const Table: ({ className, ...props }: TableProps) => import("react/jsx-runtime").JSX.Element;
4
+ export type TableHeaderProps = ComponentPropsWithRef<"thead">;
5
+ export declare const TableHeader: ({ className, ...props }: TableHeaderProps) => import("react/jsx-runtime").JSX.Element;
6
+ export type TableBodyProps = ComponentPropsWithRef<"tbody">;
7
+ export declare const TableBody: ({ className, ...props }: TableBodyProps) => import("react/jsx-runtime").JSX.Element;
8
+ export type TableFooterProps = ComponentPropsWithRef<"tfoot">;
9
+ export declare const TableFooter: ({ className, ...props }: TableFooterProps) => import("react/jsx-runtime").JSX.Element;
10
+ export type TableRowProps = ComponentPropsWithRef<"tr">;
11
+ export declare const TableRow: ({ className, ...props }: TableRowProps) => import("react/jsx-runtime").JSX.Element;
12
+ export type TableHeadProps = ComponentPropsWithRef<"th">;
13
+ export declare const TableHead: ({ className, ...props }: TableHeadProps) => import("react/jsx-runtime").JSX.Element;
14
+ export type TableCellProps = ComponentPropsWithRef<"td">;
15
+ export declare const TableCell: ({ className, ...props }: TableCellProps) => import("react/jsx-runtime").JSX.Element;
16
+ export type TableCaptionProps = ComponentPropsWithRef<"caption">;
17
+ export declare const TableCaption: ({ className, ...props }: TableCaptionProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export { Table, TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell, TableCaption, type TableProps, type TableHeaderProps, type TableBodyProps, type TableFooterProps, type TableRowProps, type TableHeadProps, type TableCellProps, type TableCaptionProps, } from "./Table";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plexui/ui",
3
- "version": "0.7.36",
3
+ "version": "0.7.38",
4
4
  "description": "Modern design system for building high-quality applications",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -79,6 +79,7 @@
79
79
  "tailwindcss": "^4.0.10"
80
80
  },
81
81
  "dependencies": {
82
+ "@tanstack/react-table": "^8.21.3",
82
83
  "clsx": "^2.1.1",
83
84
  "lodash": "4.17.21",
84
85
  "luxon": "3.7.1",