laif-ds 0.2.75 → 0.2.77

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,20 +1,22 @@
1
1
  {
2
2
  "schemaVersion": "1.1.0",
3
- "generatedAt": "2026-03-09T16:04:39.745Z",
3
+ "generatedAt": "2026-03-24T15:46:53.701Z",
4
4
  "package": {
5
5
  "name": "laif-ds",
6
- "version": "0.2.75"
6
+ "version": "0.2.77"
7
7
  },
8
8
  "stats": {
9
- "documentedComponentCount": 91,
10
- "catalogedComponentCount": 90,
11
- "missingFromDocsCount": 0,
9
+ "documentedComponentCount": 92,
10
+ "catalogedComponentCount": 92,
11
+ "missingFromDocsCount": 1,
12
12
  "deprecatedComponentCount": 2,
13
- "averageAiReadinessScore": 54.23,
14
- "highAiReadinessCount": 35,
13
+ "averageAiReadinessScore": 54.73,
14
+ "highAiReadinessCount": 36,
15
15
  "lowAiReadinessCount": 42
16
16
  },
17
- "missingFromDocs": [],
17
+ "missingFromDocs": [
18
+ "TruncatedCell"
19
+ ],
18
20
  "components": [
19
21
  {
20
22
  "name": "Accordion",
@@ -246,6 +248,92 @@
246
248
  "type AlertDialogTriggerProps = React_2.ComponentProps<typeof AlertDialogPrimitive.Trigger>;\r"
247
249
  ]
248
250
  },
251
+ {
252
+ "name": "AppCard",
253
+ "markdownPath": "components/AppCard.md",
254
+ "importPath": "laif-ds",
255
+ "deprecated": false,
256
+ "replacement": null,
257
+ "tags": {
258
+ "cataloged": true,
259
+ "aiReady": true
260
+ },
261
+ "docs": {
262
+ "sections": [
263
+ {
264
+ "title": "Overview",
265
+ "slug": "overview"
266
+ },
267
+ {
268
+ "title": "Props",
269
+ "slug": "props"
270
+ },
271
+ {
272
+ "title": "Exports",
273
+ "slug": "exports"
274
+ },
275
+ {
276
+ "title": "Behavior",
277
+ "slug": "behavior"
278
+ },
279
+ {
280
+ "title": "Examples",
281
+ "slug": "examples"
282
+ },
283
+ {
284
+ "title": "Notes",
285
+ "slug": "notes"
286
+ }
287
+ ],
288
+ "hasPropsTable": true,
289
+ "hasExamples": true,
290
+ "exampleTitles": [
291
+ "AppCardProps",
292
+ "Variant Reference",
293
+ "Size Reference",
294
+ "Basic",
295
+ "Semantic Variants",
296
+ "Interactive Card with onClick",
297
+ "Loading State",
298
+ "Nested Flat Cards",
299
+ "Size Variants",
300
+ "Children as Fallback Body",
301
+ "Advanced Composition with Sub-components"
302
+ ],
303
+ "controlledPattern": "likely-controlled",
304
+ "requiredProps": []
305
+ },
306
+ "metadata": {
307
+ "props": {
308
+ "totalProps": 23,
309
+ "requiredPropsCount": 0,
310
+ "typedPropsCount": 23,
311
+ "describedPropsCount": 23
312
+ },
313
+ "accessibility": {
314
+ "hasCoverage": true
315
+ },
316
+ "states": {
317
+ "coveredStates": [
318
+ "hover",
319
+ "focus",
320
+ "loading",
321
+ "error",
322
+ "empty"
323
+ ],
324
+ "coveredStateCount": 5
325
+ }
326
+ },
327
+ "aiReadiness": {
328
+ "score": 100,
329
+ "tier": "high"
330
+ },
331
+ "typeReferences": [
332
+ "interface AppCardProps extends Omit<React_2.ComponentProps<\"div\">, \"title\"> {\r",
333
+ "type AppCardSize = \"sm\" | \"default\" | \"lg\" | \"none\";\r",
334
+ "type AppCardVariant = \"default\" | \"elevated\" | \"outlined\" | \"ghost\" | \"flat\" | \"interactive\" | \"success\" | \"warning\" | \"destructive\" | \"info\";\r"
335
+ ]
336
+ },
249
337
  {
250
338
  "name": "AppCheckbox",
251
339
  "markdownPath": "components/AppCheckbox.md",
@@ -522,19 +610,13 @@
522
610
  "AppFormItem",
523
611
  "Submit Button Inside vs Outside",
524
612
  "input",
525
- "textarea",
526
- "select",
527
- "multiselect",
613
+ "select / multiselect",
614
+ "custom",
528
615
  "async / async-multiple",
529
616
  "datepicker",
530
- "radio",
531
- "checkbox",
532
- "switch",
533
- "slider",
534
- "Basic Form",
535
- "Full Feature Form",
536
- "With Date Range",
537
- "External Form Control"
617
+ "radio / checkbox / switch / slider",
618
+ "Grid and Icons Example",
619
+ "Advanced componentProps"
538
620
  ],
539
621
  "controlledPattern": "likely-controlled",
540
622
  "requiredProps": [
@@ -557,10 +639,9 @@
557
639
  "disabled",
558
640
  "loading",
559
641
  "error",
560
- "empty",
561
642
  "selected"
562
643
  ],
563
- "coveredStateCount": 5
644
+ "coveredStateCount": 4
564
645
  }
565
646
  },
566
647
  "aiReadiness": {
@@ -568,8 +649,10 @@
568
649
  "tier": "high"
569
650
  },
570
651
  "typeReferences": [
571
- "interface AppFormItem<TAsyncOption = unknown> {\r",
572
- "interface AppFormProps<TFormValues extends FieldValues = FieldValues, TAsyncOption = unknown> {\r"
652
+ "interface AppFormItemComponentProps<TAsyncOption = unknown> {\r",
653
+ "interface AppFormProps<TFormValues extends FieldValues = FieldValues, TAsyncOption = unknown> {\r",
654
+ "type AppFormComponentType = \"input\" | \"select\" | \"textarea\" | \"checkbox\" | \"multiselect\" | \"datepicker\" | \"radio\" | \"switch\" | \"slider\" | \"async\" | \"async-multiple\" | \"custom\";\r",
655
+ "type AppFormItem<TAsyncOption = unknown, TComponent extends AppFormComponentType = AppFormComponentType> = {\r"
573
656
  ]
574
657
  },
575
658
  {
@@ -2585,10 +2668,10 @@
2585
2668
  },
2586
2669
  "metadata": {
2587
2670
  "props": {
2588
- "totalProps": 22,
2671
+ "totalProps": 23,
2589
2672
  "requiredPropsCount": 0,
2590
- "typedPropsCount": 22,
2591
- "describedPropsCount": 22
2673
+ "typedPropsCount": 23,
2674
+ "describedPropsCount": 23
2592
2675
  },
2593
2676
  "accessibility": {
2594
2677
  "hasCoverage": true
@@ -5975,5 +6058,5 @@
5975
6058
  ]
5976
6059
  }
5977
6060
  ],
5978
- "checksum": "10e072f1a2d3f682aff594d6c5319ff53034c93de21a31cb6a1b3c2c3407fbd4"
6061
+ "checksum": "04503a20ecd4bab54c8394f25ac6f42427d60e457070009b8248a22c8747a5de"
5979
6062
  }
@@ -0,0 +1,342 @@
1
+ # TruncatedCell
2
+
3
+ The TruncatedCell component is designed to display text that may be too long for its container. It automatically detects when text is truncated and provides a popover to show the full content.
4
+
5
+ ## Features
6
+
7
+ - **Flexible Content**: Accepts plain text or rich ReactNode content
8
+ - **Automatic Truncation Detection**: Uses scrollWidth vs clientWidth comparison to detect if content is truncated
9
+ - **Responsive**: Re-checks truncation on resize using ResizeObserver for better performance
10
+ - **Controlled Popover**: Manages popover state programmatically for better UX
11
+ - **Eye Icon Hint**: Displays an eye icon hint only when content is truncated, with smooth fade-in animation
12
+ - **Button Visibility Control**: Optional `showButton` prop to control eye button visibility
13
+ - **Custom Popover Styling**: `popoverClassName` prop for custom popover content styling
14
+ - **Keyboard Accessibility**: Full keyboard navigation support (Enter/Space to open popover)
15
+ - **Screen Reader Support**: Proper ARIA labels and roles for accessibility
16
+ - **Empty State**: Shows "-" with muted styling when no content is provided
17
+ - **Custom Empty Fallback**: Supports a custom placeholder for empty values
18
+ - **Customizable Styling**: Supports custom CSS classes for container, cell, and popover
19
+ - **Dialog Title**: Optional title for the popover header
20
+ - **Custom Content**: Full JSX support for custom popover content
21
+ - **Hover Effects**: Smooth underline on content hover and button appearance
22
+ - **Scrollable Content**: Long content in popover is scrollable with max height
23
+ - **DX-first API**: Rich children work out of the box, and `text` is only needed when you want explicit popover/accessibility text
24
+
25
+ ## Usage
26
+
27
+ ```tsx
28
+ import { TruncatedCell } from "laif-ds";
29
+
30
+ // Basic usage with string content
31
+ <TruncatedCell text="Short text" />
32
+
33
+ // Long text that will be truncated
34
+ <TruncatedCell
35
+ text="This is a very long text that will be truncated because it exceeds the container width"
36
+ wrapperClassName="w-56"
37
+ />
38
+
39
+ // String children also work without text
40
+ <TruncatedCell wrapperClassName="w-56">
41
+ This is a string content
42
+ </TruncatedCell>
43
+
44
+ // Rich content works without duplicating text
45
+ <TruncatedCell wrapperClassName="w-56">
46
+ <div className="flex items-center gap-2">
47
+ <Avatar src="/avatar.jpg" />
48
+ <div className="min-w-0">
49
+ <p className="font-semibold">John Doe</p>
50
+ <p className="text-sm text-gray-600">john@example.com</p>
51
+ </div>
52
+ </div>
53
+ </TruncatedCell>
54
+
55
+ // Provide text when you want explicit popover or accessibility content
56
+ <TruncatedCell
57
+ text="John Doe - john@example.com"
58
+ title="User details"
59
+ wrapperClassName="w-56"
60
+ >
61
+ <UserSummary />
62
+ </TruncatedCell>
63
+
64
+ // With custom styling and title
65
+ <TruncatedCell
66
+ text="Custom styled truncated text"
67
+ title="Full Content"
68
+ wrapperClassName="w-40"
69
+ className="max-w-40"
70
+ />
71
+
72
+ // With custom popover content and styling
73
+ <TruncatedCell
74
+ text="Text with custom popover content"
75
+ title="Custom Content"
76
+ popoverContent={
77
+ <div className="space-y-3">
78
+ <p>Custom JSX content here</p>
79
+ <button>Action Button</button>
80
+ </div>
81
+ }
82
+ popoverClassName="max-w-md"
83
+ showButton={true}
84
+ />
85
+
86
+ // Hide the eye hint
87
+ <TruncatedCell
88
+ text="Text without eye button"
89
+ showButton={false}
90
+ />
91
+
92
+ // Empty text
93
+ <TruncatedCell text="" />
94
+
95
+ // Custom empty fallback
96
+ <TruncatedCell text="" emptyFallback="No value" />
97
+ ```
98
+
99
+ ## Props
100
+
101
+ | Prop | Type | Default | Description |
102
+ | ------------------ | ----------- | ----------- | ---------------------------------------------------------------------------- |
103
+ | `children` | `ReactNode` | `undefined` | Content to display |
104
+ | `text` | `string` | `undefined` | Optional text used for truncation detection, accessibility, and popover copy |
105
+ | `title` | `string` | `undefined` | Optional title for the popover dialog |
106
+ | `popoverContent` | `ReactNode` | `undefined` | Custom popover content (JSX) |
107
+ | `wrapperClassName` | `string` | `""` | Preferred CSS classes for the wrapper container |
108
+ | `className` | `string` | `""` | CSS classes for the cell content |
109
+ | `popoverClassName` | `string` | `""` | CSS classes for the popover content |
110
+ | `showButton` | `boolean` | `true` | Flag used to show/hide the eye hint |
111
+ | `emptyFallback` | `ReactNode` | `"-"` | Custom placeholder rendered when no content is available |
112
+
113
+ ## Behavior
114
+
115
+ ### Truncation Detection
116
+
117
+ - Component monitors the text element's scrollWidth vs clientWidth
118
+ - If scrollWidth > clientWidth, the text is considered truncated
119
+ - Detection runs on mount and on resize
120
+ - When `text` is not provided, the component also extracts `textContent` from the rendered node to power the default popover content
121
+
122
+ ### Visual States
123
+
124
+ 1. **Normal State**: Text is displayed with truncation (CSS `truncate`)
125
+ 2. **Truncated State**: Text is truncated + eye icon hint appears
126
+ 3. **Empty State**: Shows "-" when text is empty/undefined
127
+ 4. **Popover State**: Opens when there is content to inspect, and the eye icon hint appears only when the rendered value is truncated
128
+
129
+ ### Styling
130
+
131
+ - Container: `flex max-w-60 gap-2` + custom classes
132
+ - Text container: `flex min-w-0 flex-1`
133
+ - Text element: `w-full min-w-0 truncate whitespace-nowrap`
134
+ - Popover: `w-96` with `whitespace-pre-wrap` for multiline support
135
+
136
+ ### Content Types
137
+
138
+ The TruncatedCell component supports two main usage patterns:
139
+
140
+ #### 1. String Content (Simple)
141
+
142
+ ```tsx
143
+ // Direct text prop
144
+ <TruncatedCell text="Simple text content" />
145
+
146
+ // String children (text prop optional)
147
+ <TruncatedCell wrapperClassName="w-56">
148
+ String content as children
149
+ </TruncatedCell>
150
+ ```
151
+
152
+ #### 2. ReactNode Content (Advanced)
153
+
154
+ ```tsx
155
+ // Rich children work without text
156
+ <TruncatedCell wrapperClassName="w-56">
157
+ <div className="flex items-center gap-2">
158
+ <Avatar src="/avatar.jpg" />
159
+ <div className="min-w-0">
160
+ <p className="font-semibold">John Doe</p>
161
+ <p className="text-sm text-gray-600">john@example.com</p>
162
+ </div>
163
+ </div>
164
+ </TruncatedCell>
165
+
166
+ // Add text when you want explicit popover content
167
+ <TruncatedCell text="User profile - John Doe" wrapperClassName="w-56">
168
+ <UserSummary />
169
+ </TruncatedCell>
170
+ ```
171
+
172
+ ### Choosing Between `children` and `text`
173
+
174
+ - Use `text` for the simplest plain-text case
175
+ - Use `children` when you need custom rendering inside the truncated area
176
+ - Add `text` together with `children` when the rendered content is visual or abbreviated and you want more descriptive text in the popover
177
+
178
+ ```tsx
179
+ // Plain text
180
+ <TruncatedCell text="Contract pending signature" />
181
+
182
+ // Rich UI with automatic text extraction
183
+ <TruncatedCell wrapperClassName="w-56">
184
+ <div>Complex content</div>
185
+ </TruncatedCell>
186
+
187
+ // Rich UI with explicit popover and a11y text
188
+ <TruncatedCell text="Complex content description" wrapperClassName="w-56">
189
+ <div>Complex content</div>
190
+ </TruncatedCell>
191
+ ```
192
+
193
+ ### Custom Popover Content
194
+
195
+ The `popoverContent` prop allows you to override the default text display with custom JSX content:
196
+
197
+ - **Full Flexibility**: Any React components can be used as popover content
198
+ - **Backward Compatible**: When not provided, defaults to displaying the text with Typo component
199
+ - **Title Support**: Works seamlessly with the `title` prop for popover headers
200
+ - **Custom Styling**: Use `popoverClassName` to style the popover container
201
+ - **Button Control**: Use `showButton` to control eye hint visibility
202
+ - **Open Behavior**: Custom popover content can open even when the displayed value itself is not truncated
203
+
204
+ ```tsx
205
+ <TruncatedCell
206
+ text="User profile"
207
+ title="User Details"
208
+ popoverContent={
209
+ <div className="space-y-2">
210
+ <div className="flex items-center gap-2">
211
+ <Avatar src="/avatar.jpg" />
212
+ <div>
213
+ <p className="font-semibold">John Doe</p>
214
+ <p className="text-sm text-gray-600">john@example.com</p>
215
+ </div>
216
+ </div>
217
+ <div className="flex gap-2">
218
+ <Button size="sm">Edit</Button>
219
+ <Button size="sm" variant="outline">
220
+ View Profile
221
+ </Button>
222
+ </div>
223
+ </div>
224
+ }
225
+ popoverClassName="max-w-md"
226
+ showButton={true}
227
+ />
228
+ ```
229
+
230
+ ### Button Visibility Control
231
+
232
+ The `showButton` prop gives you control over the eye hint visibility:
233
+
234
+ ```tsx
235
+ // Show eye hint (default)
236
+ <TruncatedCell text="Long text that will be truncated" showButton={true} />
237
+
238
+ // Hide eye hint
239
+ <TruncatedCell text="Long text without eye hint" showButton={false} />
240
+ ```
241
+
242
+ ### Empty Fallback
243
+
244
+ ```tsx
245
+ // Default placeholder
246
+ <TruncatedCell text="" />
247
+
248
+ // Custom placeholder
249
+ <TruncatedCell text="" emptyFallback="No value" />
250
+ ```
251
+
252
+ ### Popover Styling
253
+
254
+ The `popoverClassName` prop allows custom styling of the popover container:
255
+
256
+ ```tsx
257
+ <TruncatedCell
258
+ text="Custom styled popover"
259
+ popoverClassName="max-w-md bg-blue-50 border-blue-200"
260
+ />
261
+ ```
262
+
263
+ ## Technical Details
264
+
265
+ ### Dependencies
266
+
267
+ - React hooks: `useState`, `useEffect`, `useRef`, `useCallback`
268
+ - Laif-DS components: `Popover`, `PopoverContent`, `PopoverTrigger`, `Typo`, `Icon`
269
+ - Utility: `cn` for class merging
270
+
271
+ ### Performance Optimizations
272
+
273
+ - **ResizeObserver**: Uses modern ResizeObserver API for better performance than window resize events
274
+ - **useCallback**: Memoizes truncation check function to prevent unnecessary re-renders
275
+ - **Controlled State**: Manages popover state programmatically to avoid prop drilling
276
+ - **Cleanup**: Proper cleanup of observers and event listeners
277
+ - **Optimized Re-renders**: Only re-checks truncation when content changes
278
+
279
+ ### Event Handling
280
+
281
+ - ResizeObserver for element-specific resize detection
282
+ - Fallback window resize listener for older browsers
283
+ - Click on the cell trigger opens the popover when available
284
+ - Keyboard support (Enter/Space keys)
285
+ - Hover effects with smooth transitions
286
+
287
+ ### Accessibility Features
288
+
289
+ - **Semantic Trigger**: Uses a real `button` element as the interactive trigger
290
+ - **Keyboard Navigation**: Full support for Enter and Space keys
291
+ - **Screen Reader Labels**: Dynamic `aria-label` based on truncation state
292
+ - **Focus Management**: Native button focus behavior
293
+ - **Semantic HTML**: Popover content remains accessible even for multiline values
294
+
295
+ ## Accessibility
296
+
297
+ - Text container has cursor pointer to indicate interactivity
298
+ - Hover state provides visual feedback
299
+ - Popover provides full text access for screen readers
300
+ - Eye icon provides a clear visual hint that more content is available
301
+
302
+ ## Examples
303
+
304
+ ### In a Table Cell
305
+
306
+ ```tsx
307
+ const TableCell = ({ value }: { value: string }) => (
308
+ <TruncatedCell text={value} wrapperClassName="w-56" className="py-2" />
309
+ );
310
+ ```
311
+
312
+ ### With Maximum Width Constraint
313
+
314
+ ```tsx
315
+ <TruncatedCell
316
+ text="Constrained width text that will truncate"
317
+ wrapperClassName="w-32"
318
+ />
319
+ ```
320
+
321
+ ### Multiline Text Support
322
+
323
+ ```tsx
324
+ <TruncatedCell text="Line 1\nLine 2\nLine 3" className="max-w-48" />
325
+ ```
326
+
327
+ ## Comparison with Alternatives
328
+
329
+ ### vs Tooltip
330
+
331
+ - **TruncatedCell**: Supports click-to-inspect content, and visually hints with the eye icon when text is actually truncated
332
+ - **Tooltip**: Always shows on hover regardless of truncation
333
+
334
+ ### vs CSS text-overflow alone
335
+
336
+ - **TruncatedCell**: Provides access to full content
337
+ - **CSS only**: Content is inaccessible when truncated
338
+
339
+ ### vs Expandable Text
340
+
341
+ - **TruncatedCell**: Compact, popover-based approach
342
+ - **Expandable**: Takes more space, inline expansion
@@ -0,0 +1,115 @@
1
+ "use client";
2
+ import { jsx as r, jsxs as e, Fragment as c } from "react/jsx-runtime";
3
+ import { cva as A } from "../../node_modules/class-variance-authority/dist/index.js";
4
+ import { designTokens as j } from "../design-tokens.js";
5
+ import { cn as t } from "../../lib/utils.js";
6
+ import { Card as y, CardHeader as b, CardTitle as S, CardDescription as T, CardAction as V, CardContent as g, CardFooter as D } from "./card.js";
7
+ import { Skeleton as s } from "./skeleton.js";
8
+ const F = A(
9
+ ["flex flex-col border shadow-sm rounded-xl", j.focusRingWithin],
10
+ {
11
+ variants: {
12
+ variant: {
13
+ default: "bg-d-card text-d-card-foreground border-d-border",
14
+ elevated: "bg-d-card text-d-card-foreground border-d-border shadow-md",
15
+ outlined: "bg-transparent text-d-foreground border-d-border shadow-none",
16
+ ghost: "bg-transparent text-d-foreground border-transparent shadow-none",
17
+ flat: "bg-d-muted text-d-foreground border-transparent shadow-none",
18
+ interactive: "bg-d-card text-d-card-foreground border-d-border cursor-pointer transition-shadow duration-200 hover:shadow-md hover:border-d-primary/40",
19
+ success: "bg-d-success-background text-d-success-foreground border-d-success/30 shadow-none",
20
+ warning: "bg-d-warning-background text-d-warning-foreground border-d-warning/30 shadow-none",
21
+ destructive: "bg-d-destructive/10 text-d-destructive border-d-destructive/30 shadow-none",
22
+ info: "bg-d-primary/10 text-d-primary border-d-primary/30 shadow-none"
23
+ }
24
+ },
25
+ defaultVariants: {
26
+ variant: "default"
27
+ }
28
+ }
29
+ );
30
+ function R() {
31
+ return /* @__PURE__ */ e(c, { children: [
32
+ /* @__PURE__ */ r(b, { children: /* @__PURE__ */ e("div", { className: "flex flex-col gap-2", children: [
33
+ /* @__PURE__ */ r(s, { className: "h-4 w-1/2" }),
34
+ /* @__PURE__ */ r(s, { className: "h-3 w-3/4" })
35
+ ] }) }),
36
+ /* @__PURE__ */ e(g, { className: "flex flex-col gap-2", children: [
37
+ /* @__PURE__ */ r(s, { className: "h-3 w-full" }),
38
+ /* @__PURE__ */ r(s, { className: "h-3 w-full" }),
39
+ /* @__PURE__ */ r(s, { className: "h-3 w-4/5" })
40
+ ] })
41
+ ] });
42
+ }
43
+ function I({
44
+ header: d,
45
+ title: a,
46
+ description: n,
47
+ body: l,
48
+ actions: o,
49
+ footer: i,
50
+ variant: h = "default",
51
+ size: p,
52
+ isLoading: x = !1,
53
+ showHeaderBorder: f = !1,
54
+ showFooterBorder: u = !1,
55
+ className: w,
56
+ headerClassName: v,
57
+ bodyClassName: N,
58
+ footerClassName: C,
59
+ children: m,
60
+ ...k
61
+ }) {
62
+ return /* @__PURE__ */ r(
63
+ y,
64
+ {
65
+ className: t(F({ variant: h }), w),
66
+ size: p,
67
+ ...k,
68
+ children: x ? /* @__PURE__ */ r(R, {}) : /* @__PURE__ */ e(c, { children: [
69
+ (d || a || n || o) && /* @__PURE__ */ r(
70
+ b,
71
+ {
72
+ className: t(
73
+ f && "border-b border-inherit",
74
+ v
75
+ ),
76
+ children: d || /* @__PURE__ */ e(c, { children: [
77
+ /* @__PURE__ */ e("div", { className: "flex flex-col gap-1.5", children: [
78
+ a && /* @__PURE__ */ r(S, { className: "text-base font-semibold", children: a }),
79
+ n && /* @__PURE__ */ r(T, { children: n })
80
+ ] }),
81
+ o && /* @__PURE__ */ r(V, { children: o })
82
+ ] })
83
+ }
84
+ ),
85
+ (l ?? m) && /* @__PURE__ */ r(
86
+ g,
87
+ {
88
+ className: t(
89
+ "flex flex-col gap-2",
90
+ (a || n || d || o) && !f && "pt-0",
91
+ u && "border-b border-inherit",
92
+ N
93
+ ),
94
+ children: l ?? m
95
+ }
96
+ ),
97
+ i && /* @__PURE__ */ r(
98
+ D,
99
+ {
100
+ className: t(
101
+ "gap-2",
102
+ (a || n || d || o || l) && !u && "pt-0",
103
+ C
104
+ ),
105
+ children: i
106
+ }
107
+ )
108
+ ] })
109
+ }
110
+ );
111
+ }
112
+ export {
113
+ I as AppCard,
114
+ I as default
115
+ };