@fayz-ai/ui 0.9.0 → 0.10.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/README.md +2 -2
- package/dist/analytics/AnalyticsCard.d.ts +10 -0
- package/dist/analytics/AnalyticsCard.d.ts.map +1 -0
- package/dist/analytics/AnalyticsControls.d.ts +18 -0
- package/dist/analytics/AnalyticsControls.d.ts.map +1 -0
- package/dist/analytics/AnalyticsGrid.d.ts +16 -0
- package/dist/analytics/AnalyticsGrid.d.ts.map +1 -0
- package/dist/analytics/context.d.ts +58 -0
- package/dist/analytics/context.d.ts.map +1 -0
- package/dist/analytics/derive.d.ts +81 -0
- package/dist/analytics/derive.d.ts.map +1 -0
- package/dist/analytics/index.d.ts +13 -0
- package/dist/analytics/index.d.ts.map +1 -0
- package/dist/analytics/range.d.ts +22 -0
- package/dist/analytics/range.d.ts.map +1 -0
- package/dist/{chunk-PVIB724L.js → chunk-22EVFMS3.js} +5 -3
- package/dist/chunk-22EVFMS3.js.map +1 -0
- package/dist/{chunk-G6OKZ7WL.js → chunk-6V5MGYXH.js} +13 -9
- package/dist/chunk-6V5MGYXH.js.map +1 -0
- package/dist/{chunk-KV3MHB6N.js → chunk-H63TOSQ7.js} +196 -53
- package/dist/chunk-H63TOSQ7.js.map +1 -0
- package/dist/{chunk-OUPJDGKE.js → chunk-I6CPKAOD.js} +134 -37
- package/dist/chunk-I6CPKAOD.js.map +1 -0
- package/dist/{chunk-YRVE4FOD.js → chunk-OKZ6WQB3.js} +3 -3
- package/dist/chunk-OKZ6WQB3.js.map +1 -0
- package/dist/{chunk-S5KNM4D2.js → chunk-SEIY2F5F.js} +235 -107
- package/dist/chunk-SEIY2F5F.js.map +1 -0
- package/dist/{chunk-75EFDLST.js → chunk-VAKWUUVC.js} +157 -6
- package/dist/chunk-VAKWUUVC.js.map +1 -0
- package/dist/dashboard/OnboardingWidget.d.ts +2 -14
- package/dist/dashboard/OnboardingWidget.d.ts.map +1 -1
- package/dist/dashboard/SidebarOnboarding.d.ts +28 -0
- package/dist/dashboard/SidebarOnboarding.d.ts.map +1 -0
- package/dist/dashboard/index.d.ts +2 -0
- package/dist/dashboard/index.d.ts.map +1 -1
- package/dist/dashboard/index.js +4 -4
- package/dist/dashboard/types.d.ts +18 -0
- package/dist/dashboard/types.d.ts.map +1 -1
- package/dist/dashboard/useOnboardingProgress.d.ts +28 -0
- package/dist/dashboard/useOnboardingProgress.d.ts.map +1 -0
- package/dist/icons.js +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +960 -14
- package/dist/index.js.map +1 -1
- package/dist/layout/AppShell.d.ts +14 -1
- package/dist/layout/AppShell.d.ts.map +1 -1
- package/dist/layout/ModulePage.d.ts +11 -2
- package/dist/layout/ModulePage.d.ts.map +1 -1
- package/dist/layout/Sidebar.d.ts +8 -1
- package/dist/layout/Sidebar.d.ts.map +1 -1
- package/dist/layout/index.js +4 -4
- package/dist/lib/cn.d.ts.map +1 -0
- package/dist/preset.d.ts +3 -0
- package/dist/preset.d.ts.map +1 -0
- package/dist/primitives/data-table.d.ts +19 -4
- package/dist/primitives/data-table.d.ts.map +1 -1
- package/dist/primitives/date-picker.d.ts +4 -2
- package/dist/primitives/date-picker.d.ts.map +1 -1
- package/dist/primitives/filter-chip.d.ts +26 -0
- package/dist/primitives/filter-chip.d.ts.map +1 -0
- package/dist/primitives/header-tabs.d.ts +32 -0
- package/dist/primitives/header-tabs.d.ts.map +1 -0
- package/dist/primitives/hint.d.ts +25 -0
- package/dist/primitives/hint.d.ts.map +1 -0
- package/dist/primitives/index.d.ts +7 -0
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +4 -4
- package/dist/primitives/list-view.d.ts +14 -1
- package/dist/primitives/list-view.d.ts.map +1 -1
- package/dist/primitives/page-header.d.ts +23 -0
- package/dist/primitives/page-header.d.ts.map +1 -0
- package/dist/primitives/stat-tiles.d.ts +30 -0
- package/dist/primitives/stat-tiles.d.ts.map +1 -0
- package/dist/primitives/switch.d.ts +11 -0
- package/dist/primitives/switch.d.ts.map +1 -0
- package/dist/stores/index.d.ts +1 -0
- package/dist/stores/index.d.ts.map +1 -1
- package/dist/stores/page-header.store.d.ts +69 -0
- package/dist/stores/page-header.store.d.ts.map +1 -0
- package/package.json +4 -13
- package/dist/chunk-75EFDLST.js.map +0 -1
- package/dist/chunk-G6OKZ7WL.js.map +0 -1
- package/dist/chunk-KV3MHB6N.js.map +0 -1
- package/dist/chunk-OUPJDGKE.js.map +0 -1
- package/dist/chunk-PVIB724L.js.map +0 -1
- package/dist/chunk-S5KNM4D2.js.map +0 -1
- package/dist/chunk-YRVE4FOD.js.map +0 -1
- package/dist/utils/cn.d.ts.map +0 -1
- package/src/dashboard/ChartWidget.tsx +0 -50
- package/src/dashboard/ChartWidgetInner.tsx +0 -83
- package/src/dashboard/DashboardCanvas.tsx +0 -210
- package/src/dashboard/DashboardCustomizeMenu.tsx +0 -53
- package/src/dashboard/DashboardGrid.tsx +0 -35
- package/src/dashboard/DashboardRange.tsx +0 -62
- package/src/dashboard/GoldCard.tsx +0 -38
- package/src/dashboard/KpiCard.tsx +0 -238
- package/src/dashboard/OnboardingWidget.tsx +0 -140
- package/src/dashboard/TableWidget.tsx +0 -51
- package/src/dashboard/define.ts +0 -53
- package/src/dashboard/icon.ts +0 -13
- package/src/dashboard/index.ts +0 -38
- package/src/dashboard/layout.ts +0 -50
- package/src/dashboard/preferences.ts +0 -71
- package/src/dashboard/types.ts +0 -41
- package/src/icons.ts +0 -66
- package/src/index.ts +0 -238
- package/src/layout/AppShell.tsx +0 -987
- package/src/layout/ContentSplit.tsx +0 -153
- package/src/layout/ModulePage.tsx +0 -466
- package/src/layout/PageTransition.tsx +0 -57
- package/src/layout/SaveBar.tsx +0 -247
- package/src/layout/Sidebar.tsx +0 -535
- package/src/layout/Topbar.tsx +0 -462
- package/src/layout/index.ts +0 -39
- package/src/layout/useCrossModuleBack.ts +0 -30
- package/src/primitives/Avatar.tsx +0 -48
- package/src/primitives/SearchCombobox.tsx +0 -216
- package/src/primitives/badge.tsx +0 -68
- package/src/primitives/breadcrumb.tsx +0 -43
- package/src/primitives/button.tsx +0 -60
- package/src/primitives/card.tsx +0 -79
- package/src/primitives/checkbox.tsx +0 -53
- package/src/primitives/confirm-dialog.tsx +0 -125
- package/src/primitives/currency-input.tsx +0 -121
- package/src/primitives/data-table.tsx +0 -160
- package/src/primitives/date-picker.tsx +0 -225
- package/src/primitives/dropdown.tsx +0 -196
- package/src/primitives/index.ts +0 -87
- package/src/primitives/input.tsx +0 -50
- package/src/primitives/list-view.tsx +0 -252
- package/src/primitives/markdown-editor.tsx +0 -75
- package/src/primitives/markdown.tsx +0 -169
- package/src/primitives/modal.tsx +0 -156
- package/src/primitives/phone-link.tsx +0 -138
- package/src/primitives/popover.tsx +0 -30
- package/src/primitives/search-select.tsx +0 -314
- package/src/primitives/segmented-control.tsx +0 -66
- package/src/primitives/select.tsx +0 -157
- package/src/primitives/separator.tsx +0 -29
- package/src/primitives/sheet.tsx +0 -181
- package/src/primitives/skeleton.tsx +0 -46
- package/src/primitives/tabs.tsx +0 -53
- package/src/primitives/time-picker.tsx +0 -148
- package/src/primitives/toast.tsx +0 -46
- package/src/primitives/tooltip.tsx +0 -28
- package/src/stores/index.ts +0 -10
- package/src/stores/layout.store.ts +0 -31
- package/src/stores/theme.store.ts +0 -457
- package/src/styles.css +0 -461
- package/src/tailwind.ts +0 -43
- package/src/theme/index.ts +0 -94
- package/src/theme/preset.ts +0 -209
- package/src/theme/presets.ts +0 -106
- package/src/utils/cn.ts +0 -6
- /package/dist/{utils → lib}/cn.d.ts +0 -0
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ export function Demo() {
|
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
## Part of the Fayz SDK
|
|
44
|
-
The presentation layer on top of `@fayz-ai/core`; the admin surface in `@fayz-ai/
|
|
44
|
+
The presentation layer on top of `@fayz-ai/core`; the admin surface in `@fayz-ai/admin` is built from it.
|
|
45
45
|
|
|
46
46
|
## Roadmap & contributing
|
|
47
|
-
Built and evolving in the open. See the [Fayz SDK roadmap](../../docs/ROADMAP.md#ui) for current gaps, missing features, and good first issues.
|
|
47
|
+
Built and evolving in the open. See the [Fayz SDK roadmap](../../docs/platform/ROADMAP.md#ui) for current gaps, missing features, and good first issues.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { AnalyticsCardDef } from '@fayz-ai/core';
|
|
3
|
+
export interface AnalyticsCardProps {
|
|
4
|
+
card: AnalyticsCardDef;
|
|
5
|
+
className?: string;
|
|
6
|
+
/** Hide the ↗ affordance (the viewer renders the same card full-size). */
|
|
7
|
+
hideOpen?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function AnalyticsCard({ card, className, hideOpen }: AnalyticsCardProps): React.JSX.Element;
|
|
10
|
+
//# sourceMappingURL=AnalyticsCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnalyticsCard.d.ts","sourceRoot":"","sources":["../../src/analytics/AnalyticsCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,gBAAgB,EAAkC,MAAM,eAAe,CAAA;AAwBrF,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,gBAAgB,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAoKD,wBAAgB,aAAa,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,kBAAkB,qBAuI9E"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { AnalyticsFilterDef } from '@fayz-ai/core';
|
|
3
|
+
export interface AnalyticsFilterPickerProps {
|
|
4
|
+
/** Every filter offered on this surface, from the cards in view. */
|
|
5
|
+
filters: AnalyticsFilterDef[];
|
|
6
|
+
}
|
|
7
|
+
export declare function AnalyticsFilterPicker({ filters }: AnalyticsFilterPickerProps): React.JSX.Element | null;
|
|
8
|
+
export interface AnalyticsControlsProps {
|
|
9
|
+
/** Filters offered in the picker — usually the union across visible cards. */
|
|
10
|
+
filters?: AnalyticsFilterDef[];
|
|
11
|
+
/** Hide the comparison control on surfaces where it means nothing. */
|
|
12
|
+
showCompare?: boolean;
|
|
13
|
+
/** Right-aligned extras (e.g. Export, New report). */
|
|
14
|
+
actions?: React.ReactNode;
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function AnalyticsControls({ filters, showCompare, actions, className }: AnalyticsControlsProps): React.JSX.Element;
|
|
18
|
+
//# sourceMappingURL=AnalyticsControls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnalyticsControls.d.ts","sourceRoot":"","sources":["../../src/analytics/AnalyticsControls.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,KAAK,EAAE,kBAAkB,EAAyB,MAAM,eAAe,CAAA;AA4I9E,MAAM,WAAW,0BAA0B;IACzC,oEAAoE;IACpE,OAAO,EAAE,kBAAkB,EAAE,CAAA;CAC9B;AAED,wBAAgB,qBAAqB,CAAC,EAAE,OAAO,EAAE,EAAE,0BAA0B,4BAwG5E;AAMD,MAAM,WAAW,sBAAsB;IACrC,8EAA8E;IAC9E,OAAO,CAAC,EAAE,kBAAkB,EAAE,CAAA;IAC9B,sEAAsE;IACtE,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,sDAAsD;IACtD,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,iBAAiB,CAAC,EAAE,OAAY,EAAE,WAAkB,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,sBAAsB,qBA2DjH"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { AnalyticsCardDef, AnalyticsFilterDef } from '@fayz-ai/core';
|
|
3
|
+
export interface AnalyticsGridProps {
|
|
4
|
+
cards: AnalyticsCardDef[];
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function AnalyticsGrid({ cards, className }: AnalyticsGridProps): React.JSX.Element;
|
|
8
|
+
/**
|
|
9
|
+
* Every filter offered by the cards on screen, de-duplicated by key.
|
|
10
|
+
*
|
|
11
|
+
* The control bar shows the union rather than the intersection: a filter that
|
|
12
|
+
* only narrows three of fourteen cards is still worth offering, and hiding it
|
|
13
|
+
* until every card supports it would leave the picker permanently empty.
|
|
14
|
+
*/
|
|
15
|
+
export declare function collectFilters(cards: AnalyticsCardDef[]): AnalyticsFilterDef[];
|
|
16
|
+
//# sourceMappingURL=AnalyticsGrid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnalyticsGrid.d.ts","sourceRoot":"","sources":["../../src/analytics/AnalyticsGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAmBzE,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,gBAAgB,EAAE,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,kBAAkB,qBAUrE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,kBAAkB,EAAE,CAQ9E"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import type { AnalyticsCardDef, AnalyticsProvider, AnalyticsQueryState, AnalyticsResult, AnalyticsCompare, AnalyticsDateRange } from '@fayz-ai/core';
|
|
3
|
+
import { type AnalyticsRangePreset } from './range';
|
|
4
|
+
import { type AnalyticsCurrency } from './derive';
|
|
5
|
+
export interface AnalyticsContextValue {
|
|
6
|
+
provider: AnalyticsProvider;
|
|
7
|
+
currency: AnalyticsCurrency;
|
|
8
|
+
state: AnalyticsQueryState;
|
|
9
|
+
preset: AnalyticsRangePreset;
|
|
10
|
+
setPreset: (preset: AnalyticsRangePreset) => void;
|
|
11
|
+
setDateRange: (range: AnalyticsDateRange) => void;
|
|
12
|
+
setCompare: (compare: AnalyticsCompare) => void;
|
|
13
|
+
setFilter: (key: string, value: unknown) => void;
|
|
14
|
+
setFilters: (filters: Record<string, unknown>) => void;
|
|
15
|
+
clearFilters: () => void;
|
|
16
|
+
setPage: (page: number) => void;
|
|
17
|
+
setPageSize: (pageSize: number) => void;
|
|
18
|
+
setSort: (sortBy: string, sortDir: 'asc' | 'desc') => void;
|
|
19
|
+
setSearch: (search: string) => void;
|
|
20
|
+
/** Bumped to force every mounted card to refetch (the ↻ button). */
|
|
21
|
+
refreshToken: number;
|
|
22
|
+
refresh: () => void;
|
|
23
|
+
/** Open a card as a full-page report. Absent ⇒ cards render no open affordance. */
|
|
24
|
+
onOpenCard?: (card: AnalyticsCardDef) => void;
|
|
25
|
+
/** "Created by" shown on cards a pack did not attribute individually. */
|
|
26
|
+
createdBy?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function useAnalyticsContext(): AnalyticsContextValue;
|
|
29
|
+
/** Non-throwing variant for primitives that may render outside a surface. */
|
|
30
|
+
export declare function useAnalyticsContextOptional(): AnalyticsContextValue | null;
|
|
31
|
+
export interface AnalyticsContextProviderProps {
|
|
32
|
+
provider: AnalyticsProvider;
|
|
33
|
+
currency?: AnalyticsCurrency;
|
|
34
|
+
defaultPreset?: AnalyticsRangePreset;
|
|
35
|
+
defaultCompare?: AnalyticsCompare;
|
|
36
|
+
defaultPageSize?: number;
|
|
37
|
+
onOpenCard?: (card: AnalyticsCardDef) => void;
|
|
38
|
+
createdBy?: string;
|
|
39
|
+
children: React.ReactNode;
|
|
40
|
+
}
|
|
41
|
+
export declare function AnalyticsContextProvider({ provider, currency, defaultPreset, defaultCompare, defaultPageSize, onOpenCard, createdBy, children, }: AnalyticsContextProviderProps): React.JSX.Element;
|
|
42
|
+
export interface UseAnalyticsCardResult {
|
|
43
|
+
result: AnalyticsResult | null;
|
|
44
|
+
/** Rollup with ratio measures resolved. Empty object until loaded. */
|
|
45
|
+
summary: Record<string, number>;
|
|
46
|
+
/** Same for the comparison window, or null when not comparing. */
|
|
47
|
+
previousSummary: Record<string, number> | null;
|
|
48
|
+
loading: boolean;
|
|
49
|
+
error: string | null;
|
|
50
|
+
/** The failure is a missing migration, not a bad card. */
|
|
51
|
+
engineMissing: boolean;
|
|
52
|
+
refetch: () => void;
|
|
53
|
+
}
|
|
54
|
+
export declare function useAnalyticsCard(card: AnalyticsCardDef, options?: {
|
|
55
|
+
stateOverride?: Partial<AnalyticsQueryState>;
|
|
56
|
+
enabled?: boolean;
|
|
57
|
+
}): UseAnalyticsCardResult;
|
|
58
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/analytics/context.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { AnalyticsCardDef, AnalyticsMeasure, AnalyticsResult, AnalyticsRow, AnalyticsSummary, AnalyticsFormat, AnalyticsGrain } from '@fayz-ai/core';
|
|
2
|
+
/**
|
|
3
|
+
* A readable message out of anything a data layer throws.
|
|
4
|
+
*
|
|
5
|
+
* Supabase/PostgREST reject with a PLAIN OBJECT ({message, details, hint,
|
|
6
|
+
* code}), not an Error — so the usual `err instanceof Error ? err.message :
|
|
7
|
+
* String(err)` renders the literal text "[object Object]" and hides the one
|
|
8
|
+
* piece of information the user needed.
|
|
9
|
+
*/
|
|
10
|
+
export declare function errorMessage(err: unknown): string;
|
|
11
|
+
/**
|
|
12
|
+
* True when the failure is "the analytics engine was never installed" rather
|
|
13
|
+
* than "this query is wrong" — a missing function, view or schema-cache entry.
|
|
14
|
+
* Worth separating: one is a migration a developer has to run, the other is a
|
|
15
|
+
* bug in a card, and telling a user "unknown error" for the first wastes an
|
|
16
|
+
* afternoon.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isEngineMissing(err: unknown): boolean;
|
|
19
|
+
export declare function num(value: unknown): number;
|
|
20
|
+
/**
|
|
21
|
+
* Resolve 'ratio' measures from the two measures they reference.
|
|
22
|
+
*
|
|
23
|
+
* Deliberately done HERE and not in SQL: a ratio aggregated per group and then
|
|
24
|
+
* averaged is not the ratio of the totals. Average order value over a week is
|
|
25
|
+
* sum(total)/count(orders) — not the mean of each day's average, which weights
|
|
26
|
+
* a 1-order Sunday the same as a 400-order Friday.
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveRatios(summary: AnalyticsSummary | undefined, measures?: AnalyticsMeasure[]): AnalyticsSummary;
|
|
29
|
+
/** Apply ratio measures to every row of a grouped result, not just the rollup. */
|
|
30
|
+
export declare function resolveRowRatios(rows: AnalyticsRow[], measures?: AnalyticsMeasure[]): AnalyticsRow[];
|
|
31
|
+
/**
|
|
32
|
+
* Percentage change, or null when there is no honest answer.
|
|
33
|
+
*
|
|
34
|
+
* Growth from zero is not "+100%" and not "+∞" — it is undefined, and printing
|
|
35
|
+
* a number there is how a dashboard claims a trend it cannot know. The card
|
|
36
|
+
* shows a dash instead.
|
|
37
|
+
*/
|
|
38
|
+
export declare function deltaPercent(current: number, previous: number | undefined | null): number | null;
|
|
39
|
+
export declare function trendOf(current: number, previous: number | undefined | null): 'up' | 'down' | 'neutral' | undefined;
|
|
40
|
+
export interface AnalyticsCurrency {
|
|
41
|
+
code?: string;
|
|
42
|
+
locale?: string;
|
|
43
|
+
symbol?: string;
|
|
44
|
+
}
|
|
45
|
+
/** Compact form for card headlines: 1.2K, 3.4M. */
|
|
46
|
+
export declare function formatCompact(value: number, locale?: string): string;
|
|
47
|
+
export declare function formatAnalyticsValue(value: unknown, format: AnalyticsFormat | undefined, currency?: AnalyticsCurrency, opts?: {
|
|
48
|
+
compact?: boolean;
|
|
49
|
+
}): string;
|
|
50
|
+
/** Durations are stored in HOURS (the read models emit hours_to_fulfillment). */
|
|
51
|
+
export declare function formatDuration(hours: number): string;
|
|
52
|
+
/** Axis tick for a bucketed timestamp — short, locale-aware, grain-aware. */
|
|
53
|
+
export declare function formatBucket(value: unknown, grain: AnalyticsGrain | undefined, locale?: string): string;
|
|
54
|
+
export interface BreakdownRow {
|
|
55
|
+
label: string;
|
|
56
|
+
value: number;
|
|
57
|
+
/** Share of the largest row (0–1), for the inline bar width. */
|
|
58
|
+
share: number;
|
|
59
|
+
formatted: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Rows for the "sessions by device type" style list. Bars are scaled to the
|
|
63
|
+
* LARGEST row, not to the total: with one dominant category every other bar
|
|
64
|
+
* collapses to an invisible sliver and the list stops communicating rank.
|
|
65
|
+
*/
|
|
66
|
+
export declare function toBreakdown(rows: AnalyticsRow[], categoryKey: string, measureKey: string, format: AnalyticsFormat | undefined, currency?: AnalyticsCurrency, limit?: number): BreakdownRow[];
|
|
67
|
+
/** The measures a card actually renders, in the order the viz asked for. */
|
|
68
|
+
export declare function vizMeasures(card: AnalyticsCardDef): AnalyticsMeasure[];
|
|
69
|
+
/** The dimension a chart/breakdown puts on its category axis. */
|
|
70
|
+
export declare function vizCategory(card: AnalyticsCardDef): import("@fayz-ai/core").AnalyticsDimension;
|
|
71
|
+
/**
|
|
72
|
+
* Chart rows with the category axis pre-formatted.
|
|
73
|
+
*
|
|
74
|
+
* recharts renders whatever string it is handed, so bucketed timestamps must be
|
|
75
|
+
* humanised BEFORE they reach it — otherwise the x-axis reads
|
|
76
|
+
* "2026-08-01T00:00:00+00:00".
|
|
77
|
+
*/
|
|
78
|
+
export declare function toChartData(rows: AnalyticsRow[], categoryKey: string, grain: AnalyticsGrain | undefined, locale?: string): Array<Record<string, string | number>>;
|
|
79
|
+
/** Sparkline series for a KPI: the headline measure across the time buckets. */
|
|
80
|
+
export declare function toSpark(result: AnalyticsResult | null, measureKey: string): number[] | undefined;
|
|
81
|
+
//# sourceMappingURL=derive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derive.d.ts","sourceRoot":"","sources":["../../src/analytics/derive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { AnalyticsContextProvider, useAnalyticsContext, useAnalyticsContextOptional, useAnalyticsCard } from './context';
|
|
2
|
+
export type { AnalyticsContextValue, AnalyticsContextProviderProps, UseAnalyticsCardResult } from './context';
|
|
3
|
+
export { AnalyticsCard } from './AnalyticsCard';
|
|
4
|
+
export type { AnalyticsCardProps } from './AnalyticsCard';
|
|
5
|
+
export { AnalyticsGrid, collectFilters } from './AnalyticsGrid';
|
|
6
|
+
export type { AnalyticsGridProps } from './AnalyticsGrid';
|
|
7
|
+
export { AnalyticsControls, AnalyticsFilterPicker } from './AnalyticsControls';
|
|
8
|
+
export type { AnalyticsControlsProps, AnalyticsFilterPickerProps } from './AnalyticsControls';
|
|
9
|
+
export { resolveRangePreset, comparisonRange, autoGrain, rangeLengthDays, toDayString, parseDay, } from './range';
|
|
10
|
+
export type { AnalyticsRangePreset } from './range';
|
|
11
|
+
export { num, resolveRatios, resolveRowRatios, deltaPercent, trendOf, errorMessage, isEngineMissing, formatAnalyticsValue, formatCompact, formatDuration, formatBucket, toBreakdown, toChartData, toSpark, vizMeasures, vizCategory, } from './derive';
|
|
12
|
+
export type { AnalyticsCurrency, BreakdownRow } from './derive';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AACxH,YAAY,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAA;AAC7G,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAC/C,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAC/D,YAAY,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAC9E,YAAY,EAAE,sBAAsB,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAA;AAC7F,OAAO,EACL,kBAAkB,EAAE,eAAe,EAAE,SAAS,EAAE,eAAe,EAAE,WAAW,EAAE,QAAQ,GACvF,MAAM,SAAS,CAAA;AAChB,YAAY,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AACnD,OAAO,EACL,GAAG,EAAE,aAAa,EAAE,gBAAgB,EAAE,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,eAAe,EAC1F,oBAAoB,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EACjE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,GAC5D,MAAM,UAAU,CAAA;AACjB,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { AnalyticsDateRange, AnalyticsCompare } from '@fayz-ai/core';
|
|
2
|
+
export type AnalyticsRangePreset = 'today' | 'yesterday' | 'last_7_days' | 'last_30_days' | 'last_90_days' | 'this_month' | 'last_month' | 'this_quarter' | 'this_year' | 'custom';
|
|
3
|
+
export declare function toDayString(d: Date): string;
|
|
4
|
+
export declare function parseDay(s: string): Date;
|
|
5
|
+
/** Inclusive whole-day count, so a single-day range compares against one day. */
|
|
6
|
+
export declare function rangeLengthDays(range: AnalyticsDateRange): number;
|
|
7
|
+
export declare function resolveRangePreset(preset: AnalyticsRangePreset, today?: Date): AnalyticsDateRange;
|
|
8
|
+
/**
|
|
9
|
+
* The window a range is compared against.
|
|
10
|
+
*
|
|
11
|
+
* 'previous_period' is the same NUMBER OF DAYS ending the day before `from`, so
|
|
12
|
+
* a 7-day range compares against the 7 days before it — never an overlapping
|
|
13
|
+
* window, which would double-count the boundary day in both halves.
|
|
14
|
+
*/
|
|
15
|
+
export declare function comparisonRange(range: AnalyticsDateRange, compare: AnalyticsCompare | undefined): AnalyticsDateRange | null;
|
|
16
|
+
/**
|
|
17
|
+
* Bucket size that keeps a chart readable across the chosen range: hours for a
|
|
18
|
+
* single day, days for a quarter, months for a year. A fixed 'day' grain turns
|
|
19
|
+
* a 12-month range into 365 unreadable ticks.
|
|
20
|
+
*/
|
|
21
|
+
export declare function autoGrain(range: AnalyticsDateRange): 'hour' | 'day' | 'week' | 'month';
|
|
22
|
+
//# sourceMappingURL=range.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"range.d.ts","sourceRoot":"","sources":["../../src/analytics/range.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAWzE,MAAM,MAAM,oBAAoB,GAC5B,OAAO,GAAG,WAAW,GAAG,aAAa,GAAG,cAAc,GAAG,cAAc,GACvE,YAAY,GAAG,YAAY,GAAG,cAAc,GAAG,WAAW,GAAG,QAAQ,CAAA;AAEzE,wBAAgB,WAAW,CAAC,CAAC,EAAE,IAAI,GAAG,MAAM,CAK3C;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAIxC;AAQD,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAIjE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,oBAAoB,EAAE,KAAK,OAAa,GAAG,kBAAkB,CAuCvG;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,kBAAkB,EACzB,OAAO,EAAE,gBAAgB,GAAG,SAAS,GACpC,kBAAkB,GAAG,IAAI,CAe3B;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAMtF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Zap, XCircle, X, Wrench, Workflow, Wheat, Warehouse, Wallet, UtensilsCrossed, Utensils, UsersRound, Users, UserX, UserPlus, UserCog, UserCheck, User, Truck, Trophy, TrendingUp, TrendingDown, TreePalm, ToggleLeft, Target, Tags, Tag, Star, Sparkles, SlidersHorizontal, Sigma, ShoppingCart, ShoppingBag, ShieldCheck, Shield, Settings, Send, Search, Ruler, RotateCcw, Repeat, Receipt, Radio, Puzzle, PlusCircle, Plus, Plug, PieChart, Phone, Percent, Pencil, PawPrint, PartyPopper, Palette, PackageCheck, Package, Newspaper, Music, MousePointerClick, MoreHorizontal, Mic, MessageSquare, MessageCircle, Megaphone, MapPin, Map, Mail, Lock, ListPlus, ListMusic, ListChecks, List, Link, LeafyGreen, Leaf, LayoutTemplate, LayoutDashboard, Layers, Landmark, Instagram, Inbox, Image, Home, Heart, Handshake, GraduationCap, Globe, FolderOpen, Flame, Filter, FileText, FileDown, FileCheck2, Eye, ExternalLink, Egg, DoorOpen, DollarSign, Dog, Disc3, CreditCard, Contact, Compass, Command, Clock3, Clock, ClipboardList, Clapperboard, CircleDollarSign, CircleCheck, Circle, ChevronsUpDown, ChefHat, CheckSquare, CheckCircle, Check, Cat, Camera, CalendarX, CalendarPlus, CalendarDays, CalendarClock, CalendarCheck2, CalendarCheck, Calendar, Building2, Briefcase, Boxes, Box, BookOpenCheck, BookOpen, Bike, Bell, BarChart3, Banknote, Ban, BadgeDollarSign, Award, ArrowUpRight, ArrowUpCircle, ArrowLeftRight, ArrowDownRight, ArrowDownCircle, Apple, AlertTriangle, Activity } from 'lucide-react';
|
|
1
|
+
import { Zap, XCircle, X, Wrench, Workflow, Wheat, Warehouse, Wallet, UtensilsCrossed, Utensils, UsersRound, Users, UserX, UserPlus, UserCog, UserCheck, User, Truck, Trophy, TrendingUp, TrendingDown, TreePalm, ToggleLeft, Target, Tags, Tag, Star, Sparkles, SlidersHorizontal, Sigma, ShoppingCart, ShoppingBag, ShieldCheck, Shield, Settings, Send, Search, Ruler, RotateCcw, Repeat, Receipt, Radio, Puzzle, PlusCircle, Plus, Plug, PieChart, Phone, Percent, Pencil, PawPrint, PartyPopper, Palette, PackageCheck, Package, Newspaper, Music, MousePointerClick, MoreHorizontal, Mic, MessageSquare, MessageCircle, Megaphone, MapPin, Map, Mail, Lock, ListPlus, ListMusic, ListChecks, List, Link, LeafyGreen, Leaf, LayoutTemplate, LayoutDashboard, Layers, Landmark, Instagram, Inbox, Images, Image, Home, FolderTree, Heart, Handshake, GraduationCap, Globe, FolderOpen, Flame, Filter, FileText, FileDown, FileCheck2, Eye, ExternalLink, Egg, DoorOpen, DollarSign, Dog, Disc3, CreditCard, Contact, Compass, Command, Clock3, Clock, ClipboardList, Clapperboard, CircleDollarSign, CircleCheck, Circle, ChevronsUpDown, ChefHat, CheckSquare, CheckCircle, Check, Cat, Camera, CalendarX, CalendarPlus, CalendarDays, CalendarClock, CalendarCheck2, CalendarCheck, Calendar, Building2, Briefcase, Boxes, Box, BookOpenCheck, BookOpen, Bike, Bell, BarChart3, Banknote, Ban, BadgeDollarSign, Award, ArrowUpRight, ArrowUpCircle, ArrowLeftRight, ArrowDownRight, ArrowDownCircle, Apple, AlertTriangle, Activity } from 'lucide-react';
|
|
2
2
|
|
|
3
3
|
// src/icons.ts
|
|
4
4
|
var registry = {
|
|
@@ -65,8 +65,10 @@ var registry = {
|
|
|
65
65
|
GraduationCap,
|
|
66
66
|
Handshake,
|
|
67
67
|
Heart,
|
|
68
|
+
FolderTree,
|
|
68
69
|
Home,
|
|
69
70
|
Image,
|
|
71
|
+
Images,
|
|
70
72
|
Inbox,
|
|
71
73
|
Instagram,
|
|
72
74
|
Landmark,
|
|
@@ -157,5 +159,5 @@ function getLucideIcon(name) {
|
|
|
157
159
|
var ICON_MAP = registry;
|
|
158
160
|
|
|
159
161
|
export { ICON_MAP, getLucideIcon, registerIcons };
|
|
160
|
-
//# sourceMappingURL=chunk-
|
|
161
|
-
//# sourceMappingURL=chunk-
|
|
162
|
+
//# sourceMappingURL=chunk-22EVFMS3.js.map
|
|
163
|
+
//# sourceMappingURL=chunk-22EVFMS3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/icons.ts"],"names":[],"mappings":"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","file":"chunk-22EVFMS3.js","sourcesContent":["import type { LucideIcon } from 'lucide-react'\nimport {\n Activity, AlertTriangle, Apple, ArrowDownCircle, ArrowDownRight, ArrowLeftRight, ArrowUpCircle, ArrowUpRight,\n Award, BadgeDollarSign, Ban, Banknote, BarChart3, Bell, Bike, BookOpen,\n BookOpenCheck, Box, Boxes, Briefcase, Building2, Calendar, CalendarCheck, CalendarCheck2,\n CalendarClock, CalendarDays, CalendarPlus, CalendarX, Camera, Cat, Check, CheckCircle,\n CheckSquare, ChefHat, ChevronsUpDown, Circle, CircleCheck, CircleDollarSign, Clapperboard, ClipboardList,\n Clock, Clock3, Command, Compass, Contact, CreditCard, Disc3, Dog,\n DollarSign, DoorOpen, Egg, ExternalLink, Eye, FileCheck2, FileDown,\n FileText, Filter, Flame, FolderOpen, Globe, GraduationCap, Handshake, Heart,\n FolderTree, Home, Image, Images, Inbox, Instagram, Landmark, Layers, LayoutDashboard, LayoutTemplate,\n Leaf, LeafyGreen, Link, List, ListChecks, ListMusic, ListPlus, Lock,\n Mail, Map, MapPin, Megaphone, MessageCircle, MessageSquare, Mic, MoreHorizontal,\n MousePointerClick, Music, Newspaper, Package, PackageCheck, Palette, PartyPopper, PawPrint,\n Pencil, Percent, Phone, PieChart, Plug, Plus, PlusCircle, Puzzle, Radio,\n Receipt, Repeat, RotateCcw, Ruler, Search, Send, Settings, Shield,\n ShieldCheck, ShoppingBag, ShoppingCart, Sigma, SlidersHorizontal, Sparkles, Star, Tag,\n Tags, Target, ToggleLeft, TreePalm, TrendingDown, TrendingUp, Trophy, Truck,\n User, UserCheck, UserCog, UserPlus, UserX, Users, UsersRound, Utensils,\n UtensilsCrossed, Wallet, Warehouse, Wheat, Workflow, Wrench, X, XCircle,\n Zap,\n} from 'lucide-react'\n\n// ---------------------------------------------------------------------------\n// Central lucide icon registry. The SDK's manifest-driven surfaces resolve\n// icons by string name; a namespace import (`import * as LucideIcons`) defeats\n// tree-shaking and drags all ~1,500 icons (~500 KB min) into every bundle, so\n// the SDK ships this curated set instead — the union of every icon name the\n// SDK, plugins, and app templates reference. Apps using names outside the set\n// call registerIcons({ Name: Component }) with their own named imports.\n// ---------------------------------------------------------------------------\n\nconst registry: Record<string, LucideIcon> = {\n Activity, AlertTriangle, Apple, ArrowDownCircle, ArrowDownRight, ArrowLeftRight, ArrowUpCircle, ArrowUpRight,\n Award, BadgeDollarSign, Ban, Banknote, BarChart3, Bell, Bike, BookOpen,\n BookOpenCheck, Box, Boxes, Briefcase, Building2, Calendar, CalendarCheck, CalendarCheck2,\n CalendarClock, CalendarDays, CalendarPlus, CalendarX, Camera, Cat, Check, CheckCircle,\n CheckSquare, ChefHat, ChevronsUpDown, Circle, CircleCheck, CircleDollarSign, Clapperboard, ClipboardList,\n Clock, Clock3, Command, Compass, Contact, CreditCard, Disc3, Dog,\n DollarSign, DoorOpen, Egg, ExternalLink, Eye, FileCheck2, FileDown,\n FileText, Filter, Flame, FolderOpen, Globe, GraduationCap, Handshake, Heart,\n FolderTree, Home, Image, Images, Inbox, Instagram, Landmark, Layers, LayoutDashboard, LayoutTemplate,\n Leaf, LeafyGreen, Link, List, ListChecks, ListMusic, ListPlus, Lock,\n Mail, Map, MapPin, Megaphone, MessageCircle, MessageSquare, Mic, MoreHorizontal,\n MousePointerClick, Music, Newspaper, Package, PackageCheck, Palette, PartyPopper, PawPrint,\n Pencil, Percent, Phone, PieChart, Plug, Plus, PlusCircle, Puzzle, Radio,\n Receipt, Repeat, RotateCcw, Ruler, Search, Send, Settings, Shield,\n ShieldCheck, ShoppingBag, ShoppingCart, Sigma, SlidersHorizontal, Sparkles, Star, Tag,\n Tags, Target, ToggleLeft, TreePalm, TrendingDown, TrendingUp, Trophy, Truck,\n User, UserCheck, UserCog, UserPlus, UserX, Users, UsersRound, Utensils,\n UtensilsCrossed, Wallet, Warehouse, Wheat, Workflow, Wrench, X, XCircle,\n Zap,\n}\n\n/** Add or override icons resolvable by string name (e.g. from app manifests). */\nexport function registerIcons(icons: Record<string, LucideIcon>): void {\n Object.assign(registry, icons)\n}\n\n/** Resolve a lucide icon by name; undefined when not registered. */\nexport function getLucideIcon(name: string): LucideIcon | undefined {\n return registry[name]\n}\n\n/** The registered icon map (live reference — do not mutate directly). */\nexport const ICON_MAP = registry\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { cn } from './chunk-
|
|
1
|
+
import { cn } from './chunk-OKZ6WQB3.js';
|
|
2
2
|
import * as React2 from 'react';
|
|
3
3
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
4
|
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
|
|
5
|
-
import { ChevronRight, Check, Circle,
|
|
5
|
+
import { ChevronRight, Check, Circle, ArrowDown, ArrowUp, ArrowUpDown } from 'lucide-react';
|
|
6
6
|
import { useReactTable, getSortedRowModel, getCoreRowModel, flexRender } from '@tanstack/react-table';
|
|
7
7
|
|
|
8
8
|
var Card = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
@@ -195,11 +195,12 @@ function DataTable({
|
|
|
195
195
|
emptyMessage = "No results.",
|
|
196
196
|
onRowClick,
|
|
197
197
|
variant = "card",
|
|
198
|
-
compact = false
|
|
198
|
+
compact = false,
|
|
199
|
+
sortIndicator
|
|
199
200
|
}) {
|
|
200
201
|
const isCard = variant === "card";
|
|
201
|
-
const wrapperCls = isCard ? "overflow-hidden rounded-lg border bg-card shadow-sm" : "overflow-hidden rounded-lg border";
|
|
202
|
-
const headerCls = isCard ? "border-b bg-muted/50" : "border-b bg-muted/30";
|
|
202
|
+
const wrapperCls = isCard ? "overflow-hidden rounded-lg border bg-card shadow-sm" : variant === "bare" ? "" : "overflow-hidden rounded-lg border";
|
|
203
|
+
const headerCls = isCard ? "border-b bg-muted/50" : variant === "bare" ? "border-b bg-muted/30 rounded-none" : "border-b bg-muted/30";
|
|
203
204
|
const thCls = compact ? "px-3 py-1.5 text-left text-[11px] font-medium text-muted-foreground" : "px-4 py-2.5 text-left font-medium text-muted-foreground";
|
|
204
205
|
const tdCls = compact ? "px-3 py-1.5 align-middle text-xs" : "px-4 py-3 align-middle";
|
|
205
206
|
const tableCls = compact ? "w-full text-xs min-w-max" : "w-full text-sm min-w-max";
|
|
@@ -226,7 +227,10 @@ function DataTable({
|
|
|
226
227
|
"th",
|
|
227
228
|
{
|
|
228
229
|
className: thCls,
|
|
229
|
-
children: header.isPlaceholder ? null : header.column.
|
|
230
|
+
children: header.isPlaceholder ? null : sortIndicator?.columnId === header.column.id ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1 text-foreground", children: [
|
|
231
|
+
flexRender(header.column.columnDef.header, header.getContext()),
|
|
232
|
+
sortIndicator.dir === "desc" ? /* @__PURE__ */ jsx(ArrowDown, { className: "h-3 w-3" }) : /* @__PURE__ */ jsx(ArrowUp, { className: "h-3 w-3" })
|
|
233
|
+
] }) : header.column.getCanSort() ? /* @__PURE__ */ jsxs(
|
|
230
234
|
"button",
|
|
231
235
|
{
|
|
232
236
|
className: "flex items-center gap-1 hover:text-foreground transition-colors",
|
|
@@ -252,7 +256,7 @@ function DataTable({
|
|
|
252
256
|
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx("td", { className: tdCls, children: flexRender(cell.column.columnDef.cell, cell.getContext()) }, cell.id))
|
|
253
257
|
},
|
|
254
258
|
row.id
|
|
255
|
-
)) : /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: columns.length, className: "h-
|
|
259
|
+
)) : /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", { colSpan: columns.length, className: "h-64 px-6 text-center align-middle text-muted-foreground", children: emptyMessage }) }) })
|
|
256
260
|
] }) }) });
|
|
257
261
|
}
|
|
258
262
|
function Skeleton({
|
|
@@ -329,5 +333,5 @@ function SegmentedControl({
|
|
|
329
333
|
}
|
|
330
334
|
|
|
331
335
|
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, DataTable, Dropdown, DropdownCheckboxItem, DropdownContent, DropdownGroup, DropdownItem, DropdownLabel, DropdownPortal, DropdownRadioGroup, DropdownRadioItem, DropdownSeparator, DropdownShortcut, DropdownSub, DropdownSubContent, DropdownSubTrigger, DropdownTrigger, SegmentedControl, Skeleton, TableSkeleton };
|
|
332
|
-
//# sourceMappingURL=chunk-
|
|
333
|
-
//# sourceMappingURL=chunk-
|
|
336
|
+
//# sourceMappingURL=chunk-6V5MGYXH.js.map
|
|
337
|
+
//# sourceMappingURL=chunk-6V5MGYXH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/primitives/card.tsx","../src/primitives/dropdown.tsx","../src/primitives/data-table.tsx","../src/primitives/skeleton.tsx","../src/primitives/segmented-control.tsx"],"names":["React","jsx","React3","jsxs","_"],"mappings":"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","file":"chunk-6V5MGYXH.js","sourcesContent":["import * as React from 'react'\n\nimport { cn } from '../lib/cn'\n\nconst Card = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n 'fayz-glass-surface rounded-card border bg-card text-card-foreground shadow-sm',\n className\n )}\n {...props}\n />\n))\nCard.displayName = 'Card'\n\nconst CardHeader = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex flex-col space-y-1 p-4', className)}\n {...props}\n />\n))\nCardHeader.displayName = 'CardHeader'\n\nconst CardTitle = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLHeadingElement>\n>(({ className, ...props }, ref) => (\n <h3\n ref={ref}\n className={cn(\n 'text-sm font-semibold leading-tight tracking-tight',\n className\n )}\n {...props}\n />\n))\nCardTitle.displayName = 'CardTitle'\n\nconst CardDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p\n ref={ref}\n className={cn('text-xs text-muted-foreground', className)}\n {...props}\n />\n))\nCardDescription.displayName = 'CardDescription'\n\nconst CardContent = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div ref={ref} className={cn('p-4 pt-0', className)} {...props} />\n))\nCardContent.displayName = 'CardContent'\n\nconst CardFooter = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex items-center p-4 pt-0', className)}\n {...props}\n />\n))\nCardFooter.displayName = 'CardFooter'\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }\n","import * as React from 'react'\nimport * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu'\nimport { Check, ChevronRight, Circle } from 'lucide-react'\n\nimport { cn } from '../lib/cn'\n\nconst Dropdown = DropdownMenuPrimitive.Root\n\nconst DropdownTrigger = DropdownMenuPrimitive.Trigger\n\nconst DropdownGroup = DropdownMenuPrimitive.Group\n\nconst DropdownPortal = DropdownMenuPrimitive.Portal\n\nconst DropdownSub = DropdownMenuPrimitive.Sub\n\nconst DropdownRadioGroup = DropdownMenuPrimitive.RadioGroup\n\nconst DropdownSubTrigger = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.SubTrigger>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean\n }\n>(({ className, inset, children, ...props }, ref) => (\n <DropdownMenuPrimitive.SubTrigger\n ref={ref}\n className={cn(\n 'flex cursor-default select-none items-center rounded-button px-2 py-1.5 text-sm outline-none focus:bg-muted data-[state=open]:bg-muted',\n inset && 'pl-8',\n className\n )}\n {...props}\n >\n {children}\n <ChevronRight className=\"ml-auto h-4 w-4\" />\n </DropdownMenuPrimitive.SubTrigger>\n))\nDropdownSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName\n\nconst DropdownSubContent = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.SubContent>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.SubContent>\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.SubContent\n ref={ref}\n className={cn(\n 'fayz-glass-surface z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n className\n )}\n {...props}\n />\n))\nDropdownSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName\n\nconst DropdownContent = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n 'fayz-glass-surface z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',\n className\n )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n))\nDropdownContent.displayName = DropdownMenuPrimitive.Content.displayName\n\nconst DropdownItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Item>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Item\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center rounded-button px-2 py-1.5 text-sm outline-none transition-colors focus:bg-muted data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n inset && 'pl-8',\n className\n )}\n {...props}\n />\n))\nDropdownItem.displayName = DropdownMenuPrimitive.Item.displayName\n\nconst DropdownCheckboxItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.CheckboxItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.CheckboxItem>\n>(({ className, children, checked, ...props }, ref) => (\n <DropdownMenuPrimitive.CheckboxItem\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center rounded-button py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-muted data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n className\n )}\n checked={checked}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <Check className=\"h-4 w-4\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n))\nDropdownCheckboxItem.displayName =\n DropdownMenuPrimitive.CheckboxItem.displayName\n\nconst DropdownRadioItem = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.RadioItem>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.RadioItem>\n>(({ className, children, ...props }, ref) => (\n <DropdownMenuPrimitive.RadioItem\n ref={ref}\n className={cn(\n 'relative flex cursor-default select-none items-center rounded-button py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-muted data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n className\n )}\n {...props}\n >\n <span className=\"absolute left-2 flex h-3.5 w-3.5 items-center justify-center\">\n <DropdownMenuPrimitive.ItemIndicator>\n <Circle className=\"h-2 w-2 fill-current\" />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n))\nDropdownRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName\n\nconst DropdownLabel = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Label>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean\n }\n>(({ className, inset, ...props }, ref) => (\n <DropdownMenuPrimitive.Label\n ref={ref}\n className={cn(\n 'px-2 py-1.5 text-sm font-semibold',\n inset && 'pl-8',\n className\n )}\n {...props}\n />\n))\nDropdownLabel.displayName = DropdownMenuPrimitive.Label.displayName\n\nconst DropdownSeparator = React.forwardRef<\n React.ElementRef<typeof DropdownMenuPrimitive.Separator>,\n React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>\n>(({ className, ...props }, ref) => (\n <DropdownMenuPrimitive.Separator\n ref={ref}\n className={cn('-mx-1 my-1 h-px bg-muted', className)}\n {...props}\n />\n))\nDropdownSeparator.displayName = DropdownMenuPrimitive.Separator.displayName\n\nconst DropdownShortcut = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLSpanElement>) => {\n return (\n <span\n className={cn('ml-auto text-xs tracking-widest opacity-60', className)}\n {...props}\n />\n )\n}\nDropdownShortcut.displayName = 'DropdownShortcut'\n\nexport {\n Dropdown,\n DropdownTrigger,\n DropdownContent,\n DropdownItem,\n DropdownCheckboxItem,\n DropdownRadioItem,\n DropdownLabel,\n DropdownSeparator,\n DropdownShortcut,\n DropdownGroup,\n DropdownPortal,\n DropdownSub,\n DropdownSubContent,\n DropdownSubTrigger,\n DropdownRadioGroup,\n}\n","import * as React from 'react'\nimport {\n type ColumnDef,\n type SortingState,\n flexRender,\n getCoreRowModel,\n getSortedRowModel,\n useReactTable,\n} from '@tanstack/react-table'\nimport { ArrowUpDown, ArrowUp, ArrowDown } from 'lucide-react'\n\nimport { cn } from '../lib/cn'\n\ninterface DataTableProps<TData, TValue> {\n columns: ColumnDef<TData, TValue>[]\n data: TData[]\n loading?: boolean\n skeletonRows?: number\n emptyMessage?: React.ReactNode\n onRowClick?: (row: TData) => void\n /** Visual variant: 'card' (white bg, card wrapper — default), 'flat'\n * (transparent bg, still bordered), or 'bare' — no wrapper chrome at all,\n * for a table already inside a card that owns the border and radius. */\n variant?: 'card' | 'flat' | 'bare'\n /** Compact mode: smaller padding and font size */\n compact?: boolean\n /**\n * Qual coluna está ordenada e para que lado, quando quem ordena é OUTRO\n * controle (o menu \"Ordenar\" da barra de ferramentas).\n *\n * Marca o cabeçalho sem torná-lo clicável: com a ordenação fora da tabela,\n * a seta é INFORMAÇÃO (\"está ordenado por isto, assim\"), não um botão. Sem\n * ela, mudar a ordem por um menu que fecha em seguida não deixava rastro\n * nenhum na tela.\n */\n sortIndicator?: { columnId: string; dir: 'asc' | 'desc' }\n}\n\nfunction DataTable<TData, TValue>({\n columns,\n data,\n loading = false,\n skeletonRows = 3,\n emptyMessage = 'No results.',\n onRowClick,\n variant = 'card',\n compact = false,\n sortIndicator,\n}: DataTableProps<TData, TValue>) {\n const isCard = variant === 'card'\n // Rounded box and scroll container must be SEPARATE elements: a scroll\n // container paints its content over its own border-radius, which squared\n // the corners the moment a row background met them.\n const wrapperCls = isCard\n ? 'overflow-hidden rounded-lg border bg-card shadow-sm'\n : variant === 'bare'\n ? ''\n : 'overflow-hidden rounded-lg border'\n // 'bare' sits below something else inside its parent card (a search/tools\n // toolbar), so its header is a mid-card band: no rounding, and it keeps the\n // card's own surface rather than starting a new tinted block.\n const headerCls = isCard\n ? 'border-b bg-muted/50'\n : variant === 'bare'\n ? 'border-b bg-muted/30 rounded-none'\n : 'border-b bg-muted/30'\n const thCls = compact ? 'px-3 py-1.5 text-left text-[11px] font-medium text-muted-foreground' : 'px-4 py-2.5 text-left font-medium text-muted-foreground'\n const tdCls = compact ? 'px-3 py-1.5 align-middle text-xs' : 'px-4 py-3 align-middle'\n const tableCls = compact ? 'w-full text-xs min-w-max' : 'w-full text-sm min-w-max'\n const rowHoverCls = isCard ? 'hover:bg-muted/30' : 'hover:bg-muted/20'\n const [sorting, setSorting] = React.useState<SortingState>([])\n\n const table = useReactTable({\n data,\n columns,\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: getSortedRowModel(),\n onSortingChange: setSorting,\n state: { sorting },\n })\n\n if (loading) {\n return (\n <div className={wrapperCls}>\n <div className=\"overflow-x-auto\">\n <table className={tableCls}>\n <thead>\n <tr className={headerCls}>\n {columns.map((_, i) => (\n <th key={i} className={thCls}>\n <div className=\"h-3.5 w-20 animate-pulse rounded bg-muted\" />\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {Array.from({ length: skeletonRows }).map((_, i) => (\n <tr key={i} className=\"border-b last:border-0\">\n {columns.map((_, j) => (\n <td key={j} className={tdCls}>\n <div className=\"h-3.5 w-full animate-pulse rounded bg-muted\" />\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n )\n }\n\n return (\n <div className={wrapperCls}>\n <div className=\"overflow-x-auto\">\n <table className={tableCls}>\n <thead>\n {table.getHeaderGroups().map((headerGroup) => (\n <tr key={headerGroup.id} className={headerCls}>\n {headerGroup.headers.map((header) => {\n const sorted = header.column.getIsSorted()\n return (\n <th\n key={header.id}\n className={thCls}\n >\n {header.isPlaceholder ? null : sortIndicator?.columnId === header.column.id ? (\n <span className=\"inline-flex items-center gap-1 text-foreground\">\n {flexRender(header.column.columnDef.header, header.getContext())}\n {sortIndicator.dir === 'desc'\n ? <ArrowDown className=\"h-3 w-3\" />\n : <ArrowUp className=\"h-3 w-3\" />}\n </span>\n ) : header.column.getCanSort() ? (\n <button\n className=\"flex items-center gap-1 hover:text-foreground transition-colors\"\n onClick={header.column.getToggleSortingHandler()}\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n {sorted === 'asc' ? (\n <ArrowUp className=\"h-3 w-3\" />\n ) : sorted === 'desc' ? (\n <ArrowDown className=\"h-3 w-3\" />\n ) : (\n <ArrowUpDown className=\"h-3 w-3 opacity-40\" />\n )}\n </button>\n ) : (\n flexRender(header.column.columnDef.header, header.getContext())\n )}\n </th>\n )\n })}\n </tr>\n ))}\n </thead>\n <tbody>\n {table.getRowModel().rows?.length ? (\n table.getRowModel().rows.map((row) => (\n <tr\n key={row.id}\n className={cn(\n `border-b last:border-0 transition-colors ${rowHoverCls}`,\n onRowClick && 'cursor-pointer'\n )}\n onClick={() => onRowClick?.(row.original)}\n >\n {row.getVisibleCells().map((cell) => (\n <td key={cell.id} className={tdCls}>\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </td>\n ))}\n </tr>\n ))\n ) : (\n <tr>\n {/* Height, not just padding: an empty table that collapses to one\n thin row reads as a rendering glitch rather than \"nothing\n here yet\". `emptyMessage` takes a node so callers can hand in\n a full empty state (icon, headline, create action). */}\n <td colSpan={columns.length} className=\"h-64 px-6 text-center align-middle text-muted-foreground\">\n {emptyMessage}\n </td>\n </tr>\n )}\n </tbody>\n </table>\n </div>\n </div>\n )\n}\n\nexport { DataTable, type DataTableProps }\n","import { cn } from '../lib/cn'\n\nfunction Skeleton({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n return (\n <div\n className={cn('animate-pulse rounded-md bg-muted', className)}\n {...props}\n />\n )\n}\n\n/**\n * Skeleton loader that mimics a table with rows and columns.\n * Drop-in replacement for \"Loading...\" text in list views.\n */\nfunction TableSkeleton({ columns = 4, rows = 2 }: { columns?: number; rows?: number }) {\n return (\n <div className=\"rounded-lg border overflow-hidden\">\n <div className=\"border-b bg-muted/30 flex gap-4 px-4 py-2.5\">\n {Array.from({ length: columns }).map((_, i) => (\n <Skeleton key={i} className=\"h-3 flex-1 rounded bg-muted-foreground/10\" />\n ))}\n </div>\n <div className=\"divide-y\">\n {Array.from({ length: rows }).map((_, r) => (\n <div key={r} className=\"flex items-center gap-4 px-4 py-3.5\">\n {Array.from({ length: columns }).map((_, c) => (\n <Skeleton\n key={c}\n className={cn(\n 'h-3 rounded',\n c === 0 ? 'flex-[2]' : 'flex-1',\n )}\n />\n ))}\n </div>\n ))}\n </div>\n </div>\n )\n}\n\nexport { Skeleton, TableSkeleton }\n","import * as React from 'react'\nimport { cn } from '../lib/cn'\n\nexport interface SegmentedOption<T extends string = string> {\n value: T\n label: React.ReactNode\n}\n\nexport interface SegmentedControlProps<T extends string = string> {\n /** Options as plain values (label = value) or `{ value, label }` objects. */\n options: ReadonlyArray<T | SegmentedOption<T>>\n value: T\n onChange: (value: T) => void\n /** Matches the equivalent Button heights: sm = 26px, md = 30px. */\n size?: 'sm' | 'md'\n className?: string\n 'aria-label'?: string\n}\n\nconst SIZE: Record<'sm' | 'md', { container: string; segment: string }> = {\n sm: { container: 'h-[26px]', segment: 'px-2.5 text-xs' },\n md: { container: 'h-[30px]', segment: 'px-3 text-sm' },\n}\n\n/**\n * Canonical segmented (pill) control — same chrome as Button (rounded-button\n * radius, hairline border + shadow-button bevel on a card surface). Use this for\n * any 7d/30d/90d-style toggle so every surface stays visually consistent instead\n * of hand-rolling a styled toggle group.\n */\nexport function SegmentedControl<T extends string = string>({\n options, value, onChange, size = 'sm', className, ...rest\n}: SegmentedControlProps<T>) {\n const items = options.map((o) => (typeof o === 'string' ? { value: o, label: o } : o)) as SegmentedOption<T>[]\n return (\n <div\n role=\"tablist\"\n aria-label={rest['aria-label']}\n className={cn(\n 'inline-flex items-center rounded-button border border-border bg-card p-0.5 shadow-button',\n SIZE[size].container,\n className,\n )}\n >\n {items.map((item) => {\n const active = item.value === value\n return (\n <button\n key={item.value}\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n onClick={() => onChange(item.value)}\n className={cn(\n 'flex h-full items-center rounded-button font-semibold transition-colors',\n SIZE[size].segment,\n active ? 'bg-foreground text-background' : 'text-muted-foreground hover:bg-muted/60',\n )}\n >\n {item.label}\n </button>\n )\n })}\n </div>\n )\n}\n"]}
|