azamat-ui-kit-cli 0.3.13 → 0.3.14

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 (30) hide show
  1. package/dist/index.cjs +807 -107
  2. package/package.json +1 -1
  3. package/vendor/src/components/data-table/data-table-pagination.tsx +1 -1
  4. package/vendor/src/components/data-table/data-table-toolbar.tsx +13 -12
  5. package/vendor/src/components/data-table/data-table.tsx +14 -14
  6. package/vendor/src/components/display/smart-card.tsx +17 -14
  7. package/vendor/src/components/form/form-input.tsx +3 -1
  8. package/vendor/src/components/form/form-textarea.tsx +15 -12
  9. package/vendor/src/components/inputs/async-select.tsx +106 -47
  10. package/vendor/src/components/inputs/clearable-input.tsx +1 -0
  11. package/vendor/src/components/inputs/input-chrome.tsx +1 -1
  12. package/vendor/src/components/inputs/input-decorator.tsx +16 -8
  13. package/vendor/src/components/inputs/simple-select.tsx +28 -28
  14. package/vendor/src/components/layout/app-sidebar.tsx +454 -154
  15. package/vendor/src/components/layout/breadcrumbs.tsx +67 -22
  16. package/vendor/src/components/layout/sidebar-nav.tsx +316 -128
  17. package/vendor/src/components/overlay/confirm-dialog.tsx +31 -20
  18. package/vendor/src/components/ui/badge.tsx +33 -32
  19. package/vendor/src/components/ui/button.tsx +15 -17
  20. package/vendor/src/components/ui/card.tsx +26 -25
  21. package/vendor/src/components/ui/dialog.tsx +6 -3
  22. package/vendor/src/components/ui/dropdown-menu.tsx +9 -9
  23. package/vendor/src/components/ui/input-primitive.tsx +1 -1
  24. package/vendor/src/components/ui/input.tsx +105 -2
  25. package/vendor/src/components/ui/popover.tsx +1 -1
  26. package/vendor/src/components/ui/select.tsx +3 -3
  27. package/vendor/src/components/ui/table.tsx +4 -4
  28. package/vendor/src/components/ui/tabs.tsx +2 -2
  29. package/vendor/src/families/member-metadata.ts +3 -3
  30. package/vendor/templates/styles/globals.css +706 -6
@@ -3,66 +3,111 @@ import { ChevronRightIcon } from "lucide-react"
3
3
 
4
4
  import { cn } from "@/lib/utils"
5
5
 
6
- export type BreadcrumbItem = {
7
- key: string
8
- label: React.ReactNode
9
- href?: string
10
- current?: boolean
11
- onSelect?: () => void
12
- }
6
+ export type BreadcrumbItem = {
7
+ key: string
8
+ label: React.ReactNode
9
+ icon?: React.ReactNode
10
+ href?: string
11
+ current?: boolean
12
+ currentLabel?: React.AriaAttributes["aria-current"]
13
+ onSelect?: () => void
14
+ }
13
15
 
14
16
  export type BreadcrumbsProps = React.ComponentProps<"nav"> & {
15
17
  items: BreadcrumbItem[]
18
+ maxItems?: number
19
+ collapseLabel?: React.ReactNode
16
20
  separator?: React.ReactNode
17
21
  renderLink?: (props: React.ComponentProps<"a"> & { item: BreadcrumbItem; [key: `data-${string}`]: string | boolean | undefined }) => React.ReactNode
18
22
  }
19
23
 
24
+ function collapseBreadcrumbItems(items: BreadcrumbItem[], maxItems: number, collapseLabel: React.ReactNode): BreadcrumbItem[] {
25
+ if (items.length <= maxItems || maxItems < 3) return items
26
+
27
+ const firstItem = items[0]
28
+ const trailingCount = Math.max(maxItems - 2, 1)
29
+ const trailingItems = items.slice(-trailingCount)
30
+
31
+ return [
32
+ firstItem,
33
+ {
34
+ key: "__collapsed__",
35
+ label: collapseLabel,
36
+ },
37
+ ...trailingItems,
38
+ ]
39
+ }
40
+
20
41
  function Breadcrumbs({
21
42
  className,
22
43
  items,
44
+ maxItems,
45
+ collapseLabel = "…",
23
46
  separator = <ChevronRightIcon className="size-3.5" />,
24
47
  renderLink,
25
48
  ...props
26
49
  }: BreadcrumbsProps) {
27
- return (
50
+ const resolvedItems = React.useMemo(
51
+ () => (typeof maxItems === "number" ? collapseBreadcrumbItems(items, maxItems, collapseLabel) : items),
52
+ [collapseLabel, items, maxItems]
53
+ )
54
+
55
+ return (
28
56
  <nav
29
57
  data-slot="breadcrumbs"
30
58
  aria-label="Breadcrumb"
31
59
  className={cn("flex min-w-0 items-center gap-1 text-sm text-muted-foreground", className)}
32
60
  {...props}
33
61
  >
34
- {items.map((item, index) => {
35
- const isLast = index === items.length - 1
36
- const isCurrent = item.current || isLast
37
-
62
+ {resolvedItems.map((item, index) => {
63
+ const isCollapsed = item.key === "__collapsed__"
64
+ const isLast = index === resolvedItems.length - 1
65
+ const isCurrent = item.current || isLast
66
+
38
67
  return (
39
68
  <React.Fragment key={item.key}>
40
69
  {index > 0 && <span className="shrink-0 opacity-60">{separator}</span>}
41
- {item.href && !isCurrent ? (
70
+ {isCollapsed ? (
71
+ <span data-slot="breadcrumbs-collapsed" className="shrink-0 rounded-full border border-border/65 px-2 py-0.5 text-xs text-muted-foreground">
72
+ {item.label}
73
+ </span>
74
+ ) : item.href && !isCurrent ? (
42
75
  renderLink ? renderLink({
43
76
  item,
44
77
  href: item.href,
78
+ "data-slot": "breadcrumbs-link",
45
79
  className: "truncate transition-colors hover:text-foreground",
46
80
  onClick: () => item.onSelect?.(),
47
- children: item.label,
81
+ children: (
82
+ <span className="inline-flex min-w-0 items-center gap-1.5">
83
+ {item.icon ? <span className="shrink-0">{item.icon}</span> : null}
84
+ <span className="truncate">{item.label}</span>
85
+ </span>
86
+ ),
48
87
  }) : (
49
88
  <a
50
89
  href={item.href}
90
+ data-slot="breadcrumbs-link"
51
91
  className="truncate transition-colors hover:text-foreground"
52
92
  onClick={() => item.onSelect?.()}
53
93
  >
54
- {item.label}
94
+ <span className="inline-flex min-w-0 items-center gap-1.5">
95
+ {item.icon ? <span className="shrink-0">{item.icon}</span> : null}
96
+ <span className="truncate">{item.label}</span>
97
+ </span>
55
98
  </a>
56
99
  )
57
100
  ) : (
58
101
  <span
59
- aria-current={isCurrent ? "page" : undefined}
60
- className={cn("truncate", isCurrent && "font-medium text-foreground")}
61
- >
62
- {item.label}
63
- </span>
64
- )}
65
- </React.Fragment>
102
+ data-slot="breadcrumbs-current"
103
+ aria-current={isCurrent ? (item.currentLabel ?? "page") : undefined}
104
+ className={cn("inline-flex min-w-0 items-center gap-1.5 truncate", isCurrent && "font-medium text-foreground")}
105
+ >
106
+ {item.icon ? <span className="shrink-0">{item.icon}</span> : null}
107
+ <span className="truncate">{item.label}</span>
108
+ </span>
109
+ )}
110
+ </React.Fragment>
66
111
  )
67
112
  })}
68
113
  </nav>
@@ -1,147 +1,335 @@
1
1
  import * as React from "react"
2
2
 
3
3
  import { Badge } from "@/components/ui/badge"
4
+ import { Tooltip } from "@/components/ui/tooltip"
4
5
  import { cn } from "@/lib/utils"
5
-
6
- export type SidebarNavItem = {
7
- key: string
8
- label: React.ReactNode
9
- icon?: React.ReactNode
10
- badge?: React.ReactNode
11
- href?: string
12
- active?: boolean
13
- disabled?: boolean
14
- hidden?: boolean
15
- onSelect?: () => void
16
- }
17
-
6
+
7
+ export type SidebarNavItem = {
8
+ key: string
9
+ label: React.ReactNode
10
+ icon?: React.ReactNode
11
+ badge?: React.ReactNode
12
+ href?: string
13
+ items?: SidebarNavItem[]
14
+ active?: boolean
15
+ current?: React.AriaAttributes["aria-current"]
16
+ disabled?: boolean
17
+ hidden?: boolean
18
+ sectionLabel?: React.ReactNode
19
+ defaultExpanded?: boolean
20
+ tooltip?: React.ReactNode
21
+ onSelect?: () => void
22
+ }
23
+
18
24
  export type SidebarNavProps = React.ComponentProps<"nav"> & {
19
25
  items: SidebarNavItem[]
20
26
  collapsed?: boolean
27
+ tooltipOnCollapsed?: boolean
21
28
  itemClassName?: string
22
29
  activeItemClassName?: string
23
30
  renderItem?: (item: SidebarNavItem, element: React.ReactNode) => React.ReactNode
24
31
  renderLink?: (props: React.ComponentProps<"a"> & { item: SidebarNavItem; [key: `data-${string}`]: string | boolean | undefined }) => React.ReactNode
25
32
  }
26
-
27
- function SidebarNav({
28
- className,
29
- items,
30
- collapsed = false,
33
+
34
+ function hasVisibleChildren(item: SidebarNavItem) {
35
+ return item.items?.some((child) => !child.hidden) ?? false
36
+ }
37
+
38
+ function isActiveItem(item: SidebarNavItem): boolean {
39
+ if (item.active) return true
40
+ return item.items?.some((child) => isActiveItem(child)) ?? false
41
+ }
42
+
43
+ function SidebarLeaf({
44
+ item,
45
+ collapsed,
46
+ depth,
47
+ itemClassName,
48
+ activeItemClassName,
49
+ renderLink,
50
+ }: {
51
+ item: SidebarNavItem
52
+ collapsed: boolean
53
+ depth: number
54
+ itemClassName?: string
55
+ activeItemClassName?: string
56
+ renderLink?: SidebarNavProps["renderLink"]
57
+ }) {
58
+ const currentValue: React.AriaAttributes["aria-current"] = item.current ?? (item.active ? "page" : undefined)
59
+ const content = (
60
+ <>
61
+ {item.icon && <span className="shrink-0 [&_svg]:size-4">{item.icon}</span>}
62
+ {!collapsed && <span className="min-w-0 flex-1 truncate">{item.label}</span>}
63
+ {!collapsed && item.badge && (
64
+ <Badge variant="secondary" className="ml-auto h-5 shrink-0 px-1.5">
65
+ {item.badge}
66
+ </Badge>
67
+ )}
68
+ </>
69
+ )
70
+
71
+ const commonClassName = cn(
72
+ "group flex min-h-8 items-center gap-2 rounded-lg border border-transparent px-2 text-sm font-medium transition-[background-color,border-color,color,box-shadow] data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50",
73
+ collapsed && "justify-center px-0",
74
+ depth > 0 && !collapsed && "pl-3",
75
+ itemClassName,
76
+ item.active && activeItemClassName
77
+ )
78
+
79
+ const wrapCollapsed = (node: React.ReactNode) =>
80
+ collapsed ? (
81
+ <Tooltip content={item.tooltip ?? item.label} side="right">
82
+ <span className="block">{node}</span>
83
+ </Tooltip>
84
+ ) : (
85
+ node
86
+ )
87
+
88
+ const internal = item.href && item.href.startsWith("/")
89
+
90
+ if (internal) {
91
+ if (renderLink) {
92
+ return wrapCollapsed(
93
+ renderLink({
94
+ item,
95
+ href: item.href,
96
+ "data-slot": "sidebar-nav-item",
97
+ "data-depth": String(depth),
98
+ "data-active": item.active || undefined,
99
+ "data-disabled": item.disabled || undefined,
100
+ "aria-current": currentValue,
101
+ className: commonClassName,
102
+ onClick: (event) => {
103
+ if (item.disabled) {
104
+ event.preventDefault()
105
+ return
106
+ }
107
+ item.onSelect?.()
108
+ },
109
+ children: content,
110
+ })
111
+ )
112
+ }
113
+
114
+ return wrapCollapsed(
115
+ <a
116
+ href={item.href}
117
+ data-slot="sidebar-nav-item"
118
+ data-depth={depth}
119
+ data-active={item.active || undefined}
120
+ data-disabled={item.disabled || undefined}
121
+ aria-current={currentValue}
122
+ className={commonClassName}
123
+ onClick={(event) => {
124
+ if (item.disabled) {
125
+ event.preventDefault()
126
+ return
127
+ }
128
+ item.onSelect?.()
129
+ }}
130
+ >
131
+ {content}
132
+ </a>
133
+ )
134
+ }
135
+
136
+ if (item.href) {
137
+ return wrapCollapsed(
138
+ <button
139
+ type="button"
140
+ data-slot="sidebar-nav-item"
141
+ data-depth={depth}
142
+ data-active={item.active || undefined}
143
+ data-disabled={item.disabled || undefined}
144
+ aria-current={currentValue}
145
+ className={cn("w-full text-left", commonClassName)}
146
+ onClick={() => {
147
+ if (item.disabled) return
148
+ const href = item.href
149
+ if (!href) return
150
+ item.onSelect?.()
151
+ if (href.startsWith("http")) {
152
+ window.open(href, "_blank", "noopener,noreferrer")
153
+ return
154
+ }
155
+ window.location.assign(href)
156
+ }}
157
+ >
158
+ {content}
159
+ </button>
160
+ )
161
+ }
162
+
163
+ return wrapCollapsed(
164
+ <button
165
+ type="button"
166
+ data-slot="sidebar-nav-item"
167
+ data-depth={depth}
168
+ data-active={item.active || undefined}
169
+ data-disabled={item.disabled || undefined}
170
+ aria-current={currentValue}
171
+ disabled={item.disabled}
172
+ className={cn("w-full text-left", commonClassName)}
173
+ onClick={item.onSelect}
174
+ >
175
+ {content}
176
+ </button>
177
+ )
178
+ }
179
+
180
+ function SidebarTree({
181
+ items,
182
+ collapsed,
183
+ depth,
31
184
  itemClassName,
32
185
  activeItemClassName,
33
186
  renderItem,
34
187
  renderLink,
35
- ...props
36
- }: SidebarNavProps) {
37
- const visibleItems = items.filter((item) => !item.hidden)
38
-
39
- return (
40
- <nav
41
- data-slot="sidebar-nav"
42
- data-collapsed={collapsed || undefined}
43
- className={cn("grid gap-1", className)}
44
- {...props}
45
- >
46
- {visibleItems.map((item) => {
47
- const content = (
48
- <>
49
- {item.icon && <span className="shrink-0 [&_svg]:size-4">{item.icon}</span>}
50
- {!collapsed && <span className="min-w-0 flex-1 truncate">{item.label}</span>}
51
- {!collapsed && item.badge && (
52
- <Badge variant="secondary" className="ml-auto h-5 shrink-0 px-1.5">
53
- {item.badge}
54
- </Badge>
55
- )}
56
- </>
57
- )
58
-
59
- const commonClassName = cn(
60
- "group flex min-h-8 items-center gap-2 rounded-lg px-2 text-sm font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground data-[active=true]:bg-muted data-[active=true]:text-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50",
61
- collapsed && "justify-center px-0",
62
- itemClassName,
63
- item.active && activeItemClassName
64
- )
65
-
66
- const isInternalLink = item.href && item.href.startsWith("/")
67
-
68
- const element = item.href && isInternalLink ? (
69
- renderLink ? (
70
- <React.Fragment key={item.key}>
71
- {renderLink({
72
- item,
73
- href: item.href,
74
- "data-active": item.active || undefined,
75
- "data-disabled": item.disabled || undefined,
76
- "aria-current": item.active ? "page" : undefined,
77
- className: commonClassName,
78
- onClick: (event) => {
79
- if (item.disabled) event.preventDefault()
80
- item.onSelect?.()
81
- },
82
- children: content,
83
- })}
84
- </React.Fragment>
85
- ) : (
86
- <a
87
- key={item.key}
88
- href={item.href}
89
- data-active={item.active || undefined}
90
- data-disabled={item.disabled || undefined}
91
- aria-current={item.active ? "page" : undefined}
92
- className={commonClassName}
93
- onClick={(event) => {
94
- if (item.disabled) event.preventDefault()
95
- item.onSelect?.()
96
- }}
188
+ }: {
189
+ items: SidebarNavItem[]
190
+ collapsed: boolean
191
+ depth: number
192
+ itemClassName?: string
193
+ activeItemClassName?: string
194
+ renderItem?: SidebarNavProps["renderItem"]
195
+ renderLink?: SidebarNavProps["renderLink"]
196
+ }) {
197
+ return items.map((item) => {
198
+ if (item.hidden) return null
199
+
200
+ const showSectionLabel = !collapsed && depth === 0 && item.sectionLabel
201
+ const hasChildren = hasVisibleChildren(item)
202
+
203
+ if (!hasChildren) {
204
+ const element = (
205
+ <SidebarLeaf
206
+ item={item}
207
+ collapsed={collapsed}
208
+ depth={depth}
209
+ itemClassName={itemClassName}
210
+ activeItemClassName={activeItemClassName}
211
+ renderLink={renderLink}
212
+ />
213
+ )
214
+
215
+ return (
216
+ <React.Fragment key={item.key}>
217
+ {showSectionLabel ? (
218
+ <div
219
+ data-slot="sidebar-nav-group-label"
220
+ className="px-2 pb-1 pt-3 text-[11px] font-semibold uppercase tracking-[0.14em] text-muted-foreground first:pt-0"
97
221
  >
98
- {content}
99
- </a>
222
+ {item.sectionLabel}
223
+ </div>
224
+ ) : null}
225
+ {renderItem ? renderItem(item, element) : element}
226
+ </React.Fragment>
227
+ )
228
+ }
229
+
230
+ const isExpanded = item.defaultExpanded ?? isActiveItem(item)
231
+ const trigger = (
232
+ <summary
233
+ data-slot="sidebar-nav-group-trigger"
234
+ className={cn(
235
+ "flex min-h-8 list-none items-center gap-2 rounded-lg border border-transparent text-sm font-medium transition-[background-color,border-color,color,box-shadow]",
236
+ collapsed ? "justify-center px-0" : "px-2"
237
+ )}
238
+ >
239
+ {item.icon ? (
240
+ collapsed ? (
241
+ <Tooltip content={item.tooltip ?? item.label} side="right">
242
+ <span className="shrink-0 [&_svg]:size-4">{item.icon}</span>
243
+ </Tooltip>
244
+ ) : (
245
+ <span className="shrink-0 [&_svg]:size-4">{item.icon}</span>
100
246
  )
101
- ) : item.href ? (
102
- <button
103
- key={item.key}
104
- type="button"
105
- data-active={item.active || undefined}
106
- data-disabled={item.disabled || undefined}
107
- aria-current={item.active ? "page" : undefined}
108
- className={cn("w-full text-left", commonClassName)}
109
- onClick={() => {
110
- if (item.disabled) return
111
- const href = item.href
112
- if (!href) return
113
- item.onSelect?.()
114
- if (href.startsWith("http")) {
115
- window.open(href, "_blank", "noopener,noreferrer")
116
- return
117
- }
118
- window.location.assign(href)
119
- }}
247
+ ) : null}
248
+ {!collapsed && <span className="min-w-0 flex-1 truncate">{item.label}</span>}
249
+ {!collapsed && item.badge ? (
250
+ <Badge variant="secondary" className="h-5 shrink-0 px-1.5">
251
+ {item.badge}
252
+ </Badge>
253
+ ) : null}
254
+ {!collapsed && (
255
+ <span
256
+ data-slot="sidebar-nav-group-chevron"
257
+ className="ml-auto text-xs text-muted-foreground transition-transform group-open/sidebar-nav-details:rotate-90"
258
+ >
259
+
260
+ </span>
261
+ )}
262
+ </summary>
263
+ )
264
+
265
+ const groupElement = (
266
+ <div data-slot="sidebar-nav-group" data-depth={depth}>
267
+ {showSectionLabel ? (
268
+ <div
269
+ data-slot="sidebar-nav-group-label"
270
+ className="px-2 pb-1 pt-3 text-[11px] font-semibold uppercase tracking-[0.14em] text-muted-foreground first:pt-0"
271
+ >
272
+ {item.sectionLabel}
273
+ </div>
274
+ ) : null}
275
+ <details
276
+ data-slot="sidebar-nav-group-details"
277
+ open={isExpanded}
278
+ className="group/sidebar-nav-details"
279
+ >
280
+ {trigger}
281
+ <div
282
+ data-slot="sidebar-nav-group-content"
283
+ className={cn("mt-1 grid gap-1", !collapsed && "ml-3 border-l border-border/55 pl-2")}
120
284
  >
121
- {content}
122
- </button>
123
- ) : (
124
- <button
125
- key={item.key}
126
- type="button"
127
- data-active={item.active || undefined}
128
- data-disabled={item.disabled || undefined}
129
- disabled={item.disabled}
130
- className={cn("w-full text-left", commonClassName)}
131
- onClick={item.onSelect}
132
- >
133
- {content}
134
- </button>
135
- )
136
-
137
- return renderItem ? (
138
- <React.Fragment key={item.key}>{renderItem(item, element)}</React.Fragment>
139
- ) : (
140
- element
141
- )
142
- })}
143
- </nav>
144
- )
145
- }
146
-
147
- export { SidebarNav }
285
+ <SidebarTree
286
+ items={item.items ?? []}
287
+ collapsed={collapsed}
288
+ depth={depth + 1}
289
+ itemClassName={itemClassName}
290
+ activeItemClassName={activeItemClassName}
291
+ renderItem={renderItem}
292
+ renderLink={renderLink}
293
+ />
294
+ </div>
295
+ </details>
296
+ </div>
297
+ )
298
+
299
+ return renderItem ? <React.Fragment key={item.key}>{renderItem(item, groupElement)}</React.Fragment> : <React.Fragment key={item.key}>{groupElement}</React.Fragment>
300
+ })
301
+ }
302
+
303
+ function SidebarNav({
304
+ className,
305
+ items,
306
+ collapsed = false,
307
+ itemClassName,
308
+ activeItemClassName,
309
+ renderItem,
310
+ renderLink,
311
+ ...props
312
+ }: SidebarNavProps) {
313
+ const visibleItems = items.filter((item) => !item.hidden)
314
+
315
+ return (
316
+ <nav
317
+ data-slot="sidebar-nav"
318
+ data-collapsed={collapsed || undefined}
319
+ className={cn("grid gap-1", className)}
320
+ {...props}
321
+ >
322
+ <SidebarTree
323
+ items={visibleItems}
324
+ collapsed={collapsed}
325
+ depth={0}
326
+ itemClassName={itemClassName}
327
+ activeItemClassName={activeItemClassName}
328
+ renderItem={renderItem}
329
+ renderLink={renderLink}
330
+ />
331
+ </nav>
332
+ )
333
+ }
334
+
335
+ export { SidebarNav }
@@ -27,17 +27,28 @@ function ConfirmDialog({
27
27
  onConfirm,
28
28
  onOpenChange,
29
29
  ...props
30
- }: ConfirmDialogProps) {
31
- const handleCancel = () => {
32
- onCancel?.()
33
- onOpenChange?.(false)
34
- }
35
-
36
- return (
37
- <ModalShell
38
- onOpenChange={onOpenChange}
39
- footer={
40
- <DialogActions>
30
+ }: ConfirmDialogProps) {
31
+ const handleOpenChange = (open: boolean) => {
32
+ if (isLoading && open === false) {
33
+ return
34
+ }
35
+
36
+ onOpenChange?.(open)
37
+ }
38
+
39
+ const handleCancel = () => {
40
+ onCancel?.()
41
+ if (!isLoading) {
42
+ onOpenChange?.(false)
43
+ }
44
+ }
45
+
46
+ return (
47
+ <ModalShell
48
+ showCloseButton={!isLoading}
49
+ onOpenChange={handleOpenChange}
50
+ footer={
51
+ <DialogActions>
41
52
  <DialogActionButton
42
53
  type="button"
43
54
  variant="outline"
@@ -46,15 +57,15 @@ function ConfirmDialog({
46
57
  >
47
58
  {cancelText}
48
59
  </DialogActionButton>
49
- <DialogActionButton
50
- type="button"
51
- variant={confirmVariant}
52
- disabled={confirmDisabled}
53
- isLoading={isLoading}
54
- onClick={onConfirm}
55
- >
56
- {confirmText}
57
- </DialogActionButton>
60
+ <DialogActionButton
61
+ type="button"
62
+ variant={confirmVariant}
63
+ disabled={confirmDisabled || isLoading}
64
+ isLoading={isLoading}
65
+ onClick={onConfirm}
66
+ >
67
+ {confirmText}
68
+ </DialogActionButton>
58
69
  </DialogActions>
59
70
  }
60
71
  {...props}