laif-ds 1.0.2 → 1.0.4

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/dist/CHANGELOG.md CHANGED
@@ -5,6 +5,19 @@ All notable technical changes to the laif-ds core will be documented in this fil
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [laif-ds@1.0.4]
9
+
10
+ ### 🐛 Fixed
11
+
12
+ - **Button**: Disabled buttons no longer show hover colours, the press squash or the loading shimmer, keep the `not-allowed` cursor, and are removed from the tab order. With `asChild`, `disabled` is no longer forwarded to the slotted element (invalid on e.g. an `<a>`) — it now gets `aria-disabled`, `data-disabled` and `tabIndex={-1}`, and its click is blocked
13
+
14
+ ## [laif-ds@1.0.3]
15
+
16
+ ### 🚀 Added
17
+
18
+ - **Confirmer**: Below 768px, the confirm now opens as a bottom drawer instead of a centered dialog — no prop needed, the mode is decided when the confirm opens and held for its lifetime. Buttons are full-width 44px touch targets (action on top, Cancel at the bottom), initial focus lands on Cancel, and the drawer keeps `role="alertdialog"`. A drag down or Esc rejects the confirm's promise; tapping the overlay does nothing, matching desktop
19
+ - **use-mobile**: Exports `MOBILE_BREAKPOINT` so consumers can read the same 768px threshold used internally
20
+
8
21
  ## [laif-ds@1.0.2]
9
22
 
10
23
  ### 🐛 Fixed
@@ -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
  };
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-09-18T09:11:12.858Z",
3
+ "generatedAt": "2026-09-23T16:57:43.943Z",
4
4
  "package": {
5
5
  "name": "laif-ds",
6
- "version": "1.0.2"
6
+ "version": "1.0.4"
7
7
  },
8
8
  "summary": {
9
9
  "scannedFiles": 404,
@@ -13,9 +13,9 @@
13
13
  "componentsWithoutPropsTableCount": 30,
14
14
  "repeatedClassPatternsCount": 25,
15
15
  "lowAiReadinessComponentsCount": 41,
16
- "componentsWithoutAccessibilityCoverageCount": 45,
16
+ "componentsWithoutAccessibilityCoverageCount": 44,
17
17
  "componentsWithWeakStateCoverageCount": 71,
18
- "averageAiReadinessScore": 56.17
18
+ "averageAiReadinessScore": 56.33
19
19
  },
20
20
  "deprecatedUsage": [],
21
21
  "documentationGaps": {
@@ -70,7 +70,6 @@
70
70
  "ChatMessage",
71
71
  "CircularProgress",
72
72
  "CodeHighlighter",
73
- "Confirmer",
74
73
  "CopyButton",
75
74
  "DataCrossTable",
76
75
  "DropdownMenu",
@@ -301,10 +300,6 @@
301
300
  "name": "Breadcrumb",
302
301
  "score": 30
303
302
  },
304
- {
305
- "name": "Confirmer",
306
- "score": 30
307
- },
308
303
  {
309
304
  "name": "Stepper",
310
305
  "score": 30
@@ -321,6 +316,10 @@
321
316
  "name": "Toggle",
322
317
  "score": 40
323
318
  },
319
+ {
320
+ "name": "Confirmer",
321
+ "score": 45
322
+ },
324
323
  {
325
324
  "name": "GanttChart",
326
325
  "score": 45
@@ -485,33 +484,20 @@
485
484
  ]
486
485
  },
487
486
  {
488
- "className": "border-d-border mt-2 rounded-md border p-4",
487
+ "className": "flex flex-col items-center gap-4",
489
488
  "occurrences": 9,
490
489
  "files": [
491
- "src/components/stories/tabs.stories.tsx"
492
- ]
493
- },
494
- {
495
- "className": "text-d-muted-foreground text-xs",
496
- "occurrences": 8,
497
- "files": [
498
- "src/components/editor/plugins/mention-plugin.tsx",
499
490
  "src/components/stories/app-card.stories.tsx",
500
- "src/components/stories/button.stories.tsx",
501
- "src/components/stories/input.stories.tsx",
502
- "src/components/ui/tables/data-cross-table/cell-editor-dialog.tsx",
503
- "src/components/ui/tables/data-cross-table/data-cross-table.tsx",
504
- "src/components/ui/tables/data-cross-table/editable-input.tsx"
491
+ "src/components/stories/confirmer.stories.tsx",
492
+ "src/components/stories/input-selector.stories.tsx",
493
+ "src/components/stories/theme-switcher.stories.tsx"
505
494
  ]
506
495
  },
507
496
  {
508
- "className": "flex flex-col items-center gap-4",
509
- "occurrences": 8,
497
+ "className": "border-d-border mt-2 rounded-md border p-4",
498
+ "occurrences": 9,
510
499
  "files": [
511
- "src/components/stories/app-card.stories.tsx",
512
- "src/components/stories/confirmer.stories.tsx",
513
- "src/components/stories/input-selector.stories.tsx",
514
- "src/components/stories/theme-switcher.stories.tsx"
500
+ "src/components/stories/tabs.stories.tsx"
515
501
  ]
516
502
  },
517
503
  {
@@ -580,6 +566,18 @@
580
566
  "src/components/stories/spinner.stories.tsx"
581
567
  ]
582
568
  },
569
+ {
570
+ "className": "text-d-muted-foreground text-xs",
571
+ "occurrences": 6,
572
+ "files": [
573
+ "src/components/editor/plugins/mention-plugin.tsx",
574
+ "src/components/stories/app-card.stories.tsx",
575
+ "src/components/stories/input.stories.tsx",
576
+ "src/components/ui/tables/data-cross-table/cell-editor-dialog.tsx",
577
+ "src/components/ui/tables/data-cross-table/data-cross-table.tsx",
578
+ "src/components/ui/tables/data-cross-table/editable-input.tsx"
579
+ ]
580
+ },
583
581
  {
584
582
  "className": "flex items-center gap-1 font-normal",
585
583
  "occurrences": 6,
@@ -129,6 +129,6 @@ export function LoadingButton() {
129
129
 
130
130
  ## Notes
131
131
 
132
- - **Disabled**: Applies reduced opacity and prevents interactions.
132
+ - **Disabled**: `disabled` renders a native disabled button: reduced opacity, `not-allowed` cursor, no hover colours, press animation or shimmer, and it is skipped by Tab. With `asChild`, `disabled` sets `aria-disabled` and `tabIndex={-1}` on the slotted element and blocks activation; pass `onClick` to `Button`, not to the child (the child's own handler runs first), and omit `href` if the link must be fully unreachable, since middle-click still opens it.
133
133
  - **Icon-only**: Use `size="icon"` for square icon buttons.
134
134
  - **Theming**: Use variants to match semantic meaning (primary, destructive, etc.).
@@ -56,6 +56,9 @@ declare function safeConfirm(
56
56
  - **Resolve/Reject**: `confirm()` resolves on action click, rejects on cancel or close.
57
57
  - **Destructive mode**: Adds an alert icon and uses destructive button variant.
58
58
  - **Custom buttons**: Pass `ActionProps` and `CancelProps` to customize.
59
+ - **Mobile (< 768px)**: the confirm opens as a bottom drawer instead of a centred dialog — no prop needed, `useIsMobile` decides when it opens and the mode is held while it stays open. Buttons are full-width, 44px tall, action on top and Cancel at the bottom; `CancelProps` is applied to that Cancel button.
60
+ - **Dismiss on mobile**: a drag down or Esc cancels (the promise rejects); a tap on the overlay does nothing, as on desktop.
61
+ - **Focus**: the initial focus lands on Cancel in both modes, and the drawer keeps `role="alertdialog"`.
59
62
 
60
63
  ---
61
64
 
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "schemaVersion": "1.1.0",
3
- "generatedAt": "2026-09-18T09:11:12.439Z",
3
+ "generatedAt": "2026-09-23T16:57:43.636Z",
4
4
  "package": {
5
5
  "name": "laif-ds",
6
- "version": "1.0.2"
6
+ "version": "1.0.4"
7
7
  },
8
8
  "stats": {
9
9
  "documentedComponentCount": 94,
10
10
  "catalogedComponentCount": 94,
11
11
  "missingFromDocsCount": 2,
12
12
  "deprecatedComponentCount": 2,
13
- "averageAiReadinessScore": 56.17,
13
+ "averageAiReadinessScore": 56.33,
14
14
  "highAiReadinessCount": 38,
15
15
  "lowAiReadinessCount": 41
16
16
  },
@@ -2544,17 +2544,18 @@
2544
2544
  "describedPropsCount": 0
2545
2545
  },
2546
2546
  "accessibility": {
2547
- "hasCoverage": false
2547
+ "hasCoverage": true
2548
2548
  },
2549
2549
  "states": {
2550
2550
  "coveredStates": [
2551
+ "focus",
2551
2552
  "error"
2552
2553
  ],
2553
- "coveredStateCount": 1
2554
+ "coveredStateCount": 2
2554
2555
  }
2555
2556
  },
2556
2557
  "aiReadiness": {
2557
- "score": 30,
2558
+ "score": 45,
2558
2559
  "tier": "low"
2559
2560
  },
2560
2561
  "typeReferences": []
@@ -6312,5 +6313,5 @@
6312
6313
  ]
6313
6314
  }
6314
6315
  ],
6315
- "checksum": "1b95270b522d7fdbd54fa834020be6d9bf1b0632fda8a9458556d024398a8574"
6316
+ "checksum": "332c6def52f863c64447793da4cde5f62b0eb7ac692b9fbd5e92a4d978e3aead"
6316
6317
  }
@@ -58,7 +58,10 @@ const e = {
58
58
  // Press snaps in (100ms) and eases back out (160ms, set by the caller) —
59
59
  // symmetric timing reads mushy. Do not deepen much past 2%: the scale is
60
60
  // anisotropic, so it distorts the label's aspect ratio too.
61
- active: "origin-bottom active:translate-y-[1px] active:scale-y-[0.98] active:scale-x-[1.02] active:shadow-none active:duration-[100ms] motion-reduce:active:translate-y-0 motion-reduce:active:scale-y-100 motion-reduce:active:scale-x-100",
61
+ // Gated on `interactive:` so a disabled control does not squash; the
62
+ // reduced-motion resets carry it too, or v4 (which emits custom variants
63
+ // after built-in ones) would let the squash win over them.
64
+ active: "origin-bottom interactive:active:translate-y-[1px] interactive:active:scale-y-[0.98] interactive:active:scale-x-[1.02] interactive:active:shadow-none interactive:active:duration-[100ms] motion-reduce:interactive:active:translate-y-0 motion-reduce:interactive:active:scale-y-100 motion-reduce:interactive:active:scale-x-100",
62
65
  disabled: "disabled:cursor-not-allowed disabled:opacity-50"
63
66
  },
64
67
  // Input specific
@@ -1,17 +1,19 @@
1
1
  "use client";
2
- import { jsx as t, jsxs as u } from "react/jsx-runtime";
3
- import { Root as g } from "../../node_modules/@radix-ui/react-slot/dist/index.js";
4
- import { cva as f } from "../../node_modules/class-variance-authority/dist/index.js";
2
+ import { jsx as t, jsxs as m } from "react/jsx-runtime";
3
+ import { Root as p } from "../../node_modules/@radix-ui/react-slot/dist/index.js";
4
+ import { cva as x } from "../../node_modules/class-variance-authority/dist/index.js";
5
5
  import { designTokens as r } from "../design-tokens.js";
6
- import { cn as d } from "../../lib/utils.js";
7
- import { Icon as v } from "./icon.js";
8
- const h = f(
9
- d(
6
+ import { cn as i } from "../../lib/utils.js";
7
+ import { Icon as g } from "./icon.js";
8
+ const f = x(
9
+ i(
10
10
  r.text.base,
11
11
  r.radius.default,
12
12
  r.focusRing,
13
13
  r.interaction.active,
14
14
  r.interaction.disabled,
15
+ // A disabled `asChild` link has no `:disabled`: it is flagged `data-disabled`.
16
+ "data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50",
15
17
  // `translate` and `scale` must be listed explicitly: Tailwind v4 compiles
16
18
  // them to the individual CSS properties of the same name, not to `transform`,
17
19
  // so a list naming only `transform` animates neither in the v4 bundle (v3
@@ -25,16 +27,16 @@ const h = f(
25
27
  {
26
28
  variants: {
27
29
  variant: {
28
- default: "bg-d-primary text-d-primary-foreground shadow-xs hover:bg-d-primary/90 hover:shadow-d-primary/25",
29
- destructive: "bg-d-destructive text-d-destructive-foreground shadow-xs hover:bg-d-destructive/90 hover:shadow-d-destructive/25 focus-visible:ring-d-destructive/20",
30
- outline: "border border-d-foreground shadow-xs disabled:border-d-foreground/30 hover:bg-d-accent hover:text-d-accent-foreground hover:border-d-foreground/80",
31
- "outline-primary": "border border-d-primary shadow-xs text-d-primary/80 hover:text-d-primary hover:bg-d-primary/10 hover:border-d-primary/80",
32
- "outline-destructive": "border border-d-destructive shadow-xs text-d-destructive/80 hover:text-d-destructive hover:bg-d-destructive/10 hover:border-d-destructive/80",
33
- secondary: "bg-d-secondary text-d-secondary-foreground shadow-xs hover:bg-d-secondary/80 hover:text-d-secondary-foreground",
34
- ghost: "hover:bg-d-accent hover:text-d-accent-foreground",
35
- "ghost-destructive": "text-d-destructive bg-transparent hover:bg-d-destructive/10",
36
- "ghost-accent": "text-d-primary bg-transparent hover:bg-d-primary/10",
37
- link: "text-d-primary underline-offset-4 hover:underline"
30
+ default: "bg-d-primary text-d-primary-foreground shadow-xs interactive:hover:bg-d-primary/90 interactive:hover:shadow-d-primary/25",
31
+ destructive: "bg-d-destructive text-d-destructive-foreground shadow-xs interactive:hover:bg-d-destructive/90 interactive:hover:shadow-d-destructive/25 focus-visible:ring-d-destructive/20",
32
+ outline: "border border-d-foreground shadow-xs disabled:border-d-foreground/30 data-[disabled]:border-d-foreground/30 interactive:hover:bg-d-accent interactive:hover:text-d-accent-foreground interactive:hover:border-d-foreground/80",
33
+ "outline-primary": "border border-d-primary shadow-xs text-d-primary/80 interactive:hover:text-d-primary interactive:hover:bg-d-primary/10 interactive:hover:border-d-primary/80",
34
+ "outline-destructive": "border border-d-destructive shadow-xs text-d-destructive/80 interactive:hover:text-d-destructive interactive:hover:bg-d-destructive/10 interactive:hover:border-d-destructive/80",
35
+ secondary: "bg-d-secondary text-d-secondary-foreground shadow-xs interactive:hover:bg-d-secondary/80 interactive:hover:text-d-secondary-foreground",
36
+ ghost: "interactive:hover:bg-d-accent interactive:hover:text-d-accent-foreground",
37
+ "ghost-destructive": "text-d-destructive bg-transparent interactive:hover:bg-d-destructive/10",
38
+ "ghost-accent": "text-d-primary bg-transparent interactive:hover:bg-d-primary/10",
39
+ link: "text-d-primary underline-offset-4 interactive:hover:underline"
38
40
  },
39
41
  size: {
40
42
  default: r.sizes.default + " has-[>svg]:px-3",
@@ -49,36 +51,48 @@ const h = f(
49
51
  }
50
52
  }
51
53
  );
52
- function _({
53
- className: a,
54
- variant: s,
54
+ function j({
55
+ className: n,
56
+ variant: d,
55
57
  size: e,
56
- asChild: n = !1,
57
- iconLeft: i,
58
- iconRight: c,
59
- isLoading: m = !1,
60
- ...o
58
+ asChild: s = !1,
59
+ iconLeft: c,
60
+ iconRight: v,
61
+ isLoading: b = !1,
62
+ disabled: o,
63
+ onClick: l,
64
+ ...a
61
65
  }) {
62
- const l = n ? g : "button";
63
- return n ? /* @__PURE__ */ t(
64
- l,
66
+ const u = s ? p : "button";
67
+ return s ? /* @__PURE__ */ t(
68
+ u,
65
69
  {
66
70
  "data-slot": "button",
67
- className: d(h({ variant: s, size: e, className: a })),
68
- ...o
71
+ className: i(f({ variant: d, size: e, className: n })),
72
+ ...a,
73
+ ...o && {
74
+ "aria-disabled": !0,
75
+ "data-disabled": "",
76
+ tabIndex: -1
77
+ },
78
+ onClick: o ? (h) => {
79
+ h.preventDefault(), h.stopPropagation();
80
+ } : l
69
81
  }
70
- ) : /* @__PURE__ */ u(
71
- l,
82
+ ) : /* @__PURE__ */ m(
83
+ u,
72
84
  {
73
85
  "data-slot": "button",
74
- className: d("relative", h({ variant: s, size: e, className: a })),
75
- ...o,
86
+ className: i("relative", f({ variant: d, size: e, className: n })),
87
+ disabled: o,
88
+ ...a,
89
+ onClick: l,
76
90
  children: [
77
- (s ?? "default") === "default" && /* @__PURE__ */ t("span", { className: "pointer-events-none absolute inset-0 overflow-hidden rounded-[inherit] motion-reduce:hidden", children: /* @__PURE__ */ t("span", { className: "absolute inset-0 -translate-x-full bg-gradient-to-r from-transparent via-white/20 to-transparent transition-transform duration-0 ease-out [@media(hover:hover)_and_(pointer:fine)]:group-hover:translate-x-full [@media(hover:hover)_and_(pointer:fine)]:group-hover:duration-700" }) }),
78
- m ? /* @__PURE__ */ u(
91
+ (d ?? "default") === "default" && !o && /* @__PURE__ */ t("span", { className: "pointer-events-none absolute inset-0 overflow-hidden rounded-[inherit] motion-reduce:hidden", children: /* @__PURE__ */ t("span", { className: "absolute inset-0 -translate-x-full bg-gradient-to-r from-transparent via-white/20 to-transparent transition-transform duration-0 ease-out [@media(hover:hover)_and_(pointer:fine)]:group-hover:translate-x-full [@media(hover:hover)_and_(pointer:fine)]:group-hover:duration-700" }) }),
92
+ b ? /* @__PURE__ */ m(
79
93
  "svg",
80
94
  {
81
- className: d("animate-spin", o.children && "mr-1 -ml-1"),
95
+ className: i("animate-spin", a.children && "mr-1 -ml-1"),
82
96
  xmlns: "http://www.w3.org/2000/svg",
83
97
  fill: "none",
84
98
  viewBox: "0 0 24 24",
@@ -106,18 +120,18 @@ function _({
106
120
  )
107
121
  ]
108
122
  }
109
- ) : i && /* @__PURE__ */ t(
110
- v,
123
+ ) : c && /* @__PURE__ */ t(
124
+ g,
111
125
  {
112
- name: i,
126
+ name: c,
113
127
  size: e === "default" ? "md" : e === "sm" ? "xs" : "sm"
114
128
  }
115
129
  ),
116
- o.children,
117
- c && /* @__PURE__ */ t(
118
- v,
130
+ a.children,
131
+ v && /* @__PURE__ */ t(
132
+ g,
119
133
  {
120
- name: c,
134
+ name: v,
121
135
  size: e === "default" ? "md" : e === "sm" ? "xs" : "sm"
122
136
  }
123
137
  )
@@ -126,6 +140,6 @@ function _({
126
140
  );
127
141
  }
128
142
  export {
129
- _ as Button,
130
- h as buttonVariants
143
+ j as Button,
144
+ f as buttonVariants
131
145
  };
@@ -1,31 +1,113 @@
1
1
  "use client";
2
- import { jsx as t, jsxs as r } from "react/jsx-runtime";
3
- import { createAsk as d } from "../../node_modules/use-ask/dist/index.js";
4
- import { AlertDialog as m, AlertDialogContent as p, AlertDialogHeader as u, AlertDialogTitle as f, AlertDialogDescription as A, AlertDialogFooter as g, AlertDialogCancel as v } from "./alert-dialog.js";
5
- import { Button as h } from "./button.js";
6
- import { Icon as x } from "./icon.js";
7
- const [i, C] = d({}), O = i.ask;
8
- i.safeAsk;
9
- const D = {
2
+ import { jsx as t, jsxs as n } from "react/jsx-runtime";
3
+ import { useRef as a } from "react";
4
+ import { createAsk as D } from "../../node_modules/use-ask/dist/index.js";
5
+ import { designTokens as f } from "../design-tokens.js";
6
+ import { AlertDialog as A, AlertDialogContent as x, AlertDialogHeader as C, AlertDialogTitle as w, AlertDialogDescription as k, AlertDialogFooter as N, AlertDialogCancel as T } from "./alert-dialog.js";
7
+ import { Button as c } from "./button.js";
8
+ import { Drawer as P, DrawerContent as O, DrawerHeader as b, DrawerTitle as y, DrawerDescription as z, DrawerFooter as B } from "./drawer.js";
9
+ import { Icon as v } from "./icon.js";
10
+ import { MOBILE_BREAKPOINT as F } from "../../hooks/use-mobile.js";
11
+ import { cn as s } from "../../lib/utils.js";
12
+ const [h, I] = D({}), G = h.ask;
13
+ h.safeAsk;
14
+ const R = {
10
15
  title: "Are you sure?",
11
16
  cancelText: "Cancel",
12
17
  actionText: "Continue",
13
18
  variant: "default"
14
- }, P = () => {
15
- const [{ key: n, payload: o }, { asking: a, cancel: c, ok: l }] = C(), e = { ...D, ...o };
16
- return /* @__PURE__ */ t(
17
- m,
19
+ }, J = () => {
20
+ const [{ key: l, payload: g }, { asking: i, cancel: o, ok: d }] = I(), e = { ...R, ...g }, m = a(!1), u = a(!1);
21
+ i && !m.current && (u.current = window.innerWidth < F), m.current = i;
22
+ const p = a(null);
23
+ return u.current ? /* @__PURE__ */ t(
24
+ P,
18
25
  {
19
- open: a,
20
- onOpenChange: (s) => !s && c(),
21
- children: /* @__PURE__ */ r(p, { children: [
22
- /* @__PURE__ */ t(u, { children: /* @__PURE__ */ r(
23
- f,
26
+ open: i,
27
+ onOpenChange: (r) => !r && o(),
28
+ children: /* @__PURE__ */ n(
29
+ O,
30
+ {
31
+ role: "alertdialog",
32
+ ...!e.description && { "aria-describedby": void 0 },
33
+ onOpenAutoFocus: (r) => {
34
+ r.preventDefault(), p.current?.focus();
35
+ },
36
+ onPointerDownOutside: (r) => r.preventDefault(),
37
+ className: "motion-reduce:animate-none! motion-reduce:transition-none!",
38
+ children: [
39
+ /* @__PURE__ */ t(b, { className: "pb-2", children: /* @__PURE__ */ n(
40
+ y,
41
+ {
42
+ className: s(
43
+ "text-lg",
44
+ e.variant === "destructive" && "flex items-start gap-2"
45
+ ),
46
+ children: [
47
+ e.variant === "destructive" && /* @__PURE__ */ t(
48
+ v,
49
+ {
50
+ name: "AlertTriangle",
51
+ className: "text-d-destructive mt-1 shrink-0",
52
+ size: "sm"
53
+ }
54
+ ),
55
+ e.title
56
+ ]
57
+ }
58
+ ) }),
59
+ e.description && /* @__PURE__ */ t(z, { className: "min-h-0 flex-1 overflow-y-auto px-4", children: e.description }),
60
+ /* @__PURE__ */ n(B, { className: "pb-[max(1rem,env(safe-area-inset-bottom))]", children: [
61
+ /* @__PURE__ */ t(
62
+ c,
63
+ {
64
+ ...e.ActionProps,
65
+ variant: e.variant === "destructive" ? "destructive" : "default",
66
+ className: s(
67
+ f.sizes.touch,
68
+ "h-auto w-full",
69
+ e.ActionProps?.className
70
+ ),
71
+ onClick: () => d(!0),
72
+ children: e.actionText
73
+ }
74
+ ),
75
+ /* @__PURE__ */ t(
76
+ c,
77
+ {
78
+ ...e.CancelProps,
79
+ ref: p,
80
+ variant: "ghost",
81
+ className: s(
82
+ f.sizes.touch,
83
+ "h-auto w-full",
84
+ e.CancelProps?.className
85
+ ),
86
+ onClick: (r) => {
87
+ e.CancelProps?.onClick?.(r), r.defaultPrevented || o();
88
+ },
89
+ children: e.cancelText
90
+ }
91
+ )
92
+ ] })
93
+ ]
94
+ }
95
+ )
96
+ },
97
+ l
98
+ ) : /* @__PURE__ */ t(
99
+ A,
100
+ {
101
+ open: i,
102
+ onOpenChange: (r) => !r && o(),
103
+ children: /* @__PURE__ */ n(x, { children: [
104
+ /* @__PURE__ */ t(C, { children: /* @__PURE__ */ n(
105
+ w,
24
106
  {
25
107
  className: e.variant === "destructive" ? "flex items-center gap-2" : void 0,
26
108
  children: [
27
109
  e.variant === "destructive" && /* @__PURE__ */ t(
28
- x,
110
+ v,
29
111
  {
30
112
  name: "AlertTriangle",
31
113
  className: "text-d-destructive",
@@ -36,25 +118,25 @@ const D = {
36
118
  ]
37
119
  }
38
120
  ) }),
39
- /* @__PURE__ */ t(A, { children: e.description }),
40
- /* @__PURE__ */ r(g, { children: [
41
- /* @__PURE__ */ t(v, { ...e.CancelProps, children: e.cancelText }),
121
+ /* @__PURE__ */ t(k, { children: e.description }),
122
+ /* @__PURE__ */ n(N, { children: [
123
+ /* @__PURE__ */ t(T, { ...e.CancelProps, children: e.cancelText }),
42
124
  /* @__PURE__ */ t(
43
- h,
125
+ c,
44
126
  {
45
127
  ...e.ActionProps,
46
128
  variant: e.variant === "destructive" ? "destructive" : "default",
47
- onClick: () => l(!0),
129
+ onClick: () => d(!0),
48
130
  children: e.actionText
49
131
  }
50
132
  )
51
133
  ] })
52
134
  ] })
53
135
  },
54
- n
136
+ l
55
137
  );
56
138
  };
57
139
  export {
58
- P as Confirmer,
59
- O as confirm
140
+ J as Confirmer,
141
+ G as confirm
60
142
  };
@@ -1,5 +1,14 @@
1
1
  /* This files contains everything that should be imported in the template */
2
2
 
3
+ /* A control that can be used right now: neither natively disabled nor marked
4
+ `data-disabled` (how Button flags a disabled `asChild` link). Gates hover/press feedback without `pointer-events: none`,
5
+ which would drop the `not-allowed` cursor and any tooltip explaining why.
6
+ `:where()` keeps specificity at zero so a consumer's `hover:` class still
7
+ wins. Declared here, not in index.css, because consumer apps compile the
8
+ laif-ds classes with their own Tailwind and only import this file.
9
+ Mirrored in tailwind.config.v3.js. */
10
+ @custom-variant interactive (&:where(:not(:disabled, [data-disabled])));
11
+
3
12
  @theme inline {
4
13
  --radius-d-sm: calc(var(--d-radius) - 4px);
5
14
  --radius-d-md: calc(var(--d-radius) - 2px);
@@ -15,5 +15,6 @@ function r() {
15
15
  }, []), !!s;
16
16
  }
17
17
  export {
18
+ e as MOBILE_BREAKPOINT,
18
19
  r as useIsMobile
19
20
  };
package/dist/index.d.ts CHANGED
@@ -952,7 +952,7 @@ export declare function BreadcrumbPage({ className, ...props }: React_2.Componen
952
952
 
953
953
  export declare function BreadcrumbSeparator({ children, className, ...props }: React_2.ComponentProps<"li">): JSX.Element;
954
954
 
955
- export declare function Button({ className, variant, size, asChild, iconLeft, iconRight, isLoading, ...props }: ButtonProps): JSX.Element;
955
+ export declare function Button({ className, variant, size, asChild, iconLeft, iconRight, isLoading, disabled, onClick, ...props }: ButtonProps): JSX.Element;
956
956
 
957
957
  export declare interface ButtonProps extends React_2.ComponentProps<"button"> {
958
958
  variant?: ButtonVariant;
@@ -2635,6 +2635,8 @@ declare interface MessageListProps {
2635
2635
 
2636
2636
  declare type MessagePart = TextPart | ReasoningPart | ToolInvocationPart | SourcePart;
2637
2637
 
2638
+ export declare const MOBILE_BREAKPOINT = 768;
2639
+
2638
2640
  /**
2639
2641
  * @deprecated This component is deprecated. Please use AppSelect component instead.
2640
2642
  */