laif-ds 0.2.61 → 0.2.62

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.
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- var e = {};
2
+ var e = { exports: {} };
3
3
  export {
4
- e as __exports
4
+ e as __module
5
5
  };
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- var e = { exports: {} };
2
+ var e = {};
3
3
  export {
4
- e as __module
4
+ e as __exports
5
5
  };
@@ -0,0 +1,271 @@
1
+ # AppDialog
2
+
3
+ ## Overview
4
+
5
+ Enhanced modal dialog component built on top of the base Dialog component. Provides a simplified API with built-in header, body, and footer sections, multiple size variants, and support for both controlled and uncontrolled usage patterns.
6
+
7
+ ---
8
+
9
+ ## Props
10
+
11
+ ### AppDialogProps
12
+
13
+ | Prop | Type | Default | Description |
14
+ | ------------------ | --------------------------------------------- | ------------ | --------------------------------------------- |
15
+ | `trigger` | `React.ReactNode` | `undefined` | Element that triggers the dialog on click. |
16
+ | `title` | `string \| React.ReactNode` | **required** | Dialog title displayed in the header. |
17
+ | `description` | `string \| React.ReactNode` | `undefined` | Dialog description displayed below the title. |
18
+ | `footer` | `React.ReactNode` | `undefined` | Footer content (typically action buttons). |
19
+ | `size` | `"sm" \| "default" \| "lg" \| "xl" \| "full"` | `"default"` | Size variant of the dialog. |
20
+ | `open` | `boolean` | `undefined` | Controlled open state. |
21
+ | `defaultOpen` | `boolean` | `undefined` | Default open state for uncontrolled usage. |
22
+ | `onOpenChange` | `(open: boolean) => void` | `undefined` | Callback when open state changes. |
23
+ | `disabled` | `boolean` | `false` | Whether to disable the trigger. |
24
+ | `asChild` | `boolean` | `false` | Whether to use asChild pattern for trigger. |
25
+ | `preventClose` | `"overlay" \| "all"` | `undefined` | Prevent closing via overlay or all methods. |
26
+ | `triggerClassName` | `string` | `undefined` | Additional className for the trigger wrapper. |
27
+ | `contentClassName` | `string` | `undefined` | Additional className for the dialog content. |
28
+ | `headerClassName` | `string` | `undefined` | Additional className for the dialog header. |
29
+ | `bodyClassName` | `string` | `undefined` | Additional className for the dialog body. |
30
+ | `footerClassName` | `string` | `undefined` | Additional className for the dialog footer. |
31
+
32
+ ### Size Variants
33
+
34
+ | Size | Dimensions |
35
+ | --------- | ---------------------------------- |
36
+ | `sm` | 5/12 width and height |
37
+ | `default` | 7/12 width and height |
38
+ | `lg` | 9/12 width and height |
39
+ | `xl` | 11/12 width and height |
40
+ | `full` | Full viewport (no rounded corners) |
41
+
42
+ ---
43
+
44
+ ## Exports
45
+
46
+ - **AppDialog**: Main dialog component.
47
+ - **AppDialogClose**: Re-export of DialogClose for closing the dialog programmatically.
48
+
49
+ ---
50
+
51
+ ## Behavior
52
+
53
+ - **Responsive**: On small screens (`max-sm`), the dialog takes full viewport.
54
+ - **Scrollable body**: Content in the body section scrolls if it exceeds available space.
55
+ - **Close button**: Built-in close button in the header (top-right).
56
+ - **Border separators**: Automatic borders between header/body and body/footer when content exists.
57
+ - **Focus management**: Inherits Radix Dialog focus trapping behavior.
58
+
59
+ ---
60
+
61
+ ## Examples
62
+
63
+ ### Basic Usage
64
+
65
+ ```tsx
66
+ import { AppDialog, Button } from "laif-ds";
67
+
68
+ export function BasicAppDialog() {
69
+ return (
70
+ <AppDialog
71
+ title="Dialog Title"
72
+ description="Optional description text."
73
+ trigger={<Button>Open Dialog</Button>}
74
+ asChild
75
+ >
76
+ <p>Dialog content goes here.</p>
77
+ </AppDialog>
78
+ );
79
+ }
80
+ ```
81
+
82
+ ### With Footer Actions
83
+
84
+ ```tsx
85
+ import { AppDialog, AppDialogClose, Button } from "laif-ds";
86
+
87
+ export function DialogWithFooter() {
88
+ return (
89
+ <AppDialog
90
+ title="Confirm Action"
91
+ description="Are you sure you want to proceed?"
92
+ trigger={<Button>Open Dialog</Button>}
93
+ footer={
94
+ <>
95
+ <AppDialogClose asChild>
96
+ <Button variant="outline">Cancel</Button>
97
+ </AppDialogClose>
98
+ <AppDialogClose asChild>
99
+ <Button>Confirm</Button>
100
+ </AppDialogClose>
101
+ </>
102
+ }
103
+ asChild
104
+ >
105
+ <p>This action cannot be undone.</p>
106
+ </AppDialog>
107
+ );
108
+ }
109
+ ```
110
+
111
+ ### Controlled Dialog
112
+
113
+ ```tsx
114
+ import { useState } from "react";
115
+ import { AppDialog, Button } from "laif-ds";
116
+
117
+ export function ControlledDialog() {
118
+ const [open, setOpen] = useState(false);
119
+
120
+ return (
121
+ <>
122
+ <Button onClick={() => setOpen(true)}>Open Dialog</Button>
123
+
124
+ <AppDialog
125
+ open={open}
126
+ onOpenChange={setOpen}
127
+ title="Controlled Dialog"
128
+ description="This dialog is controlled externally."
129
+ footer={<Button onClick={() => setOpen(false)}>Close</Button>}
130
+ >
131
+ <p>The dialog state is managed by the parent component.</p>
132
+ </AppDialog>
133
+ </>
134
+ );
135
+ }
136
+ ```
137
+
138
+ ### Size Variants
139
+
140
+ ```tsx
141
+ import { AppDialog, Button } from "laif-ds";
142
+
143
+ export function SizeVariants() {
144
+ return (
145
+ <div className="flex flex-wrap gap-4">
146
+ <AppDialog
147
+ title="Small Dialog"
148
+ size="sm"
149
+ trigger={<Button variant="outline">Small</Button>}
150
+ asChild
151
+ >
152
+ <p>Small dialog content.</p>
153
+ </AppDialog>
154
+
155
+ <AppDialog
156
+ title="Default Dialog"
157
+ size="default"
158
+ trigger={<Button variant="outline">Default</Button>}
159
+ asChild
160
+ >
161
+ <p>Default dialog content.</p>
162
+ </AppDialog>
163
+
164
+ <AppDialog
165
+ title="Large Dialog"
166
+ size="lg"
167
+ trigger={<Button variant="outline">Large</Button>}
168
+ asChild
169
+ >
170
+ <p>Large dialog content.</p>
171
+ </AppDialog>
172
+
173
+ <AppDialog
174
+ title="Extra Large Dialog"
175
+ size="xl"
176
+ trigger={<Button variant="outline">Extra Large</Button>}
177
+ asChild
178
+ >
179
+ <p>Extra large dialog content.</p>
180
+ </AppDialog>
181
+
182
+ <AppDialog
183
+ title="Full Dialog"
184
+ size="full"
185
+ trigger={<Button variant="outline">Full</Button>}
186
+ asChild
187
+ >
188
+ <p>Full screen dialog content.</p>
189
+ </AppDialog>
190
+ </div>
191
+ );
192
+ }
193
+ ```
194
+
195
+ ### With Form
196
+
197
+ ```tsx
198
+ import { useState } from "react";
199
+ import { AppDialog, AppDialogClose, Button, Input, Label } from "laif-ds";
200
+
201
+ export function DialogWithForm() {
202
+ const [open, setOpen] = useState(false);
203
+
204
+ const handleSubmit = (e: React.FormEvent) => {
205
+ e.preventDefault();
206
+ // Handle form submission
207
+ setOpen(false);
208
+ };
209
+
210
+ return (
211
+ <AppDialog
212
+ open={open}
213
+ onOpenChange={setOpen}
214
+ title="Edit Profile"
215
+ description="Update your profile information."
216
+ trigger={<Button>Edit Profile</Button>}
217
+ footer={
218
+ <>
219
+ <AppDialogClose asChild>
220
+ <Button variant="outline">Cancel</Button>
221
+ </AppDialogClose>
222
+ <Button type="submit" onClick={handleSubmit}>
223
+ Save
224
+ </Button>
225
+ </>
226
+ }
227
+ asChild
228
+ >
229
+ <form onSubmit={handleSubmit} className="space-y-4">
230
+ <div className="space-y-2">
231
+ <Label htmlFor="name">Name</Label>
232
+ <Input id="name" placeholder="Your name" />
233
+ </div>
234
+ <div className="space-y-2">
235
+ <Label htmlFor="email">Email</Label>
236
+ <Input id="email" type="email" placeholder="Your email" />
237
+ </div>
238
+ </form>
239
+ </AppDialog>
240
+ );
241
+ }
242
+ ```
243
+
244
+ ### Disabled Trigger
245
+
246
+ ```tsx
247
+ import { AppDialog, Button } from "laif-ds";
248
+
249
+ export function DisabledDialog() {
250
+ return (
251
+ <AppDialog
252
+ title="Disabled Dialog"
253
+ trigger={<Button disabled>Cannot Open</Button>}
254
+ disabled
255
+ asChild
256
+ >
257
+ <p>This content won't be accessible.</p>
258
+ </AppDialog>
259
+ );
260
+ }
261
+ ```
262
+
263
+ ---
264
+
265
+ ## Notes
266
+
267
+ - **Use `asChild`**: When passing a Button or other interactive element as trigger, set `asChild={true}` to avoid nesting buttons.
268
+ - **AppDialogClose**: Use this component to create buttons that close the dialog. Wrap with `asChild` when using custom elements.
269
+ - **Scrolling content**: The body section automatically handles overflow with scrolling.
270
+ - **Accessibility**: Title is rendered as an `h5` heading; description uses caption typography.
271
+ - **vs Dialog**: Use `AppDialog` for simpler use cases with consistent header/body/footer layout. Use base `Dialog` for more complex custom layouts.
@@ -46,6 +46,7 @@ type ColumnMeta = {
46
46
  | "list_single_select"
47
47
  | "list_multi_select"
48
48
  | "other";
49
+ headerLabel?: string;
49
50
  sortable?: boolean;
50
51
  filterable?: boolean;
51
52
  searchable?: boolean;
@@ -57,7 +58,7 @@ type ColumnMeta = {
57
58
  Notes:
58
59
 
59
60
  - `id` must match the field key used for filtering/sorting.
60
- - Header should be a simple string (not JSX) for proper filtering/sorting UI.
61
+ - If `header` is a `ReactNode` (e.g. `header: () => <div>Nome</div>`), set `meta.headerLabel` to provide a stable text label for sorting/filtering/column-visibility UI.
61
62
  - Filtering nested accessors (e.g., `"user.name"`) is not supported.
62
63
 
63
64
  ---
@@ -69,7 +70,9 @@ Notes:
69
70
  - **Operators**: Full operator set per type, including `eq_null`/`n_eq_null`, list operators (`array_overlap`, `n_array_overlap`), date/time before/after, checked/unchecked.
70
71
  - **Sorting**: Multi-column (limited by `maxSortedColumns`).
71
72
  - **Selection**: Integrated checkbox column when `checkable`.
72
- - **Column visibility**: Columns can start hidden via `initialState.columnVisibility` and be toggled from the eye icon popover in the toolbar.
73
+ - **Column visibility**: Columns can start hidden via `initialState.columnVisibility` and be toggled from the eye icon popover in the toolbar (supports drag-and-drop reordering).
74
+ - **Non-hideable columns**: Set `enableHiding: false` on a column to prevent it from being hidden.
75
+ - **Custom JSX headers**: Use `meta.headerLabel` when `header` is a ReactNode to provide a stable text label for menus.
73
76
  - **Pinning**: `meta.pinned` supports left/right pinned columns.
74
77
  - **Pagination**: Auto page size from container height; respects `disableAutoPageSize`.
75
78
  - **Loading**: Skeleton rows adapt to viewport height (no hardcoded length).
@@ -275,6 +278,74 @@ export function TableWithHiddenColumns({ data }: { data: Person[] }) {
275
278
  }
276
279
  ```
277
280
 
281
+ ### Non-hideable columns
282
+
283
+ If a column must always stay visible, set `enableHiding: false` on the column definition.
284
+
285
+ ```tsx
286
+ import type { ColumnDef } from "@tanstack/react-table";
287
+
288
+ const columns: ColumnDef<Person>[] = [
289
+ {
290
+ accessorKey: "name",
291
+ header: "Nome",
292
+ meta: { type: "string", sortable: true, searchable: true },
293
+ },
294
+ {
295
+ accessorKey: "email",
296
+ header: "Email",
297
+ enableHiding: false,
298
+ meta: { type: "string", searchable: true },
299
+ },
300
+ ];
301
+
302
+ export function TableWithNonHideableColumn({ data }: { data: Person[] }) {
303
+ return <DataTable columns={columns} data={data} />;
304
+ }
305
+ ```
306
+
307
+ ### Checkbox selection column (`checkable`)
308
+
309
+ When `checkable` is enabled, the DataTable adds a left checkbox column for row selection. This column is not hideable and not draggable in the column visibility popover.
310
+
311
+ ```tsx
312
+ export function TableCheckable({ data }: { data: Person[] }) {
313
+ return <DataTable columns={columns} data={data} checkable />;
314
+ }
315
+ ```
316
+
317
+ ### Drag-and-drop reordering
318
+
319
+ You can reorder columns by opening the column visibility popover (eye icon) and dragging items (grip icon). The order is managed internally via table `columnOrder` state.
320
+
321
+ ```tsx
322
+ export function TableWithReordering({ data }: { data: Person[] }) {
323
+ return <DataTable columns={columns} data={data} />;
324
+ }
325
+ ```
326
+
327
+ ### ReactNode headers + `meta.headerLabel`
328
+
329
+ If you use a `ReactNode` header, set `meta.headerLabel` so that sorting/filtering/visibility menus can show a readable label.
330
+
331
+ ```tsx
332
+ import type { ColumnDef } from "@tanstack/react-table";
333
+
334
+ const columns: ColumnDef<Person>[] = [
335
+ {
336
+ accessorKey: "name",
337
+ header: () => <div>Nome</div>,
338
+ meta: {
339
+ type: "string",
340
+ headerLabel: "Nome",
341
+ sortable: true,
342
+ filterable: true,
343
+ searchable: true,
344
+ },
345
+ },
346
+ ];
347
+ ```
348
+
278
349
  ### Utility recipes (pinning, list options, quick filters)
279
350
 
280
351
  ```tsx
@@ -23,6 +23,7 @@ This document provides a complete mapping of all components available in the lai
23
23
  ## UI Components
24
24
 
25
25
  ### Form & Input Components
26
+
26
27
  - **AppForm** - Dynamic form component with multiple field types support
27
28
  - **AppRadioGroup** - Enhanced radio group with card and icon support
28
29
  - **AsyncSelect** - Select component with asynchronous data loading capabilities
@@ -41,6 +42,7 @@ This document provides a complete mapping of all components available in the lai
41
42
  - **TextArea** - Multi-line text input field
42
43
 
43
44
  ### Layout & Structure Components
45
+
44
46
  - **Accordion** - Collapsible content panels for organizing information hierarchically
45
47
  - **AppSidebar** - Application sidebar navigation component
46
48
  - **AppStepper** - Step-by-step progress indicator for multi-step processes
@@ -56,8 +58,10 @@ This document provides a complete mapping of all components available in the lai
56
58
  - **Tabs** - Tabbed interface for organizing content
57
59
 
58
60
  ### Overlay & Dialog Components
61
+
59
62
  - **Alert** - Display important messages and notifications to users
60
63
  - **AlertDialog** - Modal dialog for critical confirmations and warnings
64
+ - **AppDialog** - Enhanced modal dialog with built-in header, body, footer sections and size variants
61
65
  - **Command** - Command palette for keyboard-driven navigation
62
66
  - **Confirmer** - Confirmation dialog for destructive actions
63
67
  - **ContextMenu** - Right-click context menu component
@@ -71,6 +75,7 @@ This document provides a complete mapping of all components available in the lai
71
75
  - **Tooltip** - Contextual information displayed on hover
72
76
 
73
77
  ### Data Display Components
78
+
74
79
  - **Avatar** - User profile image display with fallback initials
75
80
  - **Badge** - Small status indicator or label for highlighting information
76
81
  - **DataCrossTable** - Cross-tabulation data display component
@@ -81,6 +86,7 @@ This document provides a complete mapping of all components available in the lai
81
86
  - **Typo** - Typography component for consistent text styling
82
87
 
83
88
  ### Content & Media Components
89
+
84
90
  - **AppEditor** - Rich text editor component for content creation
85
91
  - **AudioVisualizer** - Audio waveform visualization component
86
92
  - **Calendar** - Date selection and display component
@@ -96,6 +102,7 @@ This document provides a complete mapping of all components available in the lai
96
102
  - **ShikiHighlighter** - Code syntax highlighter using Shiki
97
103
 
98
104
  ### Messaging & Communication
105
+
99
106
  - **Chat** - Complete chat interface component
100
107
  - **ChatMessage** - Individual message display within chat interfaces
101
108
  - **MessageInput** - Text input specifically designed for messaging
@@ -103,12 +110,14 @@ This document provides a complete mapping of all components available in the lai
103
110
  - **PromptSuggestions** - Suggestion chips for prompt input
104
111
 
105
112
  ### Navigation Components
113
+
106
114
  - **Button** - Primary interactive element for user actions
107
115
  - **NavigationMenu** - Navigation menu with dropdown support
108
116
  - **ThemeSwitcher** - Component for switching between light/dark themes
109
117
  - **WeeklyCalendar** - Week-view calendar component
110
118
 
111
119
  ### Utility & Feedback Components
120
+
112
121
  - **Skeleton** - Loading placeholder component with animation
113
122
  - **Sonner** - Toast notification system
114
123
  - **Spinner** - Loading spinner indicator
@@ -0,0 +1,123 @@
1
+ "use client";
2
+ import { jsx as l, jsxs as a } from "react/jsx-runtime";
3
+ import { cva as D } from "../../node_modules/class-variance-authority/dist/index.js";
4
+ import { Button as C } from "./button.js";
5
+ import { Dialog as b, DialogTrigger as y, DialogContent as z, DialogHeader as j, DialogClose as A, DialogFooter as B } from "./dialog.js";
6
+ import { Typo as u } from "./typo.js";
7
+ import { cn as s } from "../../lib/utils.js";
8
+ const T = D(
9
+ [
10
+ "flex flex-col justify-between gap-2 w-full h-dvh max-w-[initial] p-6",
11
+ "max-sm:rounded-none max-sm:px-2 max-sm:py-3 max-sm:min-w-full max-sm:min-h-full max-sm:w-full max-sm:h-full max-sm:max-w-full max-sm:max-h-full"
12
+ ],
13
+ {
14
+ variants: {
15
+ size: {
16
+ sm: "min-w-5/12 min-h-5/12 w-5/12 h-5/12 max-w-5/12 max-h-5/12",
17
+ default: "min-w-7/12 min-h-7/12 w-7/12 h-7/12 max-w-7/12 max-h-7/12",
18
+ lg: "min-w-9/12 min-h-9/12 w-9/12 h-9/12 max-w-9/12 max-h-9/12",
19
+ xl: "min-w-11/12 min-h-11/12 w-11/12 h-11/12 max-w-11/12 max-h-11/12",
20
+ full: "min-w-full min-h-full w-full h-full max-w-full max-h-full rounded-none"
21
+ }
22
+ },
23
+ defaultVariants: {
24
+ size: "default"
25
+ }
26
+ }
27
+ );
28
+ function E({
29
+ children: o,
30
+ trigger: m,
31
+ title: n,
32
+ description: e,
33
+ footer: i,
34
+ size: d = "default",
35
+ open: f,
36
+ defaultOpen: c,
37
+ onOpenChange: r,
38
+ triggerClassName: x,
39
+ headerClassName: w,
40
+ bodyClassName: p,
41
+ footerClassName: v,
42
+ disabled: t = !1,
43
+ asChild: g = !1,
44
+ preventClose: V,
45
+ ...h
46
+ }) {
47
+ const N = f !== void 0;
48
+ return t ? /* @__PURE__ */ l("div", { className: x, children: m }) : /* @__PURE__ */ a(
49
+ b,
50
+ {
51
+ open: N ? f : void 0,
52
+ defaultOpen: c,
53
+ onOpenChange: r,
54
+ children: [
55
+ m && /* @__PURE__ */ l(
56
+ y,
57
+ {
58
+ asChild: g,
59
+ className: x,
60
+ disabled: t,
61
+ children: m
62
+ }
63
+ ),
64
+ /* @__PURE__ */ a(
65
+ z,
66
+ {
67
+ ...h,
68
+ className: s(
69
+ T({
70
+ size: d
71
+ }),
72
+ h.className
73
+ ),
74
+ showCloseButton: !1,
75
+ children: [
76
+ /* @__PURE__ */ a(j, { className: s("gap-1", w), children: [
77
+ /* @__PURE__ */ a("div", { className: "flex w-full flex-row items-start gap-2", children: [
78
+ /* @__PURE__ */ l(u, { variant: "h5", className: "flex flex-1", children: n }),
79
+ /* @__PURE__ */ l(A, { asChild: !0, children: /* @__PURE__ */ l(
80
+ C,
81
+ {
82
+ iconLeft: "X",
83
+ variant: "ghost",
84
+ size: "icon",
85
+ className: "size-7",
86
+ onClick: () => r?.(!1)
87
+ }
88
+ ) })
89
+ ] }),
90
+ e && /* @__PURE__ */ l(
91
+ u,
92
+ {
93
+ variant: "caption",
94
+ className: "text-d-secondary-foreground flex flex-1",
95
+ children: e
96
+ }
97
+ )
98
+ ] }),
99
+ o && /* @__PURE__ */ l(
100
+ "div",
101
+ {
102
+ className: s(
103
+ "border-d-border flex min-h-0 w-full flex-1 flex-col gap-2 overflow-auto py-2",
104
+ (!!n || !!e) && "border-t",
105
+ !!i && "border-b",
106
+ p
107
+ ),
108
+ children: o
109
+ }
110
+ ),
111
+ i && /* @__PURE__ */ l(B, { className: v, children: i })
112
+ ]
113
+ }
114
+ )
115
+ ]
116
+ }
117
+ );
118
+ }
119
+ export {
120
+ E as AppDialog,
121
+ A as AppDialogClose,
122
+ E as default
123
+ };