@arqel-dev/ui 0.8.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.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -0
  3. package/SKILL.md +116 -0
  4. package/dist/FormRenderer-BJBRIkfH.d.ts +70 -0
  5. package/dist/TableToolbar-POLdlSgC.d.ts +54 -0
  6. package/dist/WidgetWrapper-DUQy381N.d.ts +54 -0
  7. package/dist/action.d.ts +73 -0
  8. package/dist/action.js +1092 -0
  9. package/dist/action.js.map +1 -0
  10. package/dist/auth.d.ts +12 -0
  11. package/dist/auth.js +12 -0
  12. package/dist/auth.js.map +1 -0
  13. package/dist/flash.d.ts +37 -0
  14. package/dist/flash.js +106 -0
  15. package/dist/flash.js.map +1 -0
  16. package/dist/form.d.ts +61 -0
  17. package/dist/form.js +675 -0
  18. package/dist/form.js.map +1 -0
  19. package/dist/index.d.ts +24 -0
  20. package/dist/index.js +3708 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/pages.d.ts +73 -0
  23. package/dist/pages.js +1648 -0
  24. package/dist/pages.js.map +1 -0
  25. package/dist/palette.d.ts +28 -0
  26. package/dist/palette.js +285 -0
  27. package/dist/palette.js.map +1 -0
  28. package/dist/primitives.d.ts +76 -0
  29. package/dist/primitives.js +660 -0
  30. package/dist/primitives.js.map +1 -0
  31. package/dist/resource.d.ts +27 -0
  32. package/dist/resource.js +722 -0
  33. package/dist/resource.js.map +1 -0
  34. package/dist/shell.d.ts +50 -0
  35. package/dist/shell.js +1048 -0
  36. package/dist/shell.js.map +1 -0
  37. package/dist/table.d.ts +13 -0
  38. package/dist/table.js +620 -0
  39. package/dist/table.js.map +1 -0
  40. package/dist/utility.d.ts +62 -0
  41. package/dist/utility.js +106 -0
  42. package/dist/utility.js.map +1 -0
  43. package/dist/utils.d.ts +12 -0
  44. package/dist/utils.js +11 -0
  45. package/dist/utils.js.map +1 -0
  46. package/dist/widgets.d.ts +163 -0
  47. package/dist/widgets.js +677 -0
  48. package/dist/widgets.js.map +1 -0
  49. package/package.json +145 -0
  50. package/src/styles/globals.css +137 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Arqel Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # @arqel-dev/ui
2
+
3
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](../../LICENSE)
4
+ [![React](https://img.shields.io/badge/react-%5E19-61dafb.svg)](https://react.dev)
5
+ [![Status](https://img.shields.io/badge/status-pre--alpha-orange.svg)](#)
6
+
7
+ Structural React components for [Arqel](https://arqel.dev) admin panels.
8
+
9
+ ## Status
10
+
11
+ 🚧 **Pre-alpha** — UI-001..006 entregues (shell, table, form, action, flash, utility).
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ pnpm add @arqel-dev/ui @arqel-dev/react @arqel-dev/hooks @arqel-dev/types
17
+ pnpm add @inertiajs/react react react-dom @base-ui-components/react @tanstack/react-table lucide-react
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ```tsx
23
+ import '@arqel-dev/ui/styles.css';
24
+ import {
25
+ AppShell, Sidebar, Topbar, MainContent,
26
+ ResourceIndex, FormRenderer, ActionButton, FlashContainer,
27
+ } from '@arqel-dev/ui';
28
+ ```
29
+
30
+ ## What's inside
31
+
32
+ | Subpath | Components |
33
+ |-------------------|--------------------------------------------------------------------------------|
34
+ | `@arqel-dev/ui/shell` | `AppShell`, `Sidebar`, `Topbar`, `MainContent`, `Footer` |
35
+ | `@arqel-dev/ui/table` | `DataTable`, `TableCell`, `TableFilters`, `TablePagination`, `TableToolbar` |
36
+ | `@arqel-dev/ui/resource` | `ResourceIndex` |
37
+ | `@arqel-dev/ui/form` | `FormRenderer`, `FieldRenderer`, `FormSection`, `FormFieldset`, `FormGrid`, `FormTabs`, `FormActions`, `registerField` |
38
+ | `@arqel-dev/ui/action` | `Button`, `ActionButton`, `ActionMenu`, `ConfirmDialog`, `ActionFormModal` |
39
+ | `@arqel-dev/ui/auth` | `CanAccess` |
40
+ | `@arqel-dev/ui/flash` | `FlashContainer`, `FlashToast` |
41
+ | `@arqel-dev/ui/utility` | `Breadcrumbs`, `PageHeader`, `EmptyState`, `ErrorState`, `LoadingSkeleton` |
42
+ | `@arqel-dev/ui/utils` | `cn` |
43
+
44
+ ## Design tokens
45
+
46
+ Tokens são CSS vars em `oklch`, honram light/dark via `.dark` class flip aplicada pelo `<ThemeProvider>`:
47
+
48
+ ```css
49
+ --color-arqel-bg / -fg
50
+ --color-arqel-primary / -fg
51
+ --color-arqel-secondary / -fg
52
+ --color-arqel-destructive / -fg
53
+ --color-arqel-success / -warning
54
+ --color-arqel-muted / -fg
55
+ --color-arqel-border / -input / -ring
56
+ --radius-arqel / -sm / -lg
57
+ ```
58
+
59
+ ## Links
60
+
61
+ - [Documentação](https://arqel.dev/docs/ui) — em construção
62
+ - [PLANNING](../../PLANNING/08-fase-1-mvp.md) — tickets `UI-*`
package/SKILL.md ADDED
@@ -0,0 +1,116 @@
1
+ # SKILL.md — @arqel-dev/ui
2
+
3
+ > Contexto canónico para AI agents.
4
+
5
+ ## Purpose
6
+
7
+ `@arqel-dev/ui` é a "casca" estrutural do admin panel Arqel: shell (AppShell + Sidebar + Topbar), página de listagem (ResourceIndex + DataTable), formulário polimórfico (FormRenderer + FieldRenderer), botões e modais de Action, flash toasts, blocos de auth e utilitários (Breadcrumbs, PageHeader, EmptyState, ErrorState, LoadingSkeleton).
8
+
9
+ A partir da migração para shadcn, o pacote é construído sobre **shadcn (style `new-york`) + Radix UI**, integrado via `shadcn@4.6` CLI. Todas as primitivas oficiais vivem em `src/shadcn/` (gerado pela CLI; **read-only**) e são re-exportadas via `src/primitives/index.ts` + barrel top-level `src/index.ts`. Componentes custom (shell, table, form renderer, etc.) consomem essas primitivas; estado vive nos hooks/Inertia.
10
+
11
+ ## Status
12
+
13
+ **Stack base:**
14
+
15
+ - shadcn CLI v4.6, registry default `new-york`
16
+ - Radix UI (`radix-ui`) — substitui Base UI (`@base-ui-components/react`) em Dialog, DropdownMenu, Sheet, Tooltip, Select, Checkbox, Separator, Label
17
+ - `class-variance-authority` (cva) + `tailwind-merge` + `clsx` (via `cn()`)
18
+ - Tailwind v4 (`@import 'tailwindcss';`) + `tw-animate-css`
19
+ - `globals.css` agora usa **shadcn CSS vars** (`--background`, `--foreground`, `--primary`, `--secondary`, `--muted`, `--accent`, `--destructive`, `--border`, `--input`, `--ring`, `--card`, `--popover`, `--sidebar*`, `--radius`, `--chart-*`) com `@theme inline` bridge para mapear vars → tokens Tailwind. `.dark` override aplicado por `<ThemeProvider>` de `@arqel-dev/react`.
20
+
21
+ **Primitivas re-exportadas** (de `@arqel-dev/ui`):
22
+
23
+ - `Button` (cva) — variants `default | destructive | outline | secondary | ghost | link`; sizes `default | xs | sm | lg | icon | icon-xs | icon-sm | icon-lg`
24
+ - `Input`, `Textarea`, `Label`, `Checkbox`, `Separator`, `Skeleton`
25
+ - `Card` + `CardHeader`, `CardTitle`, `CardDescription`, `CardContent`, `CardFooter`, `CardAction`
26
+ - `Alert` + `AlertTitle`, `AlertDescription`
27
+ - `Badge` (cva) — variants `default | secondary | destructive | outline` (success/warning foram removidas)
28
+ - `Select` + `SelectTrigger`, `SelectContent`, `SelectItem`, `SelectValue`, `SelectGroup`, `SelectLabel`, `SelectSeparator`
29
+ - `Field` + `FieldGroup`, `FieldLabel`, `FieldError`, `FieldDescription`, `FieldSeparator`
30
+ - `Dialog`, `DropdownMenu`, `Sheet`, `Tooltip` (Radix-based)
31
+
32
+ **Blocks shadcn integrados:**
33
+
34
+ - `sidebar-07` — base do `<Sidebar>` / `<AppShell>` (com `<SidebarProvider>`, `<SidebarTrigger>`, `<SidebarInset>`, colapsável para ícone, persistência via cookie)
35
+ - `login-04` — split-screen card + hero illustration; usado por `LoginPage` em `@arqel-dev/auth`
36
+ - `signup-04` — análogo para `RegisterPage`
37
+
38
+ **Custom components (sobre as primitivas):**
39
+
40
+ - `<AppShell variant>`: 4 variants (`sidebar-left | sidebar-right | topbar-only | full-width`) com `SidebarProvider` interno
41
+ - `<Sidebar>` (block `sidebar-07` + collapsible icon + items via `useNavigation()` ou prop `items`, groups, badges, `aria-current="page"`)
42
+ - `<Topbar>`: brand + theme toggle + `SidebarTrigger` mobile + slots search/userMenu/tenantSwitcher
43
+ - `<MainContent>` (`SidebarInset` wrapper) com padding responsivo + `maxWidth` (`md..7xl | none`)
44
+ - `<DataTable>` (TanStack Table v8) — 9 cell renderers, seleção controlada, sticky header, `aria-sort`
45
+ - `<TableFilters>` / `<TablePagination>` / `<TableToolbar>` / `<ResourceIndex>`
46
+ - `<FormRenderer>` + `<FieldRenderer>` + `FieldRegistry` + `<FormSection>` / `<FormFieldset>` / `<FormGrid>` / `<FormTabs>` / `<FormActions>`
47
+ - `<ActionButton>` / `<ActionMenu>` (Radix DropdownMenu) / `<ConfirmDialog>` (Radix Dialog) / `<ActionFormModal>` (Radix Dialog hospedando `<FormRenderer>`)
48
+ - `<FlashContainer>` + `<FlashToast>` (4 posições, `role=alert/status`)
49
+ - `<Breadcrumbs>`, `<PageHeader>`, `<EmptyState>`, `<ErrorState>`, `<LoadingSkeleton>`
50
+ - `<CanAccess>` wrapper sobre `useCanAccess`
51
+
52
+ ## Key Contracts
53
+
54
+ ```tsx
55
+ import '@arqel-dev/ui/styles.css';
56
+ import {
57
+ AppShell, Sidebar, Topbar, MainContent, FlashContainer,
58
+ ResourceIndex, FormRenderer, ActionButton, CanAccess,
59
+ Breadcrumbs, PageHeader,
60
+ Button, Card, CardHeader, CardContent, Field, FieldLabel, Input,
61
+ } from '@arqel-dev/ui';
62
+
63
+ export default function UsersIndex(props: ResourceIndexProps<User>) {
64
+ return (
65
+ <AppShell sidebar={<Sidebar />} topbar={<Topbar />}>
66
+ <MainContent breadcrumbs={<Breadcrumbs />}>
67
+ <ResourceIndex
68
+ {...props}
69
+ rowActions={(record) => (
70
+ <ActionButton
71
+ action={editAction}
72
+ onInvoke={() => router.visit(`/admin/users/${record.id}/edit`)}
73
+ />
74
+ )}
75
+ />
76
+ </MainContent>
77
+ <FlashContainer />
78
+ </AppShell>
79
+ );
80
+ }
81
+ ```
82
+
83
+ ## Conventions
84
+
85
+ - **Subpath imports** preferidos para tree-shaking (`@arqel-dev/ui/shell`, `/table`, `/form`, `/action`, `/auth`, `/flash`, `/utility`, `/utils`, `/primitives`)
86
+ - CSS exposto como `@arqel-dev/ui/styles.css` — apps importam uma vez
87
+ - Design tokens via **shadcn CSS vars** (`--background`, `--primary`, `--sidebar`, `--radius`, etc.) — mapeados em `@theme inline`. Honorar tema = nunca hardcodar cor.
88
+ - `.dark` class flip aplicada por `<ThemeProvider>` de `@arqel-dev/react`
89
+ - Componentes presentational — callbacks lifted (sem fetch interno)
90
+ - `peerDependencies`: `radix-ui`, `@tanstack/react-table`, `lucide-react`, `@arqel-dev/{react,hooks}`
91
+ - Props com `undefined` explícito quando opcionais (`exactOptionalPropertyTypes: true`)
92
+
93
+ ## Anti-patterns
94
+
95
+ - ❌ **Editar `src/shadcn/*`** — gerado/atualizado pela `shadcn` CLI, ignorado pelo Biome lint. Para customizar uma primitiva: faz fork do componente shadcn para `src/<feature>/<Component>.tsx` próprio e re-exporta dali, mantendo `src/shadcn/` pristine.
96
+ - ❌ **Importar `@base-ui-components/react`** — substituído por `radix-ui`. Code legacy deve migrar.
97
+ - ❌ **Hardcode de cor** — usa CSS vars shadcn (`bg-primary`, `text-foreground`, etc.) para honrar tema
98
+ - ❌ **Bundle Tailwind no dist** — apps trazem o próprio Tailwind; expomos só os tokens via `globals.css`
99
+ - ❌ **Importar de `dist/`** — usa exports declarados (`@arqel-dev/ui` ou subpaths)
100
+ - ❌ **Estado local em ResourceIndex/DataTable** — sempre lifted via callbacks
101
+ - ❌ **Duplicar `useFlash({ onMessage })`** — um único `<FlashContainer>` no AppShell
102
+ - ❌ **Recriar variants `success`/`warning` no `Badge`** — foram removidas; usa `default`/`secondary`/`outline` ou compõe com `className`
103
+
104
+ ## Testing
105
+
106
+ - 70+ testes Vitest passando (jsdom + @testing-library/react + @testing-library/user-event)
107
+ - `pnpm test` watch, `pnpm exec vitest run --coverage` para relatório
108
+ - Coverage atual: ~67% global (barrels e overlays mobile do Sidebar baixam o número)
109
+
110
+ ## Related
111
+
112
+ - Tickets: [`PLANNING/08-fase-1-mvp.md`](../../PLANNING/08-fase-1-mvp.md) §UI-001..007
113
+ - API: [`PLANNING/06-api-react.md`](../../PLANNING/06-api-react.md) §8, §12
114
+ - shadcn registry: `components.json` na raiz do pacote
115
+ - Source: [`packages-js/ui/src/`](src/) — `shadcn/` (gerado), `primitives/` (barrel), `shell/`, `table/`, `form/`, `action/`, `auth/`, `flash/`, `utility/`
116
+ - Tests: [`packages-js/ui/tests/`](tests/)
@@ -0,0 +1,70 @@
1
+ import { ReactNode, ComponentType } from 'react';
2
+ import { FieldSchema } from '@arqel-dev/types/fields';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
4
+ import { FormSchema } from '@arqel-dev/types/forms';
5
+
6
+ /**
7
+ * `<FieldRenderer>` — renders a single field.
8
+ *
9
+ * Resolution order:
10
+ * 1. Component registered via `registerField(field.component)` (rich
11
+ * inputs from `@arqel-dev/fields`)
12
+ * 2. Native fallback dispatched by `field.type` (text/number/boolean/...)
13
+ *
14
+ * Errors come from `errors[name]` (Inertia or client). The component
15
+ * also honours `disabled` / `readonly` / `required` from the schema.
16
+ */
17
+
18
+ interface FieldRendererProps {
19
+ field: FieldSchema;
20
+ value: unknown;
21
+ onChange: (value: unknown) => void;
22
+ errors?: string[] | undefined;
23
+ disabled?: boolean | undefined;
24
+ className?: string | undefined;
25
+ inputId?: string | undefined;
26
+ describedBy?: string | undefined;
27
+ }
28
+ declare function FieldRenderer(props: FieldRendererProps): ReactNode;
29
+
30
+ /**
31
+ * `FieldRegistry` — name → React component mapping for FieldRenderer.
32
+ *
33
+ * `@arqel-dev/fields` (FIELDS-JS-*) calls `registerField` at module init to
34
+ * plug rich inputs in; until then FieldRenderer falls back to the
35
+ * native HTML primitives in `nativeFields.tsx`. Registration is global
36
+ * by design — apps can override Arqel defaults by re-registering with
37
+ * the same name.
38
+ */
39
+
40
+ type FieldComponent = ComponentType<FieldRendererProps>;
41
+ declare function registerField(name: string, component: FieldComponent): void;
42
+ declare function getFieldComponent(name: string): FieldComponent | undefined;
43
+ declare function unregisterField(name: string): void;
44
+ declare function getRegisteredFields(): string[];
45
+ /** Test-only helper. */
46
+ declare function clearFieldRegistry(): void;
47
+
48
+ interface FormActionsProps {
49
+ submitLabel?: string;
50
+ cancelLabel?: string;
51
+ onCancel?: () => void;
52
+ processing?: boolean;
53
+ disabled?: boolean;
54
+ extra?: ReactNode;
55
+ className?: string;
56
+ }
57
+ declare function FormActions({ submitLabel, cancelLabel, onCancel, processing, disabled, extra, className, }: FormActionsProps): react_jsx_runtime.JSX.Element;
58
+
59
+ interface FormRendererProps {
60
+ schema: FormSchema;
61
+ fields: FieldSchema[];
62
+ values: Record<string, unknown>;
63
+ errors?: Record<string, string[]>;
64
+ onChange: (name: string, value: unknown) => void;
65
+ disabled?: boolean;
66
+ className?: string;
67
+ }
68
+ declare function FormRenderer({ schema, fields, values, errors, onChange, disabled, className, }: FormRendererProps): react_jsx_runtime.JSX.Element;
69
+
70
+ export { type FieldComponent as F, FieldRenderer as a, type FieldRendererProps as b, FormActions as c, type FormActionsProps as d, FormRenderer as e, type FormRendererProps as f, clearFieldRegistry as g, getFieldComponent as h, getRegisteredFields as i, registerField as r, unregisterField as u };
@@ -0,0 +1,54 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ColumnSchema, TableSort, SortDirection, FilterSchema } from '@arqel-dev/types/tables';
3
+ import { ReactNode } from 'react';
4
+ import { PaginationMeta } from '@arqel-dev/types/resources';
5
+
6
+ type RowId = string | number;
7
+ interface DataTableRecord {
8
+ id: RowId;
9
+ [key: string]: unknown;
10
+ }
11
+ interface DataTableProps<TRecord extends DataTableRecord> {
12
+ columns: ColumnSchema[];
13
+ records: TRecord[];
14
+ enableSelection?: boolean;
15
+ selectedIds?: ReadonlyArray<RowId>;
16
+ onSelectionChange?: ((ids: RowId[]) => void) | undefined;
17
+ sort?: TableSort | null;
18
+ onSortChange?: ((column: string, direction: SortDirection) => void) | undefined;
19
+ rowActions?: ((record: TRecord) => ReactNode) | undefined;
20
+ loading?: boolean;
21
+ emptyState?: ReactNode;
22
+ className?: string;
23
+ }
24
+ declare function DataTable<TRecord extends DataTableRecord>({ columns, records, enableSelection, selectedIds, onSelectionChange, sort, onSortChange, rowActions, loading, emptyState, className, }: DataTableProps<TRecord>): react_jsx_runtime.JSX.Element;
25
+
26
+ interface TableFiltersProps {
27
+ filters: FilterSchema[];
28
+ values: Record<string, unknown>;
29
+ onChange: (name: string, value: unknown) => void;
30
+ onClearAll?: (() => void) | undefined;
31
+ className?: string | undefined;
32
+ }
33
+ declare function TableFilters({ filters, values, onChange, onClearAll, className, }: TableFiltersProps): react_jsx_runtime.JSX.Element | null;
34
+
35
+ interface TablePaginationProps {
36
+ meta: PaginationMeta;
37
+ onPageChange: (page: number) => void;
38
+ onPerPageChange?: ((perPage: number) => void) | undefined;
39
+ perPageOptions?: number[];
40
+ className?: string;
41
+ }
42
+ declare function TablePagination({ meta, onPageChange, onPerPageChange, perPageOptions, className, }: TablePaginationProps): react_jsx_runtime.JSX.Element;
43
+
44
+ interface TableToolbarProps {
45
+ search?: ReactNode;
46
+ filters?: ReactNode;
47
+ selectedCount?: number;
48
+ bulkActions?: ReactNode;
49
+ onClearSelection?: (() => void) | undefined;
50
+ className?: string;
51
+ }
52
+ declare function TableToolbar({ search, filters, selectedCount, bulkActions, onClearSelection, className, }: TableToolbarProps): react_jsx_runtime.JSX.Element;
53
+
54
+ export { DataTable as D, TableFilters as T, type DataTableProps as a, type DataTableRecord as b, type TableFiltersProps as c, TablePagination as d, type TablePaginationProps as e, TableToolbar as f, type TableToolbarProps as g };
@@ -0,0 +1,54 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+
4
+ /**
5
+ * `<StatCard>` — KPI / "big number" widget.
6
+ *
7
+ * Renders the payload produced by `Arqel\Widgets\StatWidget::data()`:
8
+ *
9
+ * {
10
+ * name, type: 'stat', heading?, description?,
11
+ * value, statDescription?, descriptionIcon?,
12
+ * color, icon?, chart?: number[], url?
13
+ * }
14
+ *
15
+ * Includes a tiny inline-SVG sparkline (no Recharts dep) when `chart`
16
+ * is set. ChartCard / TableCard (Recharts-based) ship in a separate
17
+ * cluster; this component is intentionally Recharts-free so the
18
+ * common "big number" case stays bundle-cheap.
19
+ */
20
+ type StatCardColor = 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info';
21
+ interface StatCardWidget {
22
+ name: string;
23
+ type: 'stat';
24
+ heading?: string;
25
+ description?: string;
26
+ value: string | number | null;
27
+ statDescription?: string | null;
28
+ descriptionIcon?: string | null;
29
+ color: StatCardColor;
30
+ icon?: string | null;
31
+ chart?: number[] | null;
32
+ url?: string | null;
33
+ }
34
+ interface StatCardProps {
35
+ widget: StatCardWidget;
36
+ className?: string | undefined;
37
+ columnSpan?: number | string | undefined;
38
+ }
39
+ declare function StatCard({ widget, className, columnSpan }: StatCardProps): react_jsx_runtime.JSX.Element;
40
+
41
+ interface WidgetWrapperProps {
42
+ heading?: string | undefined;
43
+ description?: string | undefined;
44
+ loading?: boolean | undefined;
45
+ error?: Error | null | undefined;
46
+ onRetry?: (() => void) | undefined;
47
+ /** Tailwind grid column span (number → `col-span-{n}`, or raw class). */
48
+ columnSpan?: number | string | undefined;
49
+ className?: string | undefined;
50
+ children: ReactNode;
51
+ }
52
+ declare function WidgetWrapper({ heading, description, loading, error, onRetry, columnSpan, className, children, }: WidgetWrapperProps): react_jsx_runtime.JSX.Element;
53
+
54
+ export { StatCard as S, WidgetWrapper as W, type StatCardColor as a, type StatCardProps as b, type StatCardWidget as c, type WidgetWrapperProps as d };
@@ -0,0 +1,73 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ActionSchema, ConfirmationConfig } from '@arqel-dev/types/actions';
3
+ import { FieldSchema } from '@arqel-dev/types/fields';
4
+ import * as React from 'react';
5
+ import { ComponentProps, ReactNode } from 'react';
6
+ import * as class_variance_authority_types from 'class-variance-authority/types';
7
+ import { VariantProps } from 'class-variance-authority';
8
+
9
+ declare const buttonVariants: (props?: ({
10
+ variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
11
+ size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
12
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
13
+ declare function Button({ className, variant, size, asChild, ...props }: React.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
14
+ asChild?: boolean;
15
+ }): react_jsx_runtime.JSX.Element;
16
+
17
+ /**
18
+ * Re-export shadcn (new-york) Button so existing consumers continue to
19
+ * import `Button` and `buttonVariants` from `@arqel-dev/ui/action`
20
+ * while the actual implementation lives in `src/shadcn/ui/button.tsx`.
21
+ *
22
+ * Variants exposed (shadcn): `default | destructive | outline |
23
+ * secondary | ghost | link`. Sizes: `default | xs | sm | lg | icon |
24
+ * icon-xs | icon-sm | icon-lg`.
25
+ */
26
+
27
+ type ButtonProps = ComponentProps<typeof Button>;
28
+
29
+ interface ActionButtonProps {
30
+ action: ActionSchema;
31
+ /** Field schemas for any form modal (resolved server-side from Action::form). */
32
+ formFields?: FieldSchema[];
33
+ onInvoke: (formValues?: Record<string, unknown>) => void;
34
+ processing?: boolean;
35
+ errors?: Record<string, string[]>;
36
+ size?: ButtonProps['size'];
37
+ className?: string;
38
+ }
39
+ declare function ActionButton({ action, formFields, onInvoke, processing, errors, size, className, }: ActionButtonProps): react_jsx_runtime.JSX.Element;
40
+
41
+ interface ActionFormModalProps {
42
+ open: boolean;
43
+ onOpenChange: (open: boolean) => void;
44
+ action: ActionSchema;
45
+ fields: FieldSchema[];
46
+ onSubmit: (values: Record<string, unknown>) => void;
47
+ processing?: boolean;
48
+ errors?: Record<string, string[]> | undefined;
49
+ initialValues?: Record<string, unknown>;
50
+ }
51
+ declare function ActionFormModal({ open, onOpenChange, action, fields, onSubmit, processing, errors, initialValues, }: ActionFormModalProps): react_jsx_runtime.JSX.Element;
52
+
53
+ interface ActionMenuProps {
54
+ actions: ActionSchema[];
55
+ formFieldsByAction?: Record<string, FieldSchema[]>;
56
+ onInvoke: (action: ActionSchema, formValues?: Record<string, unknown>) => void;
57
+ inlineThreshold?: number;
58
+ processing?: boolean;
59
+ trigger?: ReactNode;
60
+ className?: string;
61
+ }
62
+ declare function ActionMenu({ actions, formFieldsByAction, onInvoke, inlineThreshold, processing, trigger, className, }: ActionMenuProps): react_jsx_runtime.JSX.Element | null;
63
+
64
+ interface ConfirmDialogProps {
65
+ open: boolean;
66
+ onOpenChange: (open: boolean) => void;
67
+ config?: ConfirmationConfig | undefined;
68
+ onConfirm: () => void;
69
+ processing?: boolean;
70
+ }
71
+ declare function ConfirmDialog({ open, onOpenChange, config, onConfirm, processing, }: ConfirmDialogProps): react_jsx_runtime.JSX.Element;
72
+
73
+ export { ActionButton, type ActionButtonProps, ActionFormModal, type ActionFormModalProps, ActionMenu, type ActionMenuProps, Button, type ButtonProps, ConfirmDialog, type ConfirmDialogProps, buttonVariants };