@bsginstitute/bsg-integra 0.0.3 → 0.0.5

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,10 +1,10 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, signal, computed, Component, inject, output, contentChildren, viewChild, effect, HostListener, linkedSignal, forwardRef, HostBinding, Directive, ElementRef, model, Injectable, PLATFORM_ID, ChangeDetectionStrategy, ViewChild } from '@angular/core';
2
+ import { input, signal, computed, Component, inject, output, contentChildren, viewChild, effect, HostListener, linkedSignal, forwardRef, HostBinding, Directive, ElementRef, model, Injectable, PLATFORM_ID, ChangeDetectionStrategy, EventEmitter, Output, Input, ViewChild } from '@angular/core';
3
3
  import { clsx } from 'clsx';
4
4
  import { cva } from 'class-variance-authority';
5
5
  import * as i1 from '@angular/platform-browser';
6
6
  import * as i1$2 from '@angular/common';
7
- import { DOCUMENT, CommonModule, isPlatformBrowser } from '@angular/common';
7
+ import { DOCUMENT, CommonModule, isPlatformBrowser, NgTemplateOutlet } from '@angular/common';
8
8
  import * as i1$1 from '@angular/forms';
9
9
  import { NG_VALUE_ACCESSOR, FormsModule, NG_VALIDATORS } from '@angular/forms';
10
10
 
@@ -338,11 +338,11 @@ const alertVariants = cva(clsx(
338
338
  'box-border'), {
339
339
  variants: {
340
340
  variant: {
341
- default: 'text-sky-600',
342
- info: 'bg-blue-200 text-blue-600',
343
- success: 'bg-green-200 text-green-600',
344
- warning: 'bg-yellow-200 text-yellow-600',
345
- destructive: 'bg-red-200 text-red-600',
341
+ default: 'text-muted-foreground',
342
+ info: 'bg-info/20 text-info',
343
+ success: 'bg-success/20 text-success',
344
+ warning: 'bg-warning/20 text-warning',
345
+ destructive: 'bg-destructive/20 text-destructive',
346
346
  },
347
347
  },
348
348
  defaultVariants: {
@@ -718,8 +718,8 @@ const avatarVariants = cva(clsx(
718
718
  },
719
719
  type: {
720
720
  default: 'bg-transparent',
721
- fallback: 'bg-violet-600',
722
- image: 'bg-neutral-100',
721
+ fallback: 'bg-primary',
722
+ image: 'bg-muted',
723
723
  },
724
724
  },
725
725
  defaultVariants: {
@@ -734,7 +734,7 @@ const avatarVariants = cva(clsx(
734
734
  */
735
735
  const avatarInitialsVariants = cva(clsx(
736
736
  // Color
737
- 'text-white',
737
+ 'text-primary-foreground',
738
738
  // Typography
739
739
  'font-sans font-normal tracking-wide',
740
740
  // Layout
@@ -980,11 +980,11 @@ const badgeVariants = cva(clsx(
980
980
  'pointer-events-none select-none'), {
981
981
  variants: {
982
982
  variant: {
983
- default: 'bg-violet-600 text-white',
984
- secondary: 'bg-blue-600 text-white',
985
- destructive: 'bg-red-600 text-white',
986
- success: 'bg-green-600 text-white',
987
- outline: 'bg-white text-slate-800 border border-slate-300',
983
+ default: 'bg-primary text-primary-foreground',
984
+ secondary: 'bg-secondary text-secondary-foreground',
985
+ destructive: 'bg-destructive text-destructive-foreground',
986
+ success: 'bg-success text-success-foreground',
987
+ outline: 'bg-background text-foreground border border-border',
988
988
  },
989
989
  size: {
990
990
  dot: 'w-3 h-3', // 12x12
@@ -1001,7 +1001,7 @@ const badgeVariants = cva(clsx(
1001
1001
  {
1002
1002
  variant: 'outline',
1003
1003
  size: 'dot',
1004
- class: 'bg-transparent border border-slate-300',
1004
+ class: 'bg-transparent border border-border',
1005
1005
  },
1006
1006
  // Default size "text" (pequeño)
1007
1007
  {
@@ -1138,28 +1138,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
1138
1138
  `, styles: [":host{display:inline-block}\n"] }]
1139
1139
  }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }] } });
1140
1140
 
1141
- /**
1142
- * Button variants
1143
- *
1144
- * Controls the button styles including size, variant, shape, and state
1145
- */
1146
- const buttonVariants = cva(clsx(
1147
- // Layout
1148
- 'inline-flex items-center justify-center',
1149
- // Gap
1150
- 'gap-2.5',
1151
- // Typography
1152
- 'text-sm font-medium leading-normal tracking-tight',
1153
- // Cursor
1154
- 'cursor-pointer',
1155
- // Transition
1156
- 'transition-all duration-200',
1157
- // Whitespace
1158
- 'whitespace-nowrap',
1159
- // Border reset
1160
- 'border-0',
1161
- // Focus outline reset (prevent focus ring on click)
1162
- 'outline-none'), {
1141
+ // projects/bsg-integra/src/lib/components/button/button.variants.ts
1142
+ const buttonVariants = cva(clsx('inline-flex items-center justify-center', 'gap-2.5', 'text-sm font-medium leading-normal tracking-tight', 'cursor-pointer', 'transition-all duration-200', 'whitespace-nowrap', 'border-0', 'outline-none', 'relative'), {
1163
1143
  variants: {
1164
1144
  size: {
1165
1145
  sm: 'h-[27px] py-2 px-4',
@@ -1169,7 +1149,7 @@ const buttonVariants = cva(clsx(
1169
1149
  variant: {
1170
1150
  default: clsx('bg-violet-600 text-white', 'hover:opacity-90', 'active:shadow-[inset_0_2px_4px_0_rgba(0,0,0,0.12)]', 'focus-visible:bg-violet-900 focus-visible:ring-2 focus-visible:ring-violet-600 focus-visible:ring-offset-2'),
1171
1151
  secondary: clsx('bg-blue-600 text-white', 'hover:opacity-90', 'active:shadow-[inset_0_2px_4px_0_rgba(0,0,0,0.12)]', 'focus-visible:bg-blue-700 focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2'),
1172
- outline: clsx('bg-transparent text-violet-600 border border-violet-600', 'hover:opacity-90', 'active:shadow-[inset_0_2px_4px_0_rgba(0,0,0,0.12)]', 'focus-visible:border-violet-900 focus-visible:text-violet-900 focus-visible:ring-2 focus-visible:ring-violet-600 focus-visible:ring-offset-2'),
1152
+ outline: clsx('bg-transparent text-violet-600 border border-violet-600', 'hover:bg-violet-50', 'active:bg-violet-100', 'focus-visible:border-violet-900 focus-visible:text-violet-900 focus-visible:ring-2 focus-visible:ring-violet-600 focus-visible:ring-offset-2'),
1173
1153
  ghost: clsx('bg-violet-100 text-slate-800', 'hover:opacity-90', 'active:shadow-[inset_0_2px_4px_0_rgba(0,0,0,0.12)]', 'focus-visible:bg-violet-200 focus-visible:ring-2 focus-visible:ring-violet-600 focus-visible:ring-offset-2'),
1174
1154
  link: clsx('bg-transparent text-blue-600', 'hover:opacity-90', 'active:underline', 'focus-visible:text-blue-700 focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2'),
1175
1155
  destructive: clsx('bg-red-600 text-white', 'hover:opacity-90', 'active:shadow-[inset_0_2px_4px_0_rgba(0,0,0,0.12)]', 'focus-visible:bg-red-700 focus-visible:ring-2 focus-visible:ring-red-600 focus-visible:ring-offset-2'),
@@ -1179,7 +1159,7 @@ const buttonVariants = cva(clsx(
1179
1159
  pill: 'rounded-full',
1180
1160
  icon: 'rounded-md',
1181
1161
  'icon-text': 'rounded-md',
1182
- 'icon-only': 'rounded-full p-0',
1162
+ 'icon-only': 'rounded-full',
1183
1163
  },
1184
1164
  disabled: {
1185
1165
  true: 'opacity-40 cursor-not-allowed pointer-events-none',
@@ -1187,57 +1167,49 @@ const buttonVariants = cva(clsx(
1187
1167
  },
1188
1168
  },
1189
1169
  compoundVariants: [
1190
- // Icon shape sizes
1191
1170
  { shape: 'icon', size: 'sm', class: 'w-[27px] h-[27px] p-2' },
1192
1171
  { shape: 'icon', size: 'md', class: 'w-[35px] h-[35px] p-2' },
1193
1172
  { shape: 'icon', size: 'lg', class: 'w-[43px] h-[43px] p-2' },
1194
- // Icon-only shape sizes
1195
1173
  {
1196
1174
  shape: 'icon-only',
1197
1175
  size: 'sm',
1198
- class: 'w-[27px] h-[27px] min-w-[27px] min-h-[27px]',
1176
+ class: 'w-[27px] h-[27px] min-w-[27px] min-h-[27px] p-0',
1199
1177
  },
1200
1178
  {
1201
1179
  shape: 'icon-only',
1202
1180
  size: 'md',
1203
- class: 'w-[35px] h-[35px] min-w-[35px] min-h-[35px]',
1181
+ class: 'w-[35px] h-[35px] min-w-[35px] min-h-[35px] p-0',
1204
1182
  },
1205
1183
  {
1206
1184
  shape: 'icon-only',
1207
1185
  size: 'lg',
1208
- class: 'w-[43px] h-[43px] min-w-[43px] min-h-[43px]',
1186
+ class: 'w-[43px] h-[43px] min-w-[43px] min-h-[43px] p-0',
1209
1187
  },
1210
- // Icon-only + outline variant
1211
1188
  {
1212
1189
  shape: 'icon-only',
1213
1190
  variant: 'outline',
1214
1191
  class: 'bg-transparent border border-slate-300 text-purple-600 hover:opacity-90 active:border-purple-600 focus-visible:border-slate-500 focus-visible:text-purple-800 focus-visible:ring-2 focus-visible:ring-purple-600 focus-visible:ring-offset-2',
1215
1192
  },
1216
- // Icon-only + default variant
1217
1193
  {
1218
1194
  shape: 'icon-only',
1219
1195
  variant: 'default',
1220
1196
  class: 'bg-violet-600 text-white border border-violet-600',
1221
1197
  },
1222
- // Icon-only + secondary variant
1223
1198
  {
1224
1199
  shape: 'icon-only',
1225
1200
  variant: 'secondary',
1226
1201
  class: 'bg-blue-600 text-white border border-blue-600',
1227
1202
  },
1228
- // Icon-only + ghost variant
1229
1203
  {
1230
1204
  shape: 'icon-only',
1231
1205
  variant: 'ghost',
1232
1206
  class: 'bg-violet-100 text-slate-800 border border-violet-100',
1233
1207
  },
1234
- // Icon-only + link variant
1235
1208
  {
1236
1209
  shape: 'icon-only',
1237
1210
  variant: 'link',
1238
1211
  class: 'bg-transparent text-blue-600 border border-transparent',
1239
1212
  },
1240
- // Icon-only + destructive variant
1241
1213
  {
1242
1214
  shape: 'icon-only',
1243
1215
  variant: 'destructive',
@@ -1251,14 +1223,7 @@ const buttonVariants = cva(clsx(
1251
1223
  disabled: false,
1252
1224
  },
1253
1225
  });
1254
- /**
1255
- * Button icon variants
1256
- *
1257
- * Controls the icon styling within buttons
1258
- */
1259
- const buttonIconVariants = cva(clsx(
1260
- // Layout
1261
- 'shrink-0'), {
1226
+ const buttonIconVariants = cva(clsx('inline-flex items-center justify-center shrink-0 leading-none'), {
1262
1227
  variants: {
1263
1228
  position: {
1264
1229
  left: '-mr-0.5',
@@ -1270,187 +1235,124 @@ const buttonIconVariants = cva(clsx(
1270
1235
  position: 'left',
1271
1236
  },
1272
1237
  });
1273
- /**
1274
- * Button label variants
1275
- *
1276
- * Controls the label text styling
1277
- */
1278
- const buttonLabelVariants = cva(clsx(
1279
- // Layout
1280
- 'inline-block'));
1281
- /**
1282
- * Button icon-only wrapper variants
1283
- *
1284
- * Controls the icon wrapper for icon-only buttons
1285
- */
1286
- const buttonIconOnlyVariants = cva(clsx(
1287
- // Layout
1288
- 'flex items-center justify-center', 'w-full h-full'), {
1238
+ const buttonLabelVariants = cva(clsx('inline-block'));
1239
+ const buttonIconOnlyVariants = cva(clsx('flex items-center justify-center leading-none'), {
1289
1240
  variants: {
1290
- size: {
1291
- sm: 'w-[17px] h-[17px]',
1292
- md: 'w-[21px] h-[21px]',
1293
- lg: 'w-[26px] h-[26px]',
1241
+ size: { sm: '', md: '', lg: '' },
1242
+ },
1243
+ defaultVariants: { size: 'md' },
1244
+ });
1245
+ /** ✅ nuevo: spinner overlay centrado */
1246
+ const buttonSpinnerVariants = cva(clsx('absolute inset-0 flex items-center justify-center'), {
1247
+ variants: {
1248
+ shape: {
1249
+ rectangular: '',
1250
+ pill: '',
1251
+ icon: '',
1252
+ 'icon-text': '',
1253
+ 'icon-only': '',
1294
1254
  },
1295
1255
  },
1296
1256
  defaultVariants: {
1297
- size: 'md',
1257
+ shape: 'rectangular',
1298
1258
  },
1299
1259
  });
1300
1260
 
1301
- // Icon definitions for icon-only buttons
1302
- const icons = {
1303
- 'chevron-left': `<svg width="100%" height="100%" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
1304
- <path d="M9.64776 3.57275C9.91136 3.30915 10.3386 3.30915 10.6023 3.57275C10.8659 3.83636 10.8659 4.26364 10.6023 4.52724L7.0295 8.1L10.6023 11.6728C10.8659 11.9364 10.8659 12.3636 10.6023 12.6272C10.3386 12.8908 9.91136 12.8908 9.64776 12.6272L5.59776 8.57724C5.33415 8.31364 5.33415 7.88636 5.59776 7.62275L9.64776 3.57275Z" fill="currentColor"/>
1305
- </svg>`,
1306
- 'chevron-right': `<svg width="100%" height="100%" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
1307
- <path d="M6.35224 3.57275C6.08864 3.30915 5.66136 3.30915 5.39776 3.57275C5.13415 3.83636 5.13415 4.26364 5.39776 4.52724L8.9705 8.1L5.39776 11.6728C5.13415 11.9364 5.13415 12.3636 5.39776 12.6272C5.66136 12.8908 6.08864 12.8908 6.35224 12.6272L10.4022 8.57724C10.6659 8.31364 10.6659 7.88636 10.4022 7.62275L6.35224 3.57275Z" fill="currentColor"/>
1308
- </svg>`,
1309
- 'chevron-up': `<svg width="100%" height="100%" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
1310
- <path d="M3.57275 9.64776C3.30915 9.91136 3.30915 10.3386 3.57275 10.6023C3.83636 10.8659 4.26364 10.8659 4.52724 10.6023L8.1 7.0295L11.6728 10.6023C11.9364 10.8659 12.3636 10.8659 12.6272 10.6023C12.8908 10.3386 12.8908 9.91136 12.6272 9.64776L8.57724 5.59776C8.31364 5.33415 7.88636 5.33415 7.62275 5.59776L3.57275 9.64776Z" fill="currentColor"/>
1311
- </svg>`,
1312
- 'chevron-down': `<svg width="100%" height="100%" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
1313
- <path d="M3.57275 6.35224C3.30915 6.08864 3.30915 5.66136 3.57275 5.39776C3.83636 5.13415 4.26364 5.13415 4.52724 5.39776L8.1 8.9705L11.6728 5.39776C11.9364 5.13415 12.3636 5.13415 12.6272 5.39776C12.8908 5.66136 12.8908 6.08864 12.6272 6.35224L8.57724 10.4022C8.31364 10.6659 7.88636 10.6659 7.62275 10.4022L3.57275 6.35224Z" fill="currentColor"/>
1314
- </svg>`,
1315
- check: `<svg width="100%" height="100%" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
1316
- <path d="M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z" fill="currentColor"/>
1317
- </svg>`,
1318
- none: '',
1319
- };
1320
- /**
1321
- * Button Component - Interactive button with multiple variants
1322
- *
1323
- * Following shadcn/ui pattern:
1324
- * ```html
1325
- * <bsg-button
1326
- * [variant]="'default'"
1327
- * [size]="'md'"
1328
- * [shape]="'rectangular'"
1329
- * [label]="'Click me'"
1330
- * (Click)="onClick()"
1331
- * />
1332
- * ```
1333
- */
1334
1261
  class ButtonComponent {
1335
- sanitizer;
1336
- constructor(sanitizer) {
1337
- this.sanitizer = sanitizer;
1338
- }
1339
- /** Size of the button */
1340
1262
  size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
1341
- /** Visual variant of the button */
1342
1263
  variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
1343
- /** Shape of the button */
1344
1264
  shape = input('rectangular', ...(ngDevMode ? [{ debugName: "shape" }] : []));
1345
- /** Button label text */
1346
1265
  label = input('Boton', ...(ngDevMode ? [{ debugName: "label" }] : []));
1347
- /** Show icon */
1348
- icon = input(false, ...(ngDevMode ? [{ debugName: "icon" }] : []));
1349
- /** Icon position (left or right) */
1350
- iconPosition = input('left', ...(ngDevMode ? [{ debugName: "iconPosition" }] : []));
1351
- /** Icon name for icon-only buttons */
1352
- iconName = input('chevron-left', ...(ngDevMode ? [{ debugName: "iconName" }] : []));
1353
- /** Disabled state */
1354
1266
  disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
1355
- /** Additional CSS classes */
1267
+ /** nuevo: muestra spinner y bloquea click */
1268
+ spinner = input(false, ...(ngDevMode ? [{ debugName: "spinner" }] : []));
1269
+ /** Accesibilidad para icon buttons */
1270
+ ariaLabel = input(null, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
1356
1271
  className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
1357
- /** Click event emitter */
1358
1272
  Click = output();
1359
- // Computed disabled state
1360
- isDisabled = computed(() => this.disabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
1361
- // Computed button classes
1273
+ isDisabled = computed(() => this.disabled() || this.spinner(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
1274
+ isIconButton = computed(() => this.shape() === 'icon-only' || this.shape() === 'icon', ...(ngDevMode ? [{ debugName: "isIconButton" }] : []));
1275
+ buttonSquarePx = computed(() => this.size() === 'sm' ? 27 : this.size() === 'lg' ? 43 : 35, ...(ngDevMode ? [{ debugName: "buttonSquarePx" }] : []));
1276
+ iconFontPx = computed(() => this.size() === 'sm' ? 15 : this.size() === 'lg' ? 22 : 18, ...(ngDevMode ? [{ debugName: "iconFontPx" }] : []));
1277
+ spinnerPx = computed(() => this.size() === 'sm' ? 14 : this.size() === 'lg' ? 20 : 16, ...(ngDevMode ? [{ debugName: "spinnerPx" }] : []));
1362
1278
  buttonClasses = computed(() => clsx(buttonVariants({
1363
1279
  size: this.size(),
1364
1280
  variant: this.variant(),
1365
1281
  shape: this.shape(),
1366
- disabled: this.disabled(),
1367
- }), this.icon() && 'btn-with-icon', this.className()), ...(ngDevMode ? [{ debugName: "buttonClasses" }] : []));
1368
- // Computed icon classes
1369
- iconClasses(position) {
1370
- return clsx(buttonIconVariants({ position }), this.shape() === 'icon' && 'm-0');
1371
- }
1372
- // Computed label classes
1282
+ disabled: this.isDisabled(),
1283
+ }), this.className()), ...(ngDevMode ? [{ debugName: "buttonClasses" }] : []));
1373
1284
  labelClasses = computed(() => clsx(buttonLabelVariants()), ...(ngDevMode ? [{ debugName: "labelClasses" }] : []));
1374
- // Computed icon-only wrapper classes
1375
1285
  iconOnlyClasses = computed(() => clsx(buttonIconOnlyVariants({ size: this.size() })), ...(ngDevMode ? [{ debugName: "iconOnlyClasses" }] : []));
1376
- // Computed icon color based on variant
1377
- iconColor = computed(() => {
1378
- const variantVal = this.variant();
1379
- if (variantVal === 'outline')
1380
- return '#7C3AED';
1381
- if (variantVal === 'ghost')
1382
- return '#1E293B';
1383
- if (variantVal === 'link')
1384
- return '#2563EB';
1385
- return 'white';
1386
- }, ...(ngDevMode ? [{ debugName: "iconColor" }] : []));
1387
- getIconSvg(iconName) {
1388
- const svg = icons[iconName] || icons['none'];
1389
- return this.sanitizer.bypassSecurityTrustHtml(svg);
1286
+ spinnerClasses = computed(() => clsx(buttonSpinnerVariants({ shape: this.shape() })), ...(ngDevMode ? [{ debugName: "spinnerClasses" }] : []));
1287
+ iconClasses(position) {
1288
+ return clsx(buttonIconVariants({ position }));
1390
1289
  }
1391
1290
  handleClick(event) {
1392
- if (!this.disabled()) {
1291
+ if (!this.isDisabled())
1393
1292
  this.Click.emit(event);
1394
- }
1395
1293
  }
1396
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ButtonComponent, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
1397
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ButtonComponent, isStandalone: true, selector: "bsg-button", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconPosition: { classPropertyName: "iconPosition", publicName: "iconPosition", isSignal: true, isRequired: false, transformFunction: null }, iconName: { classPropertyName: "iconName", publicName: "iconName", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { Click: "Click" }, ngImport: i0, template: `
1294
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1295
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ButtonComponent, isStandalone: true, selector: "bsg-button", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, spinner: { classPropertyName: "spinner", publicName: "spinner", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { Click: "Click" }, ngImport: i0, template: `
1398
1296
  <button
1399
1297
  type="button"
1400
1298
  (click)="handleClick($event)"
1401
1299
  [class]="buttonClasses()"
1402
1300
  [disabled]="isDisabled()"
1403
1301
  [attr.aria-disabled]="isDisabled()"
1302
+ [attr.aria-busy]="spinner() ? 'true' : null"
1404
1303
  [attr.aria-label]="
1405
- shape() === 'icon-only' ? label() || 'Icon button' : null
1304
+ ariaLabel() ?? (isIconButton() ? label() || 'Icon button' : null)
1406
1305
  "
1306
+ [style.width.px]="isIconButton() ? buttonSquarePx() : null"
1307
+ [style.minWidth.px]="isIconButton() ? buttonSquarePx() : null"
1308
+ [style.height.px]="isIconButton() ? buttonSquarePx() : null"
1309
+ [style.minHeight.px]="isIconButton() ? buttonSquarePx() : null"
1310
+ [style.padding]="isIconButton() ? '0' : null"
1407
1311
  >
1408
- <!-- Icon-only button: centered icon using DomSanitizer -->
1409
- @if (shape() === 'icon-only') {
1312
+ <!-- Spinner -->
1313
+ @if (spinner()) {
1410
1314
  <span
1411
- [class]="iconOnlyClasses()"
1412
- [innerHTML]="getIconSvg(iconName())"
1413
- ></span>
1315
+ [class]="spinnerClasses()"
1316
+ [style.fontSize.px]="spinnerPx()"
1317
+ [attr.aria-hidden]="'true'"
1318
+ >
1319
+ <i class="fa-solid fa-spinner fa-spin"></i>
1320
+ </span>
1414
1321
  }
1415
1322
 
1416
- <!-- Regular buttons with optional icons -->
1417
- @if (shape() !== 'icon-only' && icon() && iconPosition() === 'left') {
1418
- <svg
1323
+ <!-- Icon-only / Icon button content -->
1324
+ @if (isIconButton()) {
1325
+ <span
1326
+ [class]="iconOnlyClasses()"
1327
+ [style.fontSize.px]="iconFontPx()"
1328
+ [style.lineHeight]="1"
1329
+ [style.opacity]="spinner() ? 0 : 1"
1330
+ >
1331
+ <ng-content></ng-content>
1332
+ </span>
1333
+ } @else {
1334
+ <span
1335
+ class="bsg-btn-icon"
1419
1336
  [class]="iconClasses('left')"
1420
- width="15"
1421
- height="15"
1422
- viewBox="0 0 15 15"
1423
- fill="none"
1424
- xmlns="http://www.w3.org/2000/svg"
1337
+ [style.opacity]="spinner() ? 0 : 1"
1425
1338
  >
1426
- <path
1427
- d="M6.43152 0.706459C7.98489 0.461733 9.57507 0.757369 10.9371 1.54325C11.236 1.71571 11.3389 2.09758 11.1666 2.39652C10.9941 2.6955 10.6117 2.79791 10.3127 2.6254C9.19838 1.98244 7.8971 1.74102 6.62622 1.9412C5.35531 2.14143 4.19123 2.77142 3.32849 3.72587C2.46577 4.68036 1.95621 5.90193 1.88501 7.18656C1.81383 8.47123 2.18524 9.74182 2.93726 10.7858C3.68927 11.8297 4.7767 12.5845 6.0177 12.9239C7.2587 13.2632 8.57874 13.167 9.75733 12.651C10.936 12.1351 11.9022 11.2303 12.4948 10.0882C13.0872 8.94613 13.2698 7.63546 13.0129 6.37479C12.944 6.03664 13.1625 5.7065 13.5006 5.63749C13.8388 5.56857 14.169 5.78696 14.2379 6.12516C14.5519 7.66605 14.3279 9.26786 13.6038 10.6637C12.8796 12.0596 11.699 13.1654 10.2584 13.7961C8.81797 14.4266 7.20484 14.5441 5.68811 14.1293C4.17129 13.7145 2.84198 12.7923 1.92285 11.5164C1.00374 10.2404 0.549867 8.68771 0.636842 7.11759C0.723839 5.54744 1.3469 4.05449 2.40137 2.88786C3.45582 1.7213 4.87818 0.951184 6.43152 0.706459ZM13.3084 2.05778C13.5524 1.81398 13.9482 1.81382 14.1921 2.05778C14.4362 2.30186 14.4362 2.6981 14.1921 2.94218L7.94214 9.19218C7.69815 9.43613 7.30244 9.43597 7.05835 9.19218L5.18335 7.31718C4.93927 7.0731 4.93927 6.67686 5.18335 6.43278C5.42744 6.18898 5.82315 6.18882 6.06714 6.43278L7.50025 7.86588L13.3084 2.05778Z"
1428
- [attr.fill]="iconColor()"
1429
- />
1430
- </svg>
1431
- }
1339
+ <ng-content select="[left-icon]"></ng-content>
1340
+ </span>
1432
1341
 
1433
- @if (shape() !== 'icon' && shape() !== 'icon-only') {
1434
- <span [class]="labelClasses()">{{ label() }}</span>
1435
- }
1342
+ <span [class]="labelClasses()" [style.opacity]="spinner() ? 0 : 1">{{
1343
+ label()
1344
+ }}</span>
1436
1345
 
1437
- @if (shape() !== 'icon-only' && icon() && iconPosition() === 'right') {
1438
- <svg
1346
+ <span
1347
+ class="bsg-btn-icon"
1439
1348
  [class]="iconClasses('right')"
1440
- width="15"
1441
- height="15"
1442
- viewBox="0 0 15 15"
1443
- fill="none"
1444
- xmlns="http://www.w3.org/2000/svg"
1349
+ [style.opacity]="spinner() ? 0 : 1"
1445
1350
  >
1446
- <path
1447
- d="M6.43152 0.706459C7.98489 0.461733 9.57507 0.757369 10.9371 1.54325C11.236 1.71571 11.3389 2.09758 11.1666 2.39652C10.9941 2.6955 10.6117 2.79791 10.3127 2.6254C9.19838 1.98244 7.8971 1.74102 6.62622 1.9412C5.35531 2.14143 4.19123 2.77142 3.32849 3.72587C2.46577 4.68036 1.95621 5.90193 1.88501 7.18656C1.81383 8.47123 2.18524 9.74182 2.93726 10.7858C3.68927 11.8297 4.7767 12.5845 6.0177 12.9239C7.2587 13.2632 8.57874 13.167 9.75733 12.651C10.936 12.1351 11.9022 11.2303 12.4948 10.0882C13.0872 8.94613 13.2698 7.63546 13.0129 6.37479C12.944 6.03664 13.1625 5.7065 13.5006 5.63749C13.8388 5.56857 14.169 5.78696 14.2379 6.12516C14.5519 7.66605 14.3279 9.26786 13.6038 10.6637C12.8796 12.0596 11.699 13.1654 10.2584 13.7961C8.81797 14.4266 7.20484 14.5441 5.68811 14.1293C4.17129 13.7145 2.84198 12.7923 1.92285 11.5164C1.00374 10.2404 0.549867 8.68771 0.636842 7.11759C0.723839 5.54744 1.3469 4.05449 2.40137 2.88786C3.45582 1.7213 4.87818 0.951184 6.43152 0.706459ZM13.3084 2.05778C13.5524 1.81398 13.9482 1.81382 14.1921 2.05778C14.4362 2.30186 14.4362 2.6981 14.1921 2.94218L7.94214 9.19218C7.69815 9.43613 7.30244 9.43597 7.05835 9.19218L5.18335 7.31718C4.93927 7.0731 4.93927 6.67686 5.18335 6.43278C5.42744 6.18898 5.82315 6.18882 6.06714 6.43278L7.50025 7.86588L13.3084 2.05778Z"
1448
- [attr.fill]="iconColor()"
1449
- />
1450
- </svg>
1351
+ <ng-content select="[right-icon]"></ng-content>
1352
+ </span>
1451
1353
  }
1452
1354
  </button>
1453
- `, isInline: true, styles: [":host{display:inline-block}\n"] });
1355
+ `, isInline: true, styles: [":host{display:inline-block}.bsg-btn-icon:empty{display:none}:host ::ng-deep i{color:inherit}\n"] });
1454
1356
  }
1455
1357
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ButtonComponent, decorators: [{
1456
1358
  type: Component,
@@ -1461,57 +1363,61 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
1461
1363
  [class]="buttonClasses()"
1462
1364
  [disabled]="isDisabled()"
1463
1365
  [attr.aria-disabled]="isDisabled()"
1366
+ [attr.aria-busy]="spinner() ? 'true' : null"
1464
1367
  [attr.aria-label]="
1465
- shape() === 'icon-only' ? label() || 'Icon button' : null
1368
+ ariaLabel() ?? (isIconButton() ? label() || 'Icon button' : null)
1466
1369
  "
1370
+ [style.width.px]="isIconButton() ? buttonSquarePx() : null"
1371
+ [style.minWidth.px]="isIconButton() ? buttonSquarePx() : null"
1372
+ [style.height.px]="isIconButton() ? buttonSquarePx() : null"
1373
+ [style.minHeight.px]="isIconButton() ? buttonSquarePx() : null"
1374
+ [style.padding]="isIconButton() ? '0' : null"
1467
1375
  >
1468
- <!-- Icon-only button: centered icon using DomSanitizer -->
1469
- @if (shape() === 'icon-only') {
1376
+ <!-- Spinner -->
1377
+ @if (spinner()) {
1470
1378
  <span
1471
- [class]="iconOnlyClasses()"
1472
- [innerHTML]="getIconSvg(iconName())"
1473
- ></span>
1379
+ [class]="spinnerClasses()"
1380
+ [style.fontSize.px]="spinnerPx()"
1381
+ [attr.aria-hidden]="'true'"
1382
+ >
1383
+ <i class="fa-solid fa-spinner fa-spin"></i>
1384
+ </span>
1474
1385
  }
1475
1386
 
1476
- <!-- Regular buttons with optional icons -->
1477
- @if (shape() !== 'icon-only' && icon() && iconPosition() === 'left') {
1478
- <svg
1387
+ <!-- Icon-only / Icon button content -->
1388
+ @if (isIconButton()) {
1389
+ <span
1390
+ [class]="iconOnlyClasses()"
1391
+ [style.fontSize.px]="iconFontPx()"
1392
+ [style.lineHeight]="1"
1393
+ [style.opacity]="spinner() ? 0 : 1"
1394
+ >
1395
+ <ng-content></ng-content>
1396
+ </span>
1397
+ } @else {
1398
+ <span
1399
+ class="bsg-btn-icon"
1479
1400
  [class]="iconClasses('left')"
1480
- width="15"
1481
- height="15"
1482
- viewBox="0 0 15 15"
1483
- fill="none"
1484
- xmlns="http://www.w3.org/2000/svg"
1401
+ [style.opacity]="spinner() ? 0 : 1"
1485
1402
  >
1486
- <path
1487
- d="M6.43152 0.706459C7.98489 0.461733 9.57507 0.757369 10.9371 1.54325C11.236 1.71571 11.3389 2.09758 11.1666 2.39652C10.9941 2.6955 10.6117 2.79791 10.3127 2.6254C9.19838 1.98244 7.8971 1.74102 6.62622 1.9412C5.35531 2.14143 4.19123 2.77142 3.32849 3.72587C2.46577 4.68036 1.95621 5.90193 1.88501 7.18656C1.81383 8.47123 2.18524 9.74182 2.93726 10.7858C3.68927 11.8297 4.7767 12.5845 6.0177 12.9239C7.2587 13.2632 8.57874 13.167 9.75733 12.651C10.936 12.1351 11.9022 11.2303 12.4948 10.0882C13.0872 8.94613 13.2698 7.63546 13.0129 6.37479C12.944 6.03664 13.1625 5.7065 13.5006 5.63749C13.8388 5.56857 14.169 5.78696 14.2379 6.12516C14.5519 7.66605 14.3279 9.26786 13.6038 10.6637C12.8796 12.0596 11.699 13.1654 10.2584 13.7961C8.81797 14.4266 7.20484 14.5441 5.68811 14.1293C4.17129 13.7145 2.84198 12.7923 1.92285 11.5164C1.00374 10.2404 0.549867 8.68771 0.636842 7.11759C0.723839 5.54744 1.3469 4.05449 2.40137 2.88786C3.45582 1.7213 4.87818 0.951184 6.43152 0.706459ZM13.3084 2.05778C13.5524 1.81398 13.9482 1.81382 14.1921 2.05778C14.4362 2.30186 14.4362 2.6981 14.1921 2.94218L7.94214 9.19218C7.69815 9.43613 7.30244 9.43597 7.05835 9.19218L5.18335 7.31718C4.93927 7.0731 4.93927 6.67686 5.18335 6.43278C5.42744 6.18898 5.82315 6.18882 6.06714 6.43278L7.50025 7.86588L13.3084 2.05778Z"
1488
- [attr.fill]="iconColor()"
1489
- />
1490
- </svg>
1491
- }
1403
+ <ng-content select="[left-icon]"></ng-content>
1404
+ </span>
1492
1405
 
1493
- @if (shape() !== 'icon' && shape() !== 'icon-only') {
1494
- <span [class]="labelClasses()">{{ label() }}</span>
1495
- }
1406
+ <span [class]="labelClasses()" [style.opacity]="spinner() ? 0 : 1">{{
1407
+ label()
1408
+ }}</span>
1496
1409
 
1497
- @if (shape() !== 'icon-only' && icon() && iconPosition() === 'right') {
1498
- <svg
1410
+ <span
1411
+ class="bsg-btn-icon"
1499
1412
  [class]="iconClasses('right')"
1500
- width="15"
1501
- height="15"
1502
- viewBox="0 0 15 15"
1503
- fill="none"
1504
- xmlns="http://www.w3.org/2000/svg"
1413
+ [style.opacity]="spinner() ? 0 : 1"
1505
1414
  >
1506
- <path
1507
- d="M6.43152 0.706459C7.98489 0.461733 9.57507 0.757369 10.9371 1.54325C11.236 1.71571 11.3389 2.09758 11.1666 2.39652C10.9941 2.6955 10.6117 2.79791 10.3127 2.6254C9.19838 1.98244 7.8971 1.74102 6.62622 1.9412C5.35531 2.14143 4.19123 2.77142 3.32849 3.72587C2.46577 4.68036 1.95621 5.90193 1.88501 7.18656C1.81383 8.47123 2.18524 9.74182 2.93726 10.7858C3.68927 11.8297 4.7767 12.5845 6.0177 12.9239C7.2587 13.2632 8.57874 13.167 9.75733 12.651C10.936 12.1351 11.9022 11.2303 12.4948 10.0882C13.0872 8.94613 13.2698 7.63546 13.0129 6.37479C12.944 6.03664 13.1625 5.7065 13.5006 5.63749C13.8388 5.56857 14.169 5.78696 14.2379 6.12516C14.5519 7.66605 14.3279 9.26786 13.6038 10.6637C12.8796 12.0596 11.699 13.1654 10.2584 13.7961C8.81797 14.4266 7.20484 14.5441 5.68811 14.1293C4.17129 13.7145 2.84198 12.7923 1.92285 11.5164C1.00374 10.2404 0.549867 8.68771 0.636842 7.11759C0.723839 5.54744 1.3469 4.05449 2.40137 2.88786C3.45582 1.7213 4.87818 0.951184 6.43152 0.706459ZM13.3084 2.05778C13.5524 1.81398 13.9482 1.81382 14.1921 2.05778C14.4362 2.30186 14.4362 2.6981 14.1921 2.94218L7.94214 9.19218C7.69815 9.43613 7.30244 9.43597 7.05835 9.19218L5.18335 7.31718C4.93927 7.0731 4.93927 6.67686 5.18335 6.43278C5.42744 6.18898 5.82315 6.18882 6.06714 6.43278L7.50025 7.86588L13.3084 2.05778Z"
1508
- [attr.fill]="iconColor()"
1509
- />
1510
- </svg>
1415
+ <ng-content select="[right-icon]"></ng-content>
1416
+ </span>
1511
1417
  }
1512
1418
  </button>
1513
- `, styles: [":host{display:inline-block}\n"] }]
1514
- }], ctorParameters: () => [{ type: i1.DomSanitizer }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], iconPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconPosition", required: false }] }], iconName: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconName", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], Click: [{ type: i0.Output, args: ["Click"] }] } });
1419
+ `, styles: [":host{display:inline-block}.bsg-btn-icon:empty{display:none}:host ::ng-deep i{color:inherit}\n"] }]
1420
+ }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], spinner: [{ type: i0.Input, args: [{ isSignal: true, alias: "spinner", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], Click: [{ type: i0.Output, args: ["Click"] }] } });
1515
1421
 
1516
1422
  /**
1517
1423
  * Card container variants
@@ -1530,19 +1436,19 @@ const cardVariants = cva(clsx(
1530
1436
  // Border
1531
1437
  'rounded-lg',
1532
1438
  // Background
1533
- 'bg-white',
1439
+ 'bg-card',
1534
1440
  // Transition
1535
1441
  'transition-all duration-200'), {
1536
1442
  variants: {
1537
1443
  variant: {
1538
- default: 'border border-zinc-200',
1444
+ default: 'border border-border',
1539
1445
  },
1540
1446
  contentVariant: {
1541
1447
  default: '',
1542
- metric: clsx('items-center justify-center', 'px-[89px] py-4', 'min-h-[87px]', 'bg-red-50 border border-red-200'),
1543
- infoDate: clsx('items-center justify-center', 'px-2 py-[17px]', 'gap-2', 'min-h-[84px]', 'w-fit max-w-[101px]', 'bg-blue-50 border-0'),
1544
- infoCurrency: clsx('items-start justify-start', 'p-4', 'gap-4', 'min-h-[90px]', 'w-fit max-w-[273px]', 'bg-blue-200 border-0'),
1545
- placeholder: clsx('w-[277px] min-h-[225px]', 'border border-slate-200', 'bg-transparent', 'p-0'),
1448
+ metric: clsx('items-center justify-center', 'px-[89px] py-4', 'min-h-[87px]', 'bg-destructive/10 border border-destructive/30'),
1449
+ infoDate: clsx('items-center justify-center', 'px-2 py-[17px]', 'gap-2', 'min-h-[84px]', 'w-fit max-w-[101px]', 'bg-info/10 border-0'),
1450
+ infoCurrency: clsx('items-start justify-start', 'p-4', 'gap-4', 'min-h-[90px]', 'w-fit max-w-[273px]', 'bg-info/30 border-0'),
1451
+ placeholder: clsx('w-[277px] min-h-[225px]', 'border border-border', 'bg-transparent', 'p-0'),
1546
1452
  },
1547
1453
  },
1548
1454
  defaultVariants: {
@@ -1573,7 +1479,7 @@ const cardHeaderVariants = cva(clsx(
1573
1479
  // Typography
1574
1480
  'text-sm font-normal leading-normal',
1575
1481
  // Color
1576
- 'text-slate-600'));
1482
+ 'text-muted-foreground'));
1577
1483
  /**
1578
1484
  * Card info icon variants
1579
1485
  *
@@ -1603,7 +1509,7 @@ const cardValueVariants = cva(clsx(
1603
1509
  // Typography
1604
1510
  'text-[32px] font-extrabold leading-[1.2]',
1605
1511
  // Color
1606
- 'text-neutral-800'));
1512
+ 'text-card-foreground'));
1607
1513
  /**
1608
1514
  * Card helper row variants
1609
1515
  *
@@ -1625,7 +1531,7 @@ const cardHelperVariants = cva(clsx(
1625
1531
  // Layout
1626
1532
  'shrink-0',
1627
1533
  // Default color (green for positive)
1628
- 'text-green-600'));
1534
+ 'text-success'));
1629
1535
  /**
1630
1536
  * Card helper description variants
1631
1537
  *
@@ -1635,7 +1541,7 @@ const cardHelperDescriptionVariants = cva(clsx(
1635
1541
  // Typography
1636
1542
  'text-[13px] font-normal leading-normal',
1637
1543
  // Color
1638
- 'text-slate-500'));
1544
+ 'text-muted-foreground'));
1639
1545
  /**
1640
1546
  * Card metric title variants
1641
1547
  *
@@ -1647,7 +1553,7 @@ const cardMetricTitleVariants = cva(clsx(
1647
1553
  // Typography
1648
1554
  'text-xs font-medium leading-normal text-center',
1649
1555
  // Color
1650
- 'text-slate-600'));
1556
+ 'text-muted-foreground'));
1651
1557
  /**
1652
1558
  * Card metric value variants
1653
1559
  *
@@ -1659,7 +1565,7 @@ const cardMetricValueVariants = cva(clsx(
1659
1565
  // Typography
1660
1566
  'text-2xl font-bold leading-normal text-center',
1661
1567
  // Color
1662
- 'text-red-600'));
1568
+ 'text-destructive'));
1663
1569
  /**
1664
1570
  * Card info label variants
1665
1571
  *
@@ -1671,7 +1577,7 @@ const cardInfoLabelVariants = cva(clsx(
1671
1577
  // Typography
1672
1578
  'text-xs font-medium leading-normal text-center',
1673
1579
  // Color
1674
- 'text-slate-600'));
1580
+ 'text-muted-foreground'));
1675
1581
  /**
1676
1582
  * Card info text variants
1677
1583
  *
@@ -1683,7 +1589,7 @@ const cardInfoTextVariants = cva(clsx(
1683
1589
  // Typography
1684
1590
  'text-sm font-bold leading-normal text-center',
1685
1591
  // Color
1686
- 'text-slate-600'));
1592
+ 'text-muted-foreground'));
1687
1593
  /**
1688
1594
  * Card currency label variants
1689
1595
  *
@@ -1695,7 +1601,7 @@ const cardCurrencyLabelVariants = cva(clsx(
1695
1601
  // Typography
1696
1602
  'text-sm font-medium leading-normal',
1697
1603
  // Color
1698
- 'text-slate-700'));
1604
+ 'text-foreground'));
1699
1605
  /**
1700
1606
  * Card currency content variants
1701
1607
  *
@@ -1727,7 +1633,7 @@ const cardCurrencyTextVariants = cva(clsx(
1727
1633
  // Typography
1728
1634
  'text-xl font-bold leading-normal',
1729
1635
  // Color
1730
- 'text-blue-600'));
1636
+ 'text-info'));
1731
1637
  /**
1732
1638
  * Slot header/body/footer variants (estilo shadcn)
1733
1639
  * Son “wrappers” que te permiten componer cards personalizadas.
@@ -2062,11 +1968,11 @@ const carouselArrowVariants = cva(clsx('absolute top-1/2 -translate-y-1/2', 'z-2
2062
1968
  // Tamaño
2063
1969
  'w-7 h-7 sm:w-8 sm:h-8 md:w-9 md:h-9 lg:w-[41px] lg:h-[41px]',
2064
1970
  // Forma
2065
- 'rounded-full bg-white border border-[#E2E8F0]',
1971
+ 'rounded-full bg-background border border-border',
2066
1972
  // Color del icono
2067
- 'text-purple-600',
1973
+ 'text-primary',
2068
1974
  // Interacción
2069
- 'cursor-pointer p-0', 'transition-opacity duration-200', 'disabled:opacity-40 disabled:cursor-not-allowed', 'hover:not-disabled:opacity-80', 'focus-visible:outline-2 focus-visible:outline-purple-600 focus-visible:outline-offset-2', 'focus:not-focus-visible:outline-none'), {
1975
+ 'cursor-pointer p-0', 'transition-opacity duration-200', 'disabled:opacity-40 disabled:cursor-not-allowed', 'hover:not-disabled:opacity-80', 'focus-visible:outline-2 focus-visible:outline-ring focus-visible:outline-offset-2', 'focus:not-focus-visible:outline-none'), {
2070
1976
  variants: {
2071
1977
  direction: {
2072
1978
  prev: 'left-2.5',
@@ -2079,7 +1985,7 @@ const carouselArrowVariants = cva(clsx('absolute top-1/2 -translate-y-1/2', 'z-2
2079
1985
  });
2080
1986
  const carouselChevronVariants = cva(clsx('block', 'w-4 h-4 sm:w-5 sm:h-5 md:w-[22px] md:h-[22px] lg:w-6 lg:h-6', 'pointer-events-none'));
2081
1987
  const carouselIndicatorsVariants = cva(clsx('flex items-center justify-center', 'gap-3 sm:gap-5', 'mt-4 sm:mt-6', 'w-full', 'pointer-events-auto'));
2082
- const carouselIndicatorVariants = cva(clsx('w-2.5 h-2.5 sm:w-3 sm:h-3', 'rounded-full', 'bg-purple-600', 'border-0', 'p-0', 'cursor-pointer', 'transition-opacity duration-200', 'shrink-0', 'hover:opacity-60', 'focus-visible:outline-2 focus-visible:outline-purple-600 focus-visible:outline-offset-2', 'focus:not-focus-visible:outline-none'), {
1988
+ const carouselIndicatorVariants = cva(clsx('w-2.5 h-2.5 sm:w-3 sm:h-3', 'rounded-full', 'bg-primary', 'border-0', 'p-0', 'cursor-pointer', 'transition-opacity duration-200', 'shrink-0', 'hover:opacity-60', 'focus-visible:outline-2 focus-visible:outline-ring focus-visible:outline-offset-2', 'focus:not-focus-visible:outline-none'), {
2083
1989
  variants: {
2084
1990
  active: {
2085
1991
  true: 'opacity-100',
@@ -3343,7 +3249,7 @@ const dialogOverlayVariants = cva(clsx('fixed inset-0', 'z-[9999]', 'flex justif
3343
3249
  /**
3344
3250
  * Dialog content variants
3345
3251
  */
3346
- const dialogContentVariants = cva(clsx('relative', 'flex flex-col', 'shrink-0', 'bg-white', 'rounded-xl', 'shadow-xl', 'max-h-[90vh]', 'w-full', 'box-border', 'animate-in zoom-in-95 duration-200', 'select-text', 'focus:outline-none'), {
3252
+ const dialogContentVariants = cva(clsx('relative', 'flex flex-col', 'shrink-0', 'bg-card', 'rounded-xl', 'shadow-xl', 'max-h-[90vh]', 'w-full', 'box-border', 'animate-in zoom-in-95 duration-200', 'select-text', 'focus:outline-none'), {
3347
3253
  variants: {
3348
3254
  size: {
3349
3255
  sm: 'max-w-sm',
@@ -3366,9 +3272,9 @@ const dialogContentVariants = cva(clsx('relative', 'flex flex-col', 'shrink-0',
3366
3272
  const dialogHeaderVariants = cva(clsx('flex items-center', 'min-h-[57px]', 'px-[17px] py-5 md:px-3.5 md:py-4', 'rounded-t-xl', 'box-border', 'font-sans text-base font-semibold leading-normal', 'md:text-sm'), {
3367
3273
  variants: {
3368
3274
  tone: {
3369
- brand: 'bg-orange-600 text-white',
3370
- info: 'bg-purple-100 text-purple-600',
3371
- secondary: 'bg-purple-100 text-purple-600',
3275
+ brand: 'bg-brand text-brand-foreground',
3276
+ info: 'bg-primary/20 text-primary',
3277
+ secondary: 'bg-primary/20 text-primary',
3372
3278
  },
3373
3279
  },
3374
3280
  defaultVariants: {
@@ -3378,7 +3284,7 @@ const dialogHeaderVariants = cva(clsx('flex items-center', 'min-h-[57px]', 'px-[
3378
3284
  /**
3379
3285
  * Dialog body variants
3380
3286
  */
3381
- const dialogBodyVariants = cva(clsx('flex-1', 'px-[23px] py-5 md:px-3.5 md:py-4', 'box-border', 'font-sans text-sm font-medium leading-normal', 'md:text-[13px]', 'text-slate-500'), {
3287
+ const dialogBodyVariants = cva(clsx('flex-1', 'px-[23px] py-5 md:px-3.5 md:py-4', 'box-border', 'font-sans text-sm font-medium leading-normal', 'md:text-[13px]', 'text-muted-foreground'), {
3382
3288
  variants: {
3383
3289
  scrollable: {
3384
3290
  true: 'overflow-y-auto max-h-[calc(90vh-200px)] md:max-h-[calc(95vh-180px)]',
@@ -3392,7 +3298,7 @@ const dialogBodyVariants = cva(clsx('flex-1', 'px-[23px] py-5 md:px-3.5 md:py-4'
3392
3298
  /**
3393
3299
  * Dialog footer variants
3394
3300
  */
3395
- const dialogFooterVariants = cva(clsx('flex items-center justify-end flex-nowrap', 'gap-8 md:gap-5', 'px-[23px] py-5 md:px-3.5 md:py-4', 'border-t border-slate-200', 'box-border', 'w-full'));
3301
+ const dialogFooterVariants = cva(clsx('flex items-center justify-end flex-nowrap', 'gap-8 md:gap-5', 'px-[23px] py-5 md:px-3.5 md:py-4', 'border-t border-border', 'box-border', 'w-full'));
3396
3302
 
3397
3303
  // projects/bsg-integra/src/lib/components/dialog/dialog.component.ts
3398
3304
  class DialogComponent {
@@ -3707,7 +3613,7 @@ const labelVariants = cva(clsx(
3707
3613
  // Typography
3708
3614
  'text-sm', 'font-inherit',
3709
3615
  // Color
3710
- 'text-slate-800'));
3616
+ 'text-foreground'));
3711
3617
 
3712
3618
  /**
3713
3619
  * Label Component
@@ -6472,6 +6378,123 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
6472
6378
  `, styles: [":host{display:block}\n"] }]
6473
6379
  }], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }] } });
6474
6380
 
6381
+ /**
6382
+ * Spinner variants
6383
+ *
6384
+ * Controls the spinner appearance including size and color variants.
6385
+ * Based on shadcn/ui spinner pattern.
6386
+ */
6387
+ const spinnerVariants = cva(clsx(
6388
+ // Base animation
6389
+ 'animate-spin',
6390
+ // Accessibility
6391
+ 'shrink-0'), {
6392
+ variants: {
6393
+ /**
6394
+ * Size variants
6395
+ * Following shadcn/ui pattern: size-3, size-4 (default), size-6, size-8
6396
+ */
6397
+ size: {
6398
+ xs: 'size-3',
6399
+ sm: 'size-4',
6400
+ md: 'size-6',
6401
+ lg: 'size-8',
6402
+ xl: 'size-10',
6403
+ },
6404
+ /**
6405
+ * Color variants using design tokens
6406
+ */
6407
+ variant: {
6408
+ default: 'text-foreground',
6409
+ primary: 'text-primary',
6410
+ secondary: 'text-secondary-foreground',
6411
+ muted: 'text-muted-foreground',
6412
+ destructive: 'text-destructive',
6413
+ success: 'text-success',
6414
+ warning: 'text-warning',
6415
+ info: 'text-info',
6416
+ brand: 'text-brand',
6417
+ },
6418
+ },
6419
+ defaultVariants: {
6420
+ size: 'sm',
6421
+ variant: 'primary',
6422
+ },
6423
+ });
6424
+
6425
+ /**
6426
+ * Spinner Component
6427
+ *
6428
+ * A loading indicator that shows a spinning animation.
6429
+ * Based on shadcn/ui spinner pattern using an SVG loader icon.
6430
+ *
6431
+ * @example
6432
+ * ```html
6433
+ * <!-- Basic usage -->
6434
+ * <bsg-spinner />
6435
+ *
6436
+ * <!-- With size -->
6437
+ * <bsg-spinner size="lg" />
6438
+ *
6439
+ * <!-- With variant (color) -->
6440
+ * <bsg-spinner variant="destructive" />
6441
+ *
6442
+ * <!-- Custom aria-label -->
6443
+ * <bsg-spinner ariaLabel="Processing request..." />
6444
+ * ```
6445
+ */
6446
+ class SpinnerComponent {
6447
+ /** Spinner size */
6448
+ size = input('sm', ...(ngDevMode ? [{ debugName: "size" }] : []));
6449
+ /** Spinner color variant */
6450
+ variant = input('primary', ...(ngDevMode ? [{ debugName: "variant" }] : []));
6451
+ /** Accessibility label for screen readers */
6452
+ ariaLabel = input('Loading', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
6453
+ /** Additional CSS classes */
6454
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
6455
+ /** Computed spinner classes */
6456
+ spinnerClasses = computed(() => clsx(spinnerVariants({
6457
+ size: this.size(),
6458
+ variant: this.variant(),
6459
+ }), this.className()), ...(ngDevMode ? [{ debugName: "spinnerClasses" }] : []));
6460
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SpinnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6461
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.15", type: SpinnerComponent, isStandalone: true, selector: "bsg-spinner", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
6462
+ <svg
6463
+ [class]="spinnerClasses()"
6464
+ xmlns="http://www.w3.org/2000/svg"
6465
+ viewBox="0 0 24 24"
6466
+ fill="none"
6467
+ stroke="currentColor"
6468
+ stroke-width="2"
6469
+ stroke-linecap="round"
6470
+ stroke-linejoin="round"
6471
+ role="status"
6472
+ [attr.aria-label]="ariaLabel()"
6473
+ >
6474
+ <path d="M21 12a9 9 0 1 1-6.219-8.56" />
6475
+ </svg>
6476
+ `, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center}\n"] });
6477
+ }
6478
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SpinnerComponent, decorators: [{
6479
+ type: Component,
6480
+ args: [{ selector: 'bsg-spinner', standalone: true, template: `
6481
+ <svg
6482
+ [class]="spinnerClasses()"
6483
+ xmlns="http://www.w3.org/2000/svg"
6484
+ viewBox="0 0 24 24"
6485
+ fill="none"
6486
+ stroke="currentColor"
6487
+ stroke-width="2"
6488
+ stroke-linecap="round"
6489
+ stroke-linejoin="round"
6490
+ role="status"
6491
+ [attr.aria-label]="ariaLabel()"
6492
+ >
6493
+ <path d="M21 12a9 9 0 1 1-6.219-8.56" />
6494
+ </svg>
6495
+ `, styles: [":host{display:inline-flex;align-items:center;justify-content:center}\n"] }]
6496
+ }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }] } });
6497
+
6475
6498
  /**
6476
6499
  * Switch root variants
6477
6500
  *
@@ -6651,6 +6674,3090 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
6651
6674
  `, changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:inline-flex}\n"] }]
6652
6675
  }], propDecorators: { checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], checkedChange: [{ type: i0.Output, args: ["checkedChange"] }] } });
6653
6676
 
6677
+ /**
6678
+ * Tabs Root Component
6679
+ *
6680
+ * The root container for a set of tabs. Manages the active tab state.
6681
+ *
6682
+ * Usage:
6683
+ * ```html
6684
+ * <bsg-tabs [defaultValue]="0" (valueChange)="onTabChange($event)">
6685
+ * <bsg-tabs-list>
6686
+ * <bsg-tabs-trigger [value]="0">Tab 1</bsg-tabs-trigger>
6687
+ * <bsg-tabs-trigger [value]="1">Tab 2</bsg-tabs-trigger>
6688
+ * </bsg-tabs-list>
6689
+ * <bsg-tabs-content [value]="0">Content 1</bsg-tabs-content>
6690
+ * <bsg-tabs-content [value]="1">Content 2</bsg-tabs-content>
6691
+ * </bsg-tabs>
6692
+ * ```
6693
+ */
6694
+ class TabsComponent {
6695
+ /** Default active tab value */
6696
+ defaultValue = input(0, ...(ngDevMode ? [{ debugName: "defaultValue" }] : []));
6697
+ /** Additional CSS classes */
6698
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
6699
+ /** Controlled value (if you want to control the tab from outside) */
6700
+ value = input(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
6701
+ /** Event emitted when tab changes */
6702
+ valueChange = output();
6703
+ // Internal state for active tab
6704
+ _internalValue = signal(null, ...(ngDevMode ? [{ debugName: "_internalValue" }] : []));
6705
+ // Computed active value (uses controlled value if set, otherwise internal state, otherwise default)
6706
+ activeValue = computed(() => {
6707
+ const controlled = this.value();
6708
+ if (controlled !== null)
6709
+ return controlled;
6710
+ const internal = this._internalValue();
6711
+ if (internal !== null)
6712
+ return internal;
6713
+ return this.defaultValue();
6714
+ }, ...(ngDevMode ? [{ debugName: "activeValue" }] : []));
6715
+ // Computed classes
6716
+ computedClasses = computed(() => clsx(this.className()), ...(ngDevMode ? [{ debugName: "computedClasses" }] : []));
6717
+ /**
6718
+ * Set the active tab value
6719
+ */
6720
+ setValue(value) {
6721
+ // Only update if it's not a controlled component
6722
+ if (this.value() === null) {
6723
+ this._internalValue.set(value);
6724
+ }
6725
+ this.valueChange.emit(value);
6726
+ }
6727
+ /**
6728
+ * Get the current active tab value
6729
+ */
6730
+ getValue() {
6731
+ return this.activeValue();
6732
+ }
6733
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
6734
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.15", type: TabsComponent, isStandalone: true, selector: "bsg-tabs", inputs: { defaultValue: { classPropertyName: "defaultValue", publicName: "defaultValue", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: `
6735
+ <div [class]="computedClasses()" data-orientation="horizontal">
6736
+ <ng-content />
6737
+ </div>
6738
+ `, isInline: true, styles: [":host{display:block}\n"] });
6739
+ }
6740
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TabsComponent, decorators: [{
6741
+ type: Component,
6742
+ args: [{ selector: 'bsg-tabs', standalone: true, template: `
6743
+ <div [class]="computedClasses()" data-orientation="horizontal">
6744
+ <ng-content />
6745
+ </div>
6746
+ `, styles: [":host{display:block}\n"] }]
6747
+ }], propDecorators: { defaultValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultValue", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
6748
+
6749
+ /**
6750
+ * Tab Navigation container variants
6751
+ *
6752
+ * Controls the overall tab navigation container layout
6753
+ */
6754
+ const tabNavigationVariants = cva(clsx(
6755
+ // Layout
6756
+ 'flex', 'gap-2', 'items-start'), {
6757
+ variants: {
6758
+ layout: {
6759
+ default: 'flex-wrap',
6760
+ carousel: clsx('overflow-x-auto', 'overflow-y-hidden', 'flex-nowrap', 'scroll-smooth',
6761
+ // Hide scrollbar - navigation is via buttons
6762
+ '[scrollbar-width:none]', '[&::-webkit-scrollbar]:hidden'),
6763
+ },
6764
+ },
6765
+ defaultVariants: {
6766
+ layout: 'default',
6767
+ },
6768
+ });
6769
+ /**
6770
+ * Tab Item variants
6771
+ *
6772
+ * Controls the individual tab button styles with size, variant, and color combinations
6773
+ */
6774
+ const tabItemVariants = cva(clsx(
6775
+ // Base layout
6776
+ 'flex', 'justify-center', 'items-center', 'rounded-lg', 'border-none',
6777
+ // Typography
6778
+ 'font-medium', 'text-sm',
6779
+ // Interaction
6780
+ 'cursor-pointer', 'transition-all', 'duration-200',
6781
+ // Box model
6782
+ 'box-border', 'relative',
6783
+ // Focus visible (semantic token)
6784
+ 'focus-visible:outline-2', 'focus-visible:outline-offset-2', 'focus-visible:outline-ring'), {
6785
+ variants: {
6786
+ variant: {
6787
+ text: 'gap-2.5',
6788
+ 'icon-text': 'flex-col gap-0',
6789
+ },
6790
+ size: {
6791
+ sm: '',
6792
+ md: '',
6793
+ lg: '',
6794
+ },
6795
+ color: {
6796
+ default: clsx(
6797
+ // Inactive state (semantic tokens)
6798
+ 'bg-primary/10', 'text-primary', 'hover:not-disabled:not-[data-active=true]:opacity-70', 'hover:not-disabled:not-[data-active=true]:underline',
6799
+ // Active state (semantic tokens)
6800
+ 'data-[active=true]:bg-primary', 'data-[active=true]:text-primary-foreground'),
6801
+ info: clsx(
6802
+ // Inactive state (semantic tokens)
6803
+ 'bg-info/10', 'text-info', 'hover:not-disabled:not-[data-active=true]:opacity-70', 'hover:not-disabled:not-[data-active=true]:underline',
6804
+ // Active state (semantic tokens)
6805
+ 'data-[active=true]:bg-info', 'data-[active=true]:text-info-foreground'),
6806
+ success: clsx(
6807
+ // Inactive state (semantic tokens)
6808
+ 'bg-success/10', 'text-success', 'hover:not-disabled:not-[data-active=true]:opacity-70', 'hover:not-disabled:not-[data-active=true]:underline',
6809
+ // Active state (semantic tokens)
6810
+ 'data-[active=true]:bg-success', 'data-[active=true]:text-success-foreground'),
6811
+ warning: clsx(
6812
+ // Inactive state (semantic tokens)
6813
+ 'bg-warning/10', 'text-warning', 'hover:not-disabled:not-[data-active=true]:opacity-70', 'hover:not-disabled:not-[data-active=true]:underline',
6814
+ // Active state (semantic tokens)
6815
+ 'data-[active=true]:bg-warning', 'data-[active=true]:text-warning-foreground'),
6816
+ destructive: clsx(
6817
+ // Inactive state (semantic tokens)
6818
+ 'bg-destructive/10', 'text-destructive', 'hover:not-disabled:not-[data-active=true]:opacity-70', 'hover:not-disabled:not-[data-active=true]:underline',
6819
+ // Active state (semantic tokens)
6820
+ 'data-[active=true]:bg-destructive', 'data-[active=true]:text-destructive-foreground'),
6821
+ },
6822
+ disabled: {
6823
+ true: 'opacity-40 cursor-not-allowed pointer-events-none',
6824
+ false: '',
6825
+ },
6826
+ },
6827
+ compoundVariants: [
6828
+ // Size + Variant: text
6829
+ {
6830
+ variant: 'text',
6831
+ size: 'sm',
6832
+ class: 'px-4 py-2 min-h-[29px]',
6833
+ },
6834
+ {
6835
+ variant: 'text',
6836
+ size: 'md',
6837
+ class: 'px-6 py-3 min-h-[35px]',
6838
+ },
6839
+ {
6840
+ variant: 'text',
6841
+ size: 'lg',
6842
+ class: 'px-8 py-4 min-h-[43px]',
6843
+ },
6844
+ // Size + Variant: icon-text
6845
+ {
6846
+ variant: 'icon-text',
6847
+ size: 'sm',
6848
+ class: 'px-[18px] py-2 min-h-[80px] w-[168px]',
6849
+ },
6850
+ {
6851
+ variant: 'icon-text',
6852
+ size: 'md',
6853
+ class: 'px-[26px] py-[13px] min-h-[88px] w-[184px]',
6854
+ },
6855
+ {
6856
+ variant: 'icon-text',
6857
+ size: 'lg',
6858
+ class: 'px-[34px] py-[17px] min-h-[96px] w-[200px]',
6859
+ },
6860
+ ],
6861
+ defaultVariants: {
6862
+ variant: 'text',
6863
+ size: 'md',
6864
+ color: 'default',
6865
+ disabled: false,
6866
+ },
6867
+ });
6868
+ /**
6869
+ * Tab Icon Circle variants
6870
+ *
6871
+ * Controls the circular icon container in icon-text variant
6872
+ */
6873
+ const tabIconCircleVariants = cva(clsx(
6874
+ // Size and shape
6875
+ 'size-8', 'rounded-full',
6876
+ // Layout
6877
+ 'flex', 'items-center', 'justify-center', 'shrink-0',
6878
+ // Transition
6879
+ 'transition-colors', 'duration-200'), {
6880
+ variants: {
6881
+ color: {
6882
+ default: 'bg-primary/20 group-data-[active=true]:bg-primary-foreground/20',
6883
+ info: 'bg-info/20 group-data-[active=true]:bg-info-foreground/20',
6884
+ success: 'bg-success/20 group-data-[active=true]:bg-success-foreground/20',
6885
+ warning: 'bg-warning/20 group-data-[active=true]:bg-warning-foreground/20',
6886
+ destructive: 'bg-destructive/20 group-data-[active=true]:bg-destructive-foreground/20',
6887
+ },
6888
+ },
6889
+ defaultVariants: {
6890
+ color: 'default',
6891
+ },
6892
+ });
6893
+ /**
6894
+ * Tab Icon Content variants
6895
+ *
6896
+ * Controls the icon + label container layout
6897
+ */
6898
+ const tabIconContentVariants = cva(clsx('flex', 'flex-col', 'items-center', 'justify-center', 'w-full'));
6899
+ /**
6900
+ * Tab Label variants
6901
+ *
6902
+ * Controls the label text in icon-text variant
6903
+ */
6904
+ const tabLabelVariants = cva(clsx('text-xs', 'font-semibold', 'leading-normal', 'text-center', 'mt-1'));
6905
+ /**
6906
+ * Tab Text Content variants
6907
+ *
6908
+ * Controls the text content in text variant
6909
+ */
6910
+ const tabTextContentVariants = cva(clsx('whitespace-nowrap'));
6911
+
6912
+ /**
6913
+ * Tabs List Component
6914
+ *
6915
+ * Container for tab triggers. This is where you place your bsg-tabs-trigger components.
6916
+ *
6917
+ * Usage:
6918
+ * ```html
6919
+ * <bsg-tabs-list>
6920
+ * <bsg-tabs-trigger [value]="0">Tab 1</bsg-tabs-trigger>
6921
+ * <bsg-tabs-trigger [value]="1">Tab 2</bsg-tabs-trigger>
6922
+ * </bsg-tabs-list>
6923
+ * ```
6924
+ *
6925
+ * Carousel layout with navigation buttons:
6926
+ * ```html
6927
+ * <bsg-tabs-list layout="carousel">
6928
+ * <bsg-tabs-trigger [value]="0">Tab 1</bsg-tabs-trigger>
6929
+ * <bsg-tabs-trigger [value]="1">Tab 2</bsg-tabs-trigger>
6930
+ * <!-- Many more tabs... -->
6931
+ * </bsg-tabs-list>
6932
+ * ```
6933
+ */
6934
+ class TabsListComponent {
6935
+ /** Layout mode: default (wraps) or carousel (scrolls horizontally) */
6936
+ layout = input('default', ...(ngDevMode ? [{ debugName: "layout" }] : []));
6937
+ /** Additional CSS classes */
6938
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
6939
+ // ViewChild for scroll container
6940
+ scrollContainer = viewChild('scrollContainer', ...(ngDevMode ? [{ debugName: "scrollContainer" }] : []));
6941
+ // Signals for button visibility
6942
+ canScrollLeft = signal(false, ...(ngDevMode ? [{ debugName: "canScrollLeft" }] : []));
6943
+ canScrollRight = signal(false, ...(ngDevMode ? [{ debugName: "canScrollRight" }] : []));
6944
+ // ResizeObserver for detecting content changes
6945
+ resizeObserver = null;
6946
+ constructor() {
6947
+ // Effect to check scroll position on layout change
6948
+ effect(() => {
6949
+ const isCarousel = this.layout() === 'carousel';
6950
+ if (isCarousel) {
6951
+ // Delay to ensure DOM is ready
6952
+ setTimeout(() => this.updateScrollButtons(), 100);
6953
+ }
6954
+ });
6955
+ }
6956
+ ngAfterViewInit() {
6957
+ // Initialize scroll buttons after view is ready
6958
+ this.setupResizeObserver();
6959
+ // Multiple checks to ensure content is rendered
6960
+ setTimeout(() => this.updateScrollButtons(), 0);
6961
+ setTimeout(() => this.updateScrollButtons(), 100);
6962
+ setTimeout(() => this.updateScrollButtons(), 500);
6963
+ }
6964
+ ngOnDestroy() {
6965
+ this.resizeObserver?.disconnect();
6966
+ }
6967
+ setupResizeObserver() {
6968
+ const container = this.scrollContainer()?.nativeElement;
6969
+ if (!container)
6970
+ return;
6971
+ this.resizeObserver = new ResizeObserver(() => {
6972
+ this.updateScrollButtons();
6973
+ });
6974
+ this.resizeObserver.observe(container);
6975
+ // Also observe children for content changes
6976
+ const children = container.children;
6977
+ for (let i = 0; i < children.length; i++) {
6978
+ this.resizeObserver.observe(children[i]);
6979
+ }
6980
+ }
6981
+ // Computed: is carousel mode
6982
+ isCarousel = computed(() => this.layout() === 'carousel', ...(ngDevMode ? [{ debugName: "isCarousel" }] : []));
6983
+ // Container classes
6984
+ containerClasses = computed(() => clsx('relative', 'flex', 'items-center', this.isCarousel() ? 'gap-3' : ''), ...(ngDevMode ? [{ debugName: "containerClasses" }] : []));
6985
+ // Computed classes using the existing tabNavigationVariants
6986
+ computedClasses = computed(() => clsx(tabNavigationVariants({
6987
+ layout: this.layout(),
6988
+ }), this.isCarousel() ? 'flex-1 min-w-0' : '', this.className()), ...(ngDevMode ? [{ debugName: "computedClasses" }] : []));
6989
+ // Scroll left
6990
+ scrollLeft() {
6991
+ const container = this.scrollContainer()?.nativeElement;
6992
+ if (container) {
6993
+ const scrollAmount = container.clientWidth * 0.8;
6994
+ container.scrollBy({ left: -scrollAmount, behavior: 'smooth' });
6995
+ }
6996
+ }
6997
+ // Scroll right
6998
+ scrollRight() {
6999
+ const container = this.scrollContainer()?.nativeElement;
7000
+ if (container) {
7001
+ const scrollAmount = container.clientWidth * 0.8;
7002
+ container.scrollBy({ left: scrollAmount, behavior: 'smooth' });
7003
+ }
7004
+ }
7005
+ // Handle scroll event
7006
+ onScroll() {
7007
+ this.updateScrollButtons();
7008
+ }
7009
+ // Update button visibility based on scroll position
7010
+ updateScrollButtons() {
7011
+ const container = this.scrollContainer()?.nativeElement;
7012
+ if (!container)
7013
+ return;
7014
+ const { scrollLeft, scrollWidth, clientWidth } = container;
7015
+ // Can scroll left if not at start
7016
+ this.canScrollLeft.set(scrollLeft > 0);
7017
+ // Can scroll right if not at end (with small tolerance)
7018
+ this.canScrollRight.set(scrollLeft < scrollWidth - clientWidth - 1);
7019
+ }
7020
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TabsListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7021
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: TabsListComponent, isStandalone: true, selector: "bsg-tabs-list", inputs: { layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "scrollContainer", first: true, predicate: ["scrollContainer"], descendants: true, isSignal: true }], ngImport: i0, template: `
7022
+ <div [class]="containerClasses()">
7023
+ <!-- Previous Button - Only shown in carousel mode -->
7024
+ @if (isCarousel()) {
7025
+ <button
7026
+ type="button"
7027
+ class="carousel-nav-btn carousel-nav-btn--prev"
7028
+ (click)="scrollLeft()"
7029
+ [disabled]="!canScrollLeft()"
7030
+ aria-label="Previous tabs"
7031
+ >
7032
+ <svg
7033
+ xmlns="http://www.w3.org/2000/svg"
7034
+ width="24"
7035
+ height="24"
7036
+ viewBox="0 0 24 24"
7037
+ fill="none"
7038
+ stroke="currentColor"
7039
+ stroke-width="2"
7040
+ stroke-linecap="round"
7041
+ stroke-linejoin="round"
7042
+ >
7043
+ <path d="m15 18-6-6 6-6" />
7044
+ </svg>
7045
+ </button>
7046
+ }
7047
+
7048
+ <!-- Tabs Container -->
7049
+ <div
7050
+ #scrollContainer
7051
+ role="tablist"
7052
+ aria-orientation="horizontal"
7053
+ aria-label="Tab navigation"
7054
+ data-orientation="horizontal"
7055
+ [class]="computedClasses()"
7056
+ (scroll)="onScroll()"
7057
+ >
7058
+ <ng-content />
7059
+ </div>
7060
+
7061
+ <!-- Next Button - Only shown in carousel mode -->
7062
+ @if (isCarousel()) {
7063
+ <button
7064
+ type="button"
7065
+ class="carousel-nav-btn carousel-nav-btn--next"
7066
+ (click)="scrollRight()"
7067
+ [disabled]="!canScrollRight()"
7068
+ aria-label="Next tabs"
7069
+ >
7070
+ <svg
7071
+ xmlns="http://www.w3.org/2000/svg"
7072
+ width="24"
7073
+ height="24"
7074
+ viewBox="0 0 24 24"
7075
+ fill="none"
7076
+ stroke="currentColor"
7077
+ stroke-width="2"
7078
+ stroke-linecap="round"
7079
+ stroke-linejoin="round"
7080
+ >
7081
+ <path d="m9 18 6-6-6-6" />
7082
+ </svg>
7083
+ </button>
7084
+ }
7085
+ </div>
7086
+ `, isInline: true, styles: [":host{display:block;width:100%}.carousel-nav-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:40px;height:40px;border-radius:50%;border:1px solid hsl(var(--border));background-color:hsl(var(--background));color:hsl(var(--foreground));cursor:pointer;transition:all .2s ease;box-shadow:0 1px 2px #0000000d}.carousel-nav-btn:hover:not(:disabled){background-color:hsl(var(--accent));color:hsl(var(--accent-foreground))}.carousel-nav-btn:focus-visible{outline:2px solid hsl(var(--ring));outline-offset:2px}.carousel-nav-btn:disabled{opacity:.5;cursor:not-allowed;pointer-events:none}\n"] });
7087
+ }
7088
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TabsListComponent, decorators: [{
7089
+ type: Component,
7090
+ args: [{ selector: 'bsg-tabs-list', standalone: true, template: `
7091
+ <div [class]="containerClasses()">
7092
+ <!-- Previous Button - Only shown in carousel mode -->
7093
+ @if (isCarousel()) {
7094
+ <button
7095
+ type="button"
7096
+ class="carousel-nav-btn carousel-nav-btn--prev"
7097
+ (click)="scrollLeft()"
7098
+ [disabled]="!canScrollLeft()"
7099
+ aria-label="Previous tabs"
7100
+ >
7101
+ <svg
7102
+ xmlns="http://www.w3.org/2000/svg"
7103
+ width="24"
7104
+ height="24"
7105
+ viewBox="0 0 24 24"
7106
+ fill="none"
7107
+ stroke="currentColor"
7108
+ stroke-width="2"
7109
+ stroke-linecap="round"
7110
+ stroke-linejoin="round"
7111
+ >
7112
+ <path d="m15 18-6-6 6-6" />
7113
+ </svg>
7114
+ </button>
7115
+ }
7116
+
7117
+ <!-- Tabs Container -->
7118
+ <div
7119
+ #scrollContainer
7120
+ role="tablist"
7121
+ aria-orientation="horizontal"
7122
+ aria-label="Tab navigation"
7123
+ data-orientation="horizontal"
7124
+ [class]="computedClasses()"
7125
+ (scroll)="onScroll()"
7126
+ >
7127
+ <ng-content />
7128
+ </div>
7129
+
7130
+ <!-- Next Button - Only shown in carousel mode -->
7131
+ @if (isCarousel()) {
7132
+ <button
7133
+ type="button"
7134
+ class="carousel-nav-btn carousel-nav-btn--next"
7135
+ (click)="scrollRight()"
7136
+ [disabled]="!canScrollRight()"
7137
+ aria-label="Next tabs"
7138
+ >
7139
+ <svg
7140
+ xmlns="http://www.w3.org/2000/svg"
7141
+ width="24"
7142
+ height="24"
7143
+ viewBox="0 0 24 24"
7144
+ fill="none"
7145
+ stroke="currentColor"
7146
+ stroke-width="2"
7147
+ stroke-linecap="round"
7148
+ stroke-linejoin="round"
7149
+ >
7150
+ <path d="m9 18 6-6-6-6" />
7151
+ </svg>
7152
+ </button>
7153
+ }
7154
+ </div>
7155
+ `, styles: [":host{display:block;width:100%}.carousel-nav-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:40px;height:40px;border-radius:50%;border:1px solid hsl(var(--border));background-color:hsl(var(--background));color:hsl(var(--foreground));cursor:pointer;transition:all .2s ease;box-shadow:0 1px 2px #0000000d}.carousel-nav-btn:hover:not(:disabled){background-color:hsl(var(--accent));color:hsl(var(--accent-foreground))}.carousel-nav-btn:focus-visible{outline:2px solid hsl(var(--ring));outline-offset:2px}.carousel-nav-btn:disabled{opacity:.5;cursor:not-allowed;pointer-events:none}\n"] }]
7156
+ }], ctorParameters: () => [], propDecorators: { layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], scrollContainer: [{ type: i0.ViewChild, args: ['scrollContainer', { isSignal: true }] }] } });
7157
+
7158
+ /**
7159
+ * Tabs Trigger Component
7160
+ *
7161
+ * A clickable tab that activates its associated content panel.
7162
+ *
7163
+ * Usage for text variant:
7164
+ * ```html
7165
+ * <bsg-tabs-trigger [value]="0">
7166
+ * Tab Label
7167
+ * </bsg-tabs-trigger>
7168
+ * ```
7169
+ *
7170
+ * Usage for icon-text variant:
7171
+ * ```html
7172
+ * <bsg-tabs-trigger [value]="0" variant="icon-text">
7173
+ * <svg slot="icon">...</svg>
7174
+ * <span slot="label">Tab Label</span>
7175
+ * </bsg-tabs-trigger>
7176
+ * ```
7177
+ */
7178
+ class TabsTriggerComponent {
7179
+ // Inject parent tabs component
7180
+ tabs = inject(TabsComponent, { optional: true });
7181
+ /** The value that identifies this tab */
7182
+ value = input.required(...(ngDevMode ? [{ debugName: "value" }] : []));
7183
+ /** Tab visual variant */
7184
+ variant = input('text', ...(ngDevMode ? [{ debugName: "variant" }] : []));
7185
+ /** Tab size variant */
7186
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
7187
+ /** Tab color scheme */
7188
+ color = input('default', ...(ngDevMode ? [{ debugName: "color" }] : []));
7189
+ /** Whether the tab is disabled */
7190
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
7191
+ /** Additional CSS classes */
7192
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
7193
+ // Computed: is this tab active?
7194
+ isActive = computed(() => {
7195
+ if (!this.tabs)
7196
+ return false;
7197
+ return this.tabs.activeValue() === this.value();
7198
+ }, ...(ngDevMode ? [{ debugName: "isActive" }] : []));
7199
+ // Computed tab button classes
7200
+ computedClasses = computed(() => clsx(tabItemVariants({
7201
+ variant: this.variant(),
7202
+ size: this.size(),
7203
+ color: this.color(),
7204
+ disabled: this.disabled(),
7205
+ }), this.className()), ...(ngDevMode ? [{ debugName: "computedClasses" }] : []));
7206
+ // Computed icon content classes
7207
+ iconContentClasses = computed(() => clsx(tabIconContentVariants()), ...(ngDevMode ? [{ debugName: "iconContentClasses" }] : []));
7208
+ // Computed icon circle classes
7209
+ iconCircleClasses = computed(() => clsx(tabIconCircleVariants({
7210
+ color: this.color(),
7211
+ })), ...(ngDevMode ? [{ debugName: "iconCircleClasses" }] : []));
7212
+ // Computed label classes
7213
+ labelClasses = computed(() => clsx(tabLabelVariants()), ...(ngDevMode ? [{ debugName: "labelClasses" }] : []));
7214
+ // Computed text content classes
7215
+ textContentClasses = computed(() => clsx(tabTextContentVariants()), ...(ngDevMode ? [{ debugName: "textContentClasses" }] : []));
7216
+ // Handle click
7217
+ handleClick() {
7218
+ if (!this.disabled() && this.tabs) {
7219
+ this.tabs.setValue(this.value());
7220
+ }
7221
+ }
7222
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TabsTriggerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7223
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: TabsTriggerComponent, isStandalone: true, selector: "bsg-tabs-trigger", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
7224
+ <button
7225
+ type="button"
7226
+ role="tab"
7227
+ [class]="computedClasses()"
7228
+ class="group"
7229
+ [attr.aria-selected]="isActive()"
7230
+ [attr.aria-controls]="'tabpanel-' + value()"
7231
+ [attr.id]="'tab-' + value()"
7232
+ [attr.data-state]="isActive() ? 'active' : 'inactive'"
7233
+ [attr.data-active]="isActive()"
7234
+ [attr.data-disabled]="disabled() ? '' : null"
7235
+ data-orientation="horizontal"
7236
+ [attr.tabindex]="isActive() ? 0 : -1"
7237
+ [disabled]="disabled()"
7238
+ (click)="handleClick()"
7239
+ >
7240
+ @if (variant() === 'icon-text') {
7241
+ <!-- Icon-text variant layout -->
7242
+ <div [class]="iconContentClasses()">
7243
+ <div [class]="iconCircleClasses()">
7244
+ <ng-content select="[slot='icon']" />
7245
+ </div>
7246
+ <span [class]="labelClasses()">
7247
+ <ng-content select="[slot='label']" />
7248
+ </span>
7249
+ </div>
7250
+ } @else {
7251
+ <!-- Text variant layout -->
7252
+ <span [class]="textContentClasses()">
7253
+ <ng-content />
7254
+ </span>
7255
+ }
7256
+ </button>
7257
+ `, isInline: true, styles: [":host{display:contents}\n"] });
7258
+ }
7259
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TabsTriggerComponent, decorators: [{
7260
+ type: Component,
7261
+ args: [{ selector: 'bsg-tabs-trigger', standalone: true, template: `
7262
+ <button
7263
+ type="button"
7264
+ role="tab"
7265
+ [class]="computedClasses()"
7266
+ class="group"
7267
+ [attr.aria-selected]="isActive()"
7268
+ [attr.aria-controls]="'tabpanel-' + value()"
7269
+ [attr.id]="'tab-' + value()"
7270
+ [attr.data-state]="isActive() ? 'active' : 'inactive'"
7271
+ [attr.data-active]="isActive()"
7272
+ [attr.data-disabled]="disabled() ? '' : null"
7273
+ data-orientation="horizontal"
7274
+ [attr.tabindex]="isActive() ? 0 : -1"
7275
+ [disabled]="disabled()"
7276
+ (click)="handleClick()"
7277
+ >
7278
+ @if (variant() === 'icon-text') {
7279
+ <!-- Icon-text variant layout -->
7280
+ <div [class]="iconContentClasses()">
7281
+ <div [class]="iconCircleClasses()">
7282
+ <ng-content select="[slot='icon']" />
7283
+ </div>
7284
+ <span [class]="labelClasses()">
7285
+ <ng-content select="[slot='label']" />
7286
+ </span>
7287
+ </div>
7288
+ } @else {
7289
+ <!-- Text variant layout -->
7290
+ <span [class]="textContentClasses()">
7291
+ <ng-content />
7292
+ </span>
7293
+ }
7294
+ </button>
7295
+ `, styles: [":host{display:contents}\n"] }]
7296
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }] } });
7297
+
7298
+ /**
7299
+ * Tabs Content Component
7300
+ *
7301
+ * A container for tab panel content. Only displays when its value matches the active tab.
7302
+ *
7303
+ * Usage:
7304
+ * ```html
7305
+ * <bsg-tabs-content [value]="0">
7306
+ * <p>Content for tab 0</p>
7307
+ * </bsg-tabs-content>
7308
+ * ```
7309
+ */
7310
+ class TabsContentComponent {
7311
+ // Inject parent tabs component
7312
+ tabs = inject(TabsComponent, { optional: true });
7313
+ /** The value that identifies which tab this content belongs to */
7314
+ value = input.required(...(ngDevMode ? [{ debugName: "value" }] : []));
7315
+ /** Additional CSS classes */
7316
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
7317
+ // Computed: is this content active?
7318
+ isActive = computed(() => {
7319
+ if (!this.tabs)
7320
+ return false;
7321
+ return this.tabs.activeValue() === this.value();
7322
+ }, ...(ngDevMode ? [{ debugName: "isActive" }] : []));
7323
+ // Computed classes with default mt-2
7324
+ computedClasses = computed(() => clsx('mt-2', this.className()), ...(ngDevMode ? [{ debugName: "computedClasses" }] : []));
7325
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TabsContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7326
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: TabsContentComponent, isStandalone: true, selector: "bsg-tabs-content", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
7327
+ @if (isActive()) {
7328
+ <div
7329
+ role="tabpanel"
7330
+ [id]="'tabpanel-' + value()"
7331
+ [attr.aria-labelledby]="'tab-' + value()"
7332
+ [attr.data-state]="isActive() ? 'active' : 'inactive'"
7333
+ data-orientation="horizontal"
7334
+ [attr.tabindex]="0"
7335
+ [class]="computedClasses()"
7336
+ >
7337
+ <ng-content />
7338
+ </div>
7339
+ }
7340
+ `, isInline: true, styles: [":host{display:contents}\n"] });
7341
+ }
7342
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TabsContentComponent, decorators: [{
7343
+ type: Component,
7344
+ args: [{ selector: 'bsg-tabs-content', standalone: true, template: `
7345
+ @if (isActive()) {
7346
+ <div
7347
+ role="tabpanel"
7348
+ [id]="'tabpanel-' + value()"
7349
+ [attr.aria-labelledby]="'tab-' + value()"
7350
+ [attr.data-state]="isActive() ? 'active' : 'inactive'"
7351
+ data-orientation="horizontal"
7352
+ [attr.tabindex]="0"
7353
+ [class]="computedClasses()"
7354
+ >
7355
+ <ng-content />
7356
+ </div>
7357
+ }
7358
+ `, styles: [":host{display:contents}\n"] }]
7359
+ }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }] } });
7360
+
7361
+ /**
7362
+ * Directive to mark content that should be projected into a specific tab panel
7363
+ *
7364
+ * Usage:
7365
+ * ```html
7366
+ * <bsg-tab-navigation [tabs]="tabs">
7367
+ * <ng-template bsgTabContent>Content for tab 0</ng-template>
7368
+ * <ng-template bsgTabContent>Content for tab 1</ng-template>
7369
+ * </bsg-tab-navigation>
7370
+ * ```
7371
+ */
7372
+ class TabContentDirective {
7373
+ template;
7374
+ constructor(template) {
7375
+ this.template = template;
7376
+ }
7377
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TabContentDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
7378
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.15", type: TabContentDirective, isStandalone: true, selector: "[bsgTabContent]", ngImport: i0 });
7379
+ }
7380
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TabContentDirective, decorators: [{
7381
+ type: Directive,
7382
+ args: [{
7383
+ selector: '[bsgTabContent]',
7384
+ standalone: true,
7385
+ }]
7386
+ }], ctorParameters: () => [{ type: i0.TemplateRef }] });
7387
+ /**
7388
+ * Tab Navigation Component
7389
+ *
7390
+ * A tabbed navigation component with support for text and icon-text variants.
7391
+ * Follows the shadcn/ui tabs pattern with separated TabsList and TabsContent.
7392
+ *
7393
+ * Usage:
7394
+ * ```html
7395
+ * <bsg-tab-navigation
7396
+ * [tabs]="tabs"
7397
+ * [variant]="'text'"
7398
+ * [size]="'md'"
7399
+ * [color]="'default'"
7400
+ * [activeIndex]="0"
7401
+ * (tabChange)="onTabChange($event)"
7402
+ * >
7403
+ * <ng-template bsgTabContent>Content for first tab</ng-template>
7404
+ * <ng-template bsgTabContent>Content for second tab</ng-template>
7405
+ * </bsg-tab-navigation>
7406
+ * ```
7407
+ */
7408
+ class TabNavigationComponent {
7409
+ /** Tab size variant */
7410
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
7411
+ /** Tab visual variant */
7412
+ variant = input('text', ...(ngDevMode ? [{ debugName: "variant" }] : []));
7413
+ /** Tab color scheme */
7414
+ color = input('default', ...(ngDevMode ? [{ debugName: "color" }] : []));
7415
+ /** Whether all tabs are disabled */
7416
+ disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
7417
+ /** List of tab items */
7418
+ tabs = input([
7419
+ { label: 'Solicitudes Realizadas', count: 3 },
7420
+ { label: 'Información del cliente' },
7421
+ ], ...(ngDevMode ? [{ debugName: "tabs" }] : []));
7422
+ /** Active tab index */
7423
+ activeIndex = input(0, ...(ngDevMode ? [{ debugName: "activeIndex" }] : []));
7424
+ /** Additional CSS classes for container */
7425
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
7426
+ /** Tab change event */
7427
+ tabChange = output();
7428
+ /** Content children (tab content templates) */
7429
+ tabContents = contentChildren(TabContentDirective, ...(ngDevMode ? [{ debugName: "tabContents" }] : []));
7430
+ // Internal state for active tab
7431
+ _activeIndex = signal(null, ...(ngDevMode ? [{ debugName: "_activeIndex" }] : []));
7432
+ // Computed active index (uses internal state if set, otherwise input)
7433
+ internalActiveIndex = computed(() => {
7434
+ const internal = this._activeIndex();
7435
+ return internal !== null ? internal : this.activeIndex();
7436
+ }, ...(ngDevMode ? [{ debugName: "internalActiveIndex" }] : []));
7437
+ // Computed container classes
7438
+ containerClasses = computed(() => clsx(this.className()), ...(ngDevMode ? [{ debugName: "containerClasses" }] : []));
7439
+ // Computed tabs list classes
7440
+ tabsListClasses = computed(() => clsx(tabNavigationVariants()), ...(ngDevMode ? [{ debugName: "tabsListClasses" }] : []));
7441
+ // Computed tab content classes
7442
+ tabContentClasses = computed(() => clsx('mt-2'), ...(ngDevMode ? [{ debugName: "tabContentClasses" }] : []));
7443
+ // Computed icon content classes
7444
+ iconContentClasses = computed(() => clsx(tabIconContentVariants()), ...(ngDevMode ? [{ debugName: "iconContentClasses" }] : []));
7445
+ // Computed label classes
7446
+ labelClasses = computed(() => clsx(tabLabelVariants()), ...(ngDevMode ? [{ debugName: "labelClasses" }] : []));
7447
+ // Computed text content classes
7448
+ textContentClasses = computed(() => clsx(tabTextContentVariants()), ...(ngDevMode ? [{ debugName: "textContentClasses" }] : []));
7449
+ // Get tab button classes for a specific index
7450
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
7451
+ getTabClasses(index) {
7452
+ return clsx(tabItemVariants({
7453
+ variant: this.variant(),
7454
+ size: this.size(),
7455
+ color: this.color(),
7456
+ disabled: this.disabled(),
7457
+ }));
7458
+ }
7459
+ // Get icon circle classes
7460
+ getIconCircleClasses() {
7461
+ return clsx(tabIconCircleVariants({
7462
+ color: this.color(),
7463
+ }));
7464
+ }
7465
+ // Get icon stroke color based on active state (uses currentColor to inherit from parent)
7466
+ getIconStroke(_index) {
7467
+ return 'currentColor';
7468
+ }
7469
+ // Handle tab click
7470
+ handleTabClick(index) {
7471
+ if (!this.disabled() && index !== this.internalActiveIndex()) {
7472
+ this._activeIndex.set(index);
7473
+ this.tabChange.emit(index);
7474
+ }
7475
+ }
7476
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TabNavigationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7477
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: TabNavigationComponent, isStandalone: true, selector: "bsg-tab-navigation", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: false, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { tabChange: "tabChange" }, queries: [{ propertyName: "tabContents", predicate: TabContentDirective, isSignal: true }], ngImport: i0, template: `
7478
+ <!-- Tabs Root -->
7479
+ <div [class]="containerClasses()" data-orientation="horizontal">
7480
+ <!-- Tabs List -->
7481
+ <div
7482
+ role="tablist"
7483
+ aria-orientation="horizontal"
7484
+ aria-label="Tab navigation"
7485
+ data-orientation="horizontal"
7486
+ [class]="tabsListClasses()"
7487
+ >
7488
+ @for (tab of tabs(); track $index) {
7489
+ <!-- Tabs Trigger -->
7490
+ <button
7491
+ type="button"
7492
+ role="tab"
7493
+ [class]="getTabClasses($index)"
7494
+ class="group"
7495
+ [attr.aria-selected]="$index === internalActiveIndex()"
7496
+ [attr.aria-controls]="'tabpanel-' + $index"
7497
+ [attr.id]="'tab-' + $index"
7498
+ [attr.data-state]="
7499
+ $index === internalActiveIndex() ? 'active' : 'inactive'
7500
+ "
7501
+ [attr.data-active]="$index === internalActiveIndex()"
7502
+ [attr.data-disabled]="disabled() ? '' : null"
7503
+ data-orientation="horizontal"
7504
+ [attr.tabindex]="$index === internalActiveIndex() ? 0 : -1"
7505
+ [disabled]="disabled()"
7506
+ (click)="handleTabClick($index)"
7507
+ >
7508
+ @if (variant() === 'icon-text') {
7509
+ <div [class]="iconContentClasses()">
7510
+ <div [class]="getIconCircleClasses()">
7511
+ <svg
7512
+ class="block"
7513
+ width="24"
7514
+ height="24"
7515
+ viewBox="0 0 24 24"
7516
+ fill="none"
7517
+ xmlns="http://www.w3.org/2000/svg"
7518
+ aria-hidden="true"
7519
+ >
7520
+ <path
7521
+ d="M19 21V19C19 17.9391 18.5786 16.9217 17.8284 16.1716C17.0783 15.4214 16.0609 15 15 15H9C7.93913 15 6.92172 15.4214 6.17157 16.1716C5.42143 16.9217 5 17.9391 5 19V21M16 7C16 9.20914 14.2091 11 12 11C9.79086 11 8 9.20914 8 7C8 4.79086 9.79086 3 12 3C14.2091 3 16 4.79086 16 7Z"
7522
+ [attr.stroke]="getIconStroke($index)"
7523
+ stroke-width="2"
7524
+ stroke-linecap="round"
7525
+ stroke-linejoin="round"
7526
+ />
7527
+ </svg>
7528
+ </div>
7529
+ <span [class]="labelClasses()">{{ tab.label }}</span>
7530
+ </div>
7531
+ } @else {
7532
+ <span [class]="textContentClasses()">
7533
+ {{ tab.label }}
7534
+ @if (tab.count !== undefined) {
7535
+ ({{ tab.count }})
7536
+ }
7537
+ </span>
7538
+ }
7539
+ </button>
7540
+ }
7541
+ </div>
7542
+
7543
+ <!-- Tabs Content Panels -->
7544
+ @for (tab of tabs(); track $index) {
7545
+ <div
7546
+ role="tabpanel"
7547
+ [id]="'tabpanel-' + $index"
7548
+ [attr.aria-labelledby]="'tab-' + $index"
7549
+ [attr.data-state]="
7550
+ $index === internalActiveIndex() ? 'active' : 'inactive'
7551
+ "
7552
+ data-orientation="horizontal"
7553
+ [attr.tabindex]="0"
7554
+ [attr.hidden]="$index !== internalActiveIndex() ? true : null"
7555
+ [class]="tabContentClasses()"
7556
+ >
7557
+ @if ($index === internalActiveIndex() && tabContents()[$index]) {
7558
+ <ng-container *ngTemplateOutlet="tabContents()[$index].template" />
7559
+ }
7560
+ </div>
7561
+ }
7562
+ </div>
7563
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
7564
+ }
7565
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TabNavigationComponent, decorators: [{
7566
+ type: Component,
7567
+ args: [{ selector: 'bsg-tab-navigation', standalone: true, imports: [NgTemplateOutlet], template: `
7568
+ <!-- Tabs Root -->
7569
+ <div [class]="containerClasses()" data-orientation="horizontal">
7570
+ <!-- Tabs List -->
7571
+ <div
7572
+ role="tablist"
7573
+ aria-orientation="horizontal"
7574
+ aria-label="Tab navigation"
7575
+ data-orientation="horizontal"
7576
+ [class]="tabsListClasses()"
7577
+ >
7578
+ @for (tab of tabs(); track $index) {
7579
+ <!-- Tabs Trigger -->
7580
+ <button
7581
+ type="button"
7582
+ role="tab"
7583
+ [class]="getTabClasses($index)"
7584
+ class="group"
7585
+ [attr.aria-selected]="$index === internalActiveIndex()"
7586
+ [attr.aria-controls]="'tabpanel-' + $index"
7587
+ [attr.id]="'tab-' + $index"
7588
+ [attr.data-state]="
7589
+ $index === internalActiveIndex() ? 'active' : 'inactive'
7590
+ "
7591
+ [attr.data-active]="$index === internalActiveIndex()"
7592
+ [attr.data-disabled]="disabled() ? '' : null"
7593
+ data-orientation="horizontal"
7594
+ [attr.tabindex]="$index === internalActiveIndex() ? 0 : -1"
7595
+ [disabled]="disabled()"
7596
+ (click)="handleTabClick($index)"
7597
+ >
7598
+ @if (variant() === 'icon-text') {
7599
+ <div [class]="iconContentClasses()">
7600
+ <div [class]="getIconCircleClasses()">
7601
+ <svg
7602
+ class="block"
7603
+ width="24"
7604
+ height="24"
7605
+ viewBox="0 0 24 24"
7606
+ fill="none"
7607
+ xmlns="http://www.w3.org/2000/svg"
7608
+ aria-hidden="true"
7609
+ >
7610
+ <path
7611
+ d="M19 21V19C19 17.9391 18.5786 16.9217 17.8284 16.1716C17.0783 15.4214 16.0609 15 15 15H9C7.93913 15 6.92172 15.4214 6.17157 16.1716C5.42143 16.9217 5 17.9391 5 19V21M16 7C16 9.20914 14.2091 11 12 11C9.79086 11 8 9.20914 8 7C8 4.79086 9.79086 3 12 3C14.2091 3 16 4.79086 16 7Z"
7612
+ [attr.stroke]="getIconStroke($index)"
7613
+ stroke-width="2"
7614
+ stroke-linecap="round"
7615
+ stroke-linejoin="round"
7616
+ />
7617
+ </svg>
7618
+ </div>
7619
+ <span [class]="labelClasses()">{{ tab.label }}</span>
7620
+ </div>
7621
+ } @else {
7622
+ <span [class]="textContentClasses()">
7623
+ {{ tab.label }}
7624
+ @if (tab.count !== undefined) {
7625
+ ({{ tab.count }})
7626
+ }
7627
+ </span>
7628
+ }
7629
+ </button>
7630
+ }
7631
+ </div>
7632
+
7633
+ <!-- Tabs Content Panels -->
7634
+ @for (tab of tabs(); track $index) {
7635
+ <div
7636
+ role="tabpanel"
7637
+ [id]="'tabpanel-' + $index"
7638
+ [attr.aria-labelledby]="'tab-' + $index"
7639
+ [attr.data-state]="
7640
+ $index === internalActiveIndex() ? 'active' : 'inactive'
7641
+ "
7642
+ data-orientation="horizontal"
7643
+ [attr.tabindex]="0"
7644
+ [attr.hidden]="$index !== internalActiveIndex() ? true : null"
7645
+ [class]="tabContentClasses()"
7646
+ >
7647
+ @if ($index === internalActiveIndex() && tabContents()[$index]) {
7648
+ <ng-container *ngTemplateOutlet="tabContents()[$index].template" />
7649
+ }
7650
+ </div>
7651
+ }
7652
+ </div>
7653
+ `, styles: [":host{display:block}\n"] }]
7654
+ }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: false }] }], activeIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIndex", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], tabChange: [{ type: i0.Output, args: ["tabChange"] }], tabContents: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TabContentDirective), { isSignal: true }] }] } });
7655
+
7656
+ // New composable components (shadcn/ui pattern)
7657
+
7658
+ /**
7659
+ * Table wrapper variants
7660
+ *
7661
+ * Container with subtle shadow for depth and rounded corners
7662
+ * for a modern, polished look
7663
+ */
7664
+ const tableWrapperVariants = cva(clsx('relative', 'w-full', 'overflow-auto', 'rounded-xl', 'border', 'border-slate-200', 'bg-white',
7665
+ // Subtle shadow for depth perception
7666
+ 'shadow-sm',
7667
+ // Smooth scrollbar for better UX
7668
+ 'scrollbar-thin', 'scrollbar-thumb-slate-300', 'scrollbar-track-transparent'));
7669
+ /**
7670
+ * Table variants
7671
+ *
7672
+ * Clean table with proper spacing and typography
7673
+ */
7674
+ const tableVariants = cva(clsx('w-full', 'caption-bottom', 'text-sm', 'border-collapse', 'border-spacing-0', 'font-sans'));
7675
+ /**
7676
+ * Table Header variants
7677
+ *
7678
+ * Distinct header with subtle background gradient
7679
+ * and clear visual separation from body
7680
+ */
7681
+ const tableHeaderVariants = cva(clsx(
7682
+ // Subtle gradient for visual interest
7683
+ 'bg-gradient-to-b', 'from-blue-50', 'to-blue-50/70',
7684
+ // Border for separation
7685
+ '[&_tr]:border-b', '[&_tr]:border-slate-200',
7686
+ // Sticky header for long tables
7687
+ 'sticky', 'top-0', 'z-10',
7688
+ // Backdrop blur for when scrolling
7689
+ 'backdrop-blur-sm'));
7690
+ /**
7691
+ * Table Body variants
7692
+ *
7693
+ * Clean body with alternating row colors option
7694
+ */
7695
+ const tableBodyVariants = cva(clsx('[&_tr:last-child]:border-0',
7696
+ // Smooth transitions for row interactions
7697
+ '[&_tr]:transition-colors', '[&_tr]:duration-150', '[&_tr]:ease-in-out'));
7698
+ /**
7699
+ * Table Footer variants
7700
+ *
7701
+ * Distinct footer for totals and summaries
7702
+ */
7703
+ const tableFooterVariants = cva(clsx('bg-gradient-to-t', 'from-slate-50', 'to-slate-50/50', 'border-t-2', 'border-slate-200', 'font-semibold', '[&>tr]:last:border-b-0'));
7704
+ /**
7705
+ * Table Row variants
7706
+ *
7707
+ * Interactive rows with clear hover and selected states
7708
+ * Following UX best practices for discoverability
7709
+ */
7710
+ const tableRowVariants = cva(clsx('border-b', 'border-slate-100',
7711
+ // Smooth transition for hover effect
7712
+ 'transition-all', 'duration-150', 'ease-in-out',
7713
+ // Hover state - subtle but noticeable
7714
+ 'hover:bg-slate-50/80',
7715
+ // Selected state - clear visual feedback
7716
+ 'data-[state=selected]:bg-blue-50/60', 'data-[state=selected]:border-blue-100',
7717
+ // Focus within for keyboard navigation
7718
+ 'focus-within:bg-slate-50/50',
7719
+ // Cursor hint for clickable rows
7720
+ 'cursor-default'));
7721
+ /**
7722
+ * Table Head variants
7723
+ *
7724
+ * Clear, readable headers with proper hierarchy
7725
+ * Using semibold weight and blue accent for brand consistency
7726
+ */
7727
+ const tableHeadVariants = cva(clsx(
7728
+ // Vertical rhythm
7729
+ 'h-12', 'px-4', 'py-3',
7730
+ // Alignment
7731
+ 'text-left', 'align-middle',
7732
+ // Typography - clear hierarchy
7733
+ 'font-semibold', 'text-blue-700', 'text-xs', 'uppercase', 'tracking-wide',
7734
+ // Prevent text wrapping for cleaner look
7735
+ 'whitespace-nowrap',
7736
+ // Checkbox alignment
7737
+ '[&:has([role=checkbox])]:pr-0',
7738
+ // Sort indicator space
7739
+ '[&:has(button)]:pr-2'));
7740
+ /**
7741
+ * Table Cell variants
7742
+ *
7743
+ * Readable cells with proper spacing and alignment
7744
+ */
7745
+ const tableCellVariants = cva(clsx(
7746
+ // Generous padding for readability
7747
+ 'px-4', 'py-4',
7748
+ // Alignment
7749
+ 'align-middle',
7750
+ // Typography - optimized for scanning
7751
+ 'text-slate-600', 'text-sm', 'font-normal',
7752
+ // Line height for multi-line content
7753
+ 'leading-relaxed',
7754
+ // Checkbox alignment
7755
+ '[&:has([role=checkbox])]:pr-0',
7756
+ // First column emphasis
7757
+ '[&:first-child]:font-medium', '[&:first-child]:text-slate-900'));
7758
+ /**
7759
+ * Table Card Header variants
7760
+ *
7761
+ * Prominent header with semantic colors and clear hierarchy
7762
+ * Following UX principles for visual weight distribution
7763
+ */
7764
+ const tableCardHeaderVariants = cva(clsx('flex', 'items-center', 'gap-3', 'px-5', 'py-4',
7765
+ // Gradient for visual interest
7766
+ 'bg-gradient-to-r',
7767
+ // Rounded top corners
7768
+ 'rounded-t-xl',
7769
+ // Subtle bottom border
7770
+ 'border-b'), {
7771
+ variants: {
7772
+ color: {
7773
+ default: clsx('from-slate-100', 'to-slate-50', 'border-slate-200/50'),
7774
+ info: clsx('from-blue-100', 'to-blue-50', 'border-blue-200/50'),
7775
+ success: clsx('from-green-100', 'to-green-50', 'border-green-200/50'),
7776
+ warning: clsx('from-amber-100', 'to-amber-50', 'border-amber-200/50'),
7777
+ destructive: clsx('from-red-100', 'to-red-50', 'border-red-200/50'),
7778
+ },
7779
+ },
7780
+ defaultVariants: {
7781
+ color: 'info',
7782
+ },
7783
+ });
7784
+ /**
7785
+ * Table Card Footer variants
7786
+ *
7787
+ * Clean footer area for pagination and actions
7788
+ */
7789
+ const tableCardFooterVariants = cva(clsx('flex', 'items-center', 'justify-between', 'gap-3', 'px-5', 'py-4', 'bg-slate-50/50', 'border-t', 'border-slate-200', 'rounded-b-xl'));
7790
+ /**
7791
+ * Table Pagination wrapper variants
7792
+ *
7793
+ * Clean pagination area with proper spacing
7794
+ */
7795
+ const tablePaginationVariants = cva(clsx('px-4', 'py-3', 'border-t', 'border-slate-100', 'bg-slate-50/30'));
7796
+ /**
7797
+ * Table Empty State variants
7798
+ *
7799
+ * For when table has no data
7800
+ */
7801
+ const tableEmptyStateVariants = cva(clsx('py-12', 'px-4', 'text-center', 'text-slate-400', 'text-sm'));
7802
+ /**
7803
+ * Table Loading State variants
7804
+ *
7805
+ * For skeleton loading states
7806
+ */
7807
+ const tableLoadingVariants = cva(clsx('animate-pulse', 'bg-slate-100', 'rounded'));
7808
+ /**
7809
+ * Striped table modifier
7810
+ *
7811
+ * Apply to tbody for alternating row colors
7812
+ */
7813
+ const tableStripedVariants = cva(clsx('[&>tr:nth-child(even)]:bg-slate-50/50'));
7814
+ /**
7815
+ * Compact table modifier
7816
+ *
7817
+ * Reduced padding for dense data
7818
+ */
7819
+ const tableCompactVariants = cva(clsx('[&_th]:py-2', '[&_th]:px-3', '[&_td]:py-2', '[&_td]:px-3', '[&_th]:text-xs', '[&_td]:text-xs'));
7820
+
7821
+ /**
7822
+ * Table Component
7823
+ *
7824
+ * A responsive table wrapper with semantic HTML table element.
7825
+ * Follows shadcn/ui table structure.
7826
+ *
7827
+ * Usage:
7828
+ * ```html
7829
+ * <bsg-table>
7830
+ * <bsg-table-caption>A list of your recent invoices.</bsg-table-caption>
7831
+ * <bsg-table-header>
7832
+ * <bsg-table-row>
7833
+ * <bsg-table-head>Invoice</bsg-table-head>
7834
+ * <bsg-table-head>Status</bsg-table-head>
7835
+ * </bsg-table-row>
7836
+ * </bsg-table-header>
7837
+ * <bsg-table-body>
7838
+ * <bsg-table-row>
7839
+ * <bsg-table-cell>INV001</bsg-table-cell>
7840
+ * <bsg-table-cell>Paid</bsg-table-cell>
7841
+ * </bsg-table-row>
7842
+ * </bsg-table-body>
7843
+ * </bsg-table>
7844
+ * ```
7845
+ */
7846
+ class TableComponent {
7847
+ /** Additional CSS classes for wrapper */
7848
+ wrapperClassName = input(...(ngDevMode ? [undefined, { debugName: "wrapperClassName" }] : []));
7849
+ /** Additional CSS classes for table */
7850
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
7851
+ wrapperClasses = computed(() => clsx(tableWrapperVariants(), this.wrapperClassName()), ...(ngDevMode ? [{ debugName: "wrapperClasses" }] : []));
7852
+ tableClasses = computed(() => clsx(tableVariants(), this.className()), ...(ngDevMode ? [{ debugName: "tableClasses" }] : []));
7853
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7854
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.15", type: TableComponent, isStandalone: true, selector: "bsg-table", inputs: { wrapperClassName: { classPropertyName: "wrapperClassName", publicName: "wrapperClassName", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
7855
+ <div [class]="wrapperClasses()">
7856
+ <table [class]="tableClasses()">
7857
+ <ng-content />
7858
+ </table>
7859
+ </div>
7860
+ `, isInline: true, styles: [":host{display:block}\n"] });
7861
+ }
7862
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableComponent, decorators: [{
7863
+ type: Component,
7864
+ args: [{ selector: 'bsg-table', standalone: true, template: `
7865
+ <div [class]="wrapperClasses()">
7866
+ <table [class]="tableClasses()">
7867
+ <ng-content />
7868
+ </table>
7869
+ </div>
7870
+ `, styles: [":host{display:block}\n"] }]
7871
+ }], propDecorators: { wrapperClassName: [{ type: i0.Input, args: [{ isSignal: true, alias: "wrapperClassName", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }] } });
7872
+
7873
+ /**
7874
+ * Table Header Component
7875
+ *
7876
+ * Wraps table header rows (thead element).
7877
+ *
7878
+ * Usage:
7879
+ * ```html
7880
+ * <bsg-table-header>
7881
+ * <bsg-table-row>
7882
+ * <bsg-table-head>Column 1</bsg-table-head>
7883
+ * <bsg-table-head>Column 2</bsg-table-head>
7884
+ * </bsg-table-row>
7885
+ * </bsg-table-header>
7886
+ * ```
7887
+ */
7888
+ class TableHeaderComponent {
7889
+ /** Additional CSS classes */
7890
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
7891
+ computedClasses = computed(() => clsx(tableHeaderVariants(), this.className()), ...(ngDevMode ? [{ debugName: "computedClasses" }] : []));
7892
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7893
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.15", type: TableHeaderComponent, isStandalone: true, selector: "bsg-table-header", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
7894
+ <thead [class]="computedClasses()">
7895
+ <ng-content />
7896
+ </thead>
7897
+ `, isInline: true, styles: [":host{display:contents}\n"] });
7898
+ }
7899
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableHeaderComponent, decorators: [{
7900
+ type: Component,
7901
+ args: [{ selector: 'bsg-table-header', standalone: true, template: `
7902
+ <thead [class]="computedClasses()">
7903
+ <ng-content />
7904
+ </thead>
7905
+ `, styles: [":host{display:contents}\n"] }]
7906
+ }], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }] } });
7907
+
7908
+ /**
7909
+ * Table Body Component
7910
+ *
7911
+ * Wraps table body rows (tbody element).
7912
+ *
7913
+ * Usage:
7914
+ * ```html
7915
+ * <bsg-table-body>
7916
+ * <bsg-table-row>
7917
+ * <bsg-table-cell>Cell 1</bsg-table-cell>
7918
+ * <bsg-table-cell>Cell 2</bsg-table-cell>
7919
+ * </bsg-table-row>
7920
+ * </bsg-table-body>
7921
+ * ```
7922
+ */
7923
+ class TableBodyComponent {
7924
+ /** Additional CSS classes */
7925
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
7926
+ computedClasses = computed(() => clsx(tableBodyVariants(), this.className()), ...(ngDevMode ? [{ debugName: "computedClasses" }] : []));
7927
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableBodyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7928
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.15", type: TableBodyComponent, isStandalone: true, selector: "bsg-table-body", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
7929
+ <tbody [class]="computedClasses()">
7930
+ <ng-content />
7931
+ </tbody>
7932
+ `, isInline: true, styles: [":host{display:contents}\n"] });
7933
+ }
7934
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableBodyComponent, decorators: [{
7935
+ type: Component,
7936
+ args: [{ selector: 'bsg-table-body', standalone: true, template: `
7937
+ <tbody [class]="computedClasses()">
7938
+ <ng-content />
7939
+ </tbody>
7940
+ `, styles: [":host{display:contents}\n"] }]
7941
+ }], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }] } });
7942
+
7943
+ /**
7944
+ * Table Footer Component
7945
+ *
7946
+ * Wraps table footer rows (tfoot element).
7947
+ *
7948
+ * Usage:
7949
+ * ```html
7950
+ * <bsg-table-footer>
7951
+ * <bsg-table-row>
7952
+ * <bsg-table-cell colSpan="3">Total</bsg-table-cell>
7953
+ * <bsg-table-cell>$2,500.00</bsg-table-cell>
7954
+ * </bsg-table-row>
7955
+ * </bsg-table-footer>
7956
+ * ```
7957
+ */
7958
+ class TableFooterComponent {
7959
+ /** Additional CSS classes */
7960
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
7961
+ computedClasses = computed(() => clsx(tableFooterVariants(), this.className()), ...(ngDevMode ? [{ debugName: "computedClasses" }] : []));
7962
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7963
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.15", type: TableFooterComponent, isStandalone: true, selector: "bsg-table-footer", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
7964
+ <tfoot [class]="computedClasses()">
7965
+ <ng-content />
7966
+ </tfoot>
7967
+ `, isInline: true, styles: [":host{display:contents}\n"] });
7968
+ }
7969
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableFooterComponent, decorators: [{
7970
+ type: Component,
7971
+ args: [{ selector: 'bsg-table-footer', standalone: true, template: `
7972
+ <tfoot [class]="computedClasses()">
7973
+ <ng-content />
7974
+ </tfoot>
7975
+ `, styles: [":host{display:contents}\n"] }]
7976
+ }], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }] } });
7977
+
7978
+ /**
7979
+ * Table Row Component
7980
+ *
7981
+ * A table row element (tr).
7982
+ *
7983
+ * Usage:
7984
+ * ```html
7985
+ * <bsg-table-row>
7986
+ * <bsg-table-cell>Cell 1</bsg-table-cell>
7987
+ * <bsg-table-cell>Cell 2</bsg-table-cell>
7988
+ * </bsg-table-row>
7989
+ * ```
7990
+ */
7991
+ class TableRowComponent {
7992
+ /** Additional CSS classes */
7993
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
7994
+ /** Whether the row is selected */
7995
+ selected = input(false, ...(ngDevMode ? [{ debugName: "selected" }] : []));
7996
+ computedClasses = computed(() => clsx(tableRowVariants(), this.className()), ...(ngDevMode ? [{ debugName: "computedClasses" }] : []));
7997
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableRowComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
7998
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.15", type: TableRowComponent, isStandalone: true, selector: "bsg-table-row", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
7999
+ <tr
8000
+ [class]="computedClasses()"
8001
+ [attr.data-state]="selected() ? 'selected' : null"
8002
+ >
8003
+ <ng-content />
8004
+ </tr>
8005
+ `, isInline: true, styles: [":host{display:contents}\n"] });
8006
+ }
8007
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableRowComponent, decorators: [{
8008
+ type: Component,
8009
+ args: [{ selector: 'bsg-table-row', standalone: true, template: `
8010
+ <tr
8011
+ [class]="computedClasses()"
8012
+ [attr.data-state]="selected() ? 'selected' : null"
8013
+ >
8014
+ <ng-content />
8015
+ </tr>
8016
+ `, styles: [":host{display:contents}\n"] }]
8017
+ }], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }] } });
8018
+
8019
+ /**
8020
+ * Table Head Component
8021
+ *
8022
+ * A table header cell element (th).
8023
+ *
8024
+ * Usage:
8025
+ * ```html
8026
+ * <bsg-table-head>Column Name</bsg-table-head>
8027
+ * <bsg-table-head className="w-[100px]">ID</bsg-table-head>
8028
+ * <bsg-table-head className="text-right">Amount</bsg-table-head>
8029
+ * ```
8030
+ */
8031
+ class TableHeadComponent {
8032
+ /** Additional CSS classes */
8033
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
8034
+ /** Column span */
8035
+ colSpan = input(...(ngDevMode ? [undefined, { debugName: "colSpan" }] : []));
8036
+ /** Scope attribute for accessibility */
8037
+ scope = input('col', ...(ngDevMode ? [{ debugName: "scope" }] : []));
8038
+ computedClasses = computed(() => clsx(tableHeadVariants(), this.className()), ...(ngDevMode ? [{ debugName: "computedClasses" }] : []));
8039
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableHeadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8040
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.15", type: TableHeadComponent, isStandalone: true, selector: "bsg-table-head", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, colSpan: { classPropertyName: "colSpan", publicName: "colSpan", isSignal: true, isRequired: false, transformFunction: null }, scope: { classPropertyName: "scope", publicName: "scope", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
8041
+ <th
8042
+ [class]="computedClasses()"
8043
+ [attr.colspan]="colSpan()"
8044
+ [scope]="scope()"
8045
+ >
8046
+ <ng-content />
8047
+ </th>
8048
+ `, isInline: true, styles: [":host{display:contents}\n"] });
8049
+ }
8050
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableHeadComponent, decorators: [{
8051
+ type: Component,
8052
+ args: [{ selector: 'bsg-table-head', standalone: true, template: `
8053
+ <th
8054
+ [class]="computedClasses()"
8055
+ [attr.colspan]="colSpan()"
8056
+ [scope]="scope()"
8057
+ >
8058
+ <ng-content />
8059
+ </th>
8060
+ `, styles: [":host{display:contents}\n"] }]
8061
+ }], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], colSpan: [{ type: i0.Input, args: [{ isSignal: true, alias: "colSpan", required: false }] }], scope: [{ type: i0.Input, args: [{ isSignal: true, alias: "scope", required: false }] }] } });
8062
+
8063
+ /**
8064
+ * Table Cell Component
8065
+ *
8066
+ * A table data cell element (td).
8067
+ *
8068
+ * Usage:
8069
+ * ```html
8070
+ * <bsg-table-cell>Cell content</bsg-table-cell>
8071
+ * <bsg-table-cell className="font-medium">Bold content</bsg-table-cell>
8072
+ * <bsg-table-cell className="text-right">$250.00</bsg-table-cell>
8073
+ * <bsg-table-cell [colSpan]="3">Spanning cell</bsg-table-cell>
8074
+ * ```
8075
+ */
8076
+ class TableCellComponent {
8077
+ /** Additional CSS classes */
8078
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
8079
+ /** Column span */
8080
+ colSpan = input(...(ngDevMode ? [undefined, { debugName: "colSpan" }] : []));
8081
+ computedClasses = computed(() => clsx(tableCellVariants(), this.className()), ...(ngDevMode ? [{ debugName: "computedClasses" }] : []));
8082
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableCellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8083
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.15", type: TableCellComponent, isStandalone: true, selector: "bsg-table-cell", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, colSpan: { classPropertyName: "colSpan", publicName: "colSpan", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
8084
+ <td [class]="computedClasses()" [attr.colspan]="colSpan()">
8085
+ <ng-content />
8086
+ </td>
8087
+ `, isInline: true, styles: [":host{display:contents}\n"] });
8088
+ }
8089
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableCellComponent, decorators: [{
8090
+ type: Component,
8091
+ args: [{ selector: 'bsg-table-cell', standalone: true, template: `
8092
+ <td [class]="computedClasses()" [attr.colspan]="colSpan()">
8093
+ <ng-content />
8094
+ </td>
8095
+ `, styles: [":host{display:contents}\n"] }]
8096
+ }], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], colSpan: [{ type: i0.Input, args: [{ isSignal: true, alias: "colSpan", required: false }] }] } });
8097
+
8098
+ /**
8099
+ * Table Card Component
8100
+ *
8101
+ * A wrapper that provides a polished card container for tables,
8102
+ * using content projection for header and footer sections.
8103
+ *
8104
+ * UX Considerations:
8105
+ * - Clear visual hierarchy with prominent header
8106
+ * - Consistent spacing and alignment
8107
+ * - Subtle shadows for depth without distraction
8108
+ * - Flexible composition with header/footer slots
8109
+ *
8110
+ * Usage:
8111
+ * ```html
8112
+ * <bsg-table-card>
8113
+ * <bsg-tableCard-header title="My Table Title">
8114
+ * <button slot="action">New Item</button>
8115
+ * </bsg-tableCard-header>
8116
+ *
8117
+ * <bsg-table>
8118
+ * ...
8119
+ * </bsg-table>
8120
+ *
8121
+ * <bsg-tableCard-footer>
8122
+ * <span>Showing 1-10 of 100</span>
8123
+ * </bsg-tableCard-footer>
8124
+ * </bsg-table-card>
8125
+ * ```
8126
+ */
8127
+ class TableCardComponent {
8128
+ /** Additional CSS classes for the card container */
8129
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
8130
+ cardClasses = computed(() => clsx('w-full', 'rounded-xl', 'border', 'border-slate-200', 'bg-white', 'shadow-sm', 'overflow-hidden', 'transition-shadow', 'duration-200', 'hover:shadow-md', this.className()), ...(ngDevMode ? [{ debugName: "cardClasses" }] : []));
8131
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8132
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.15", type: TableCardComponent, isStandalone: true, selector: "bsg-table-card", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
8133
+ <div [class]="cardClasses()">
8134
+ <!-- Header slot -->
8135
+ <ng-content select="bsg-tableCard-header" />
8136
+
8137
+ <!-- Content wrapper - removes nested borders/shadows -->
8138
+ <div
8139
+ class="[&>bsg-table]:rounded-none [&>bsg-table>div]:rounded-none [&>bsg-table>div]:border-0 [&>bsg-table>div]:shadow-none"
8140
+ >
8141
+ <ng-content />
8142
+ </div>
8143
+
8144
+ <!-- Footer slot -->
8145
+ <ng-content select="bsg-tableCard-footer" />
8146
+ </div>
8147
+ `, isInline: true, styles: [":host{display:block}\n"] });
8148
+ }
8149
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableCardComponent, decorators: [{
8150
+ type: Component,
8151
+ args: [{ selector: 'bsg-table-card', standalone: true, template: `
8152
+ <div [class]="cardClasses()">
8153
+ <!-- Header slot -->
8154
+ <ng-content select="bsg-tableCard-header" />
8155
+
8156
+ <!-- Content wrapper - removes nested borders/shadows -->
8157
+ <div
8158
+ class="[&>bsg-table]:rounded-none [&>bsg-table>div]:rounded-none [&>bsg-table>div]:border-0 [&>bsg-table>div]:shadow-none"
8159
+ >
8160
+ <ng-content />
8161
+ </div>
8162
+
8163
+ <!-- Footer slot -->
8164
+ <ng-content select="bsg-tableCard-footer" />
8165
+ </div>
8166
+ `, styles: [":host{display:block}\n"] }]
8167
+ }], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }] } });
8168
+
8169
+ /**
8170
+ * Table Card Header Component
8171
+ *
8172
+ * Header section for table cards with content projection for icon and title.
8173
+ *
8174
+ * Usage:
8175
+ * ```html
8176
+ * <!-- Simple title -->
8177
+ * <bsg-tableCard-header>
8178
+ * <span>Titulo de la Tabla</span>
8179
+ * </bsg-tableCard-header>
8180
+ *
8181
+ * <!-- With icon and title -->
8182
+ * <bsg-tableCard-header color="info">
8183
+ * <svg class="size-5">...</svg>
8184
+ * <span>Titulo de la Tabla</span>
8185
+ * </bsg-tableCard-header>
8186
+ *
8187
+ * <!-- With icon, title and action -->
8188
+ * <bsg-tableCard-header color="success">
8189
+ * <svg class="size-5">...</svg>
8190
+ * <span>Titulo de la Tabla</span>
8191
+ * <button slot="action">Nueva Accion</button>
8192
+ * </bsg-tableCard-header>
8193
+ * ```
8194
+ */
8195
+ class TableCardHeaderComponent {
8196
+ /** Semantic color variant */
8197
+ color = input('info', ...(ngDevMode ? [{ debugName: "color" }] : []));
8198
+ /** Additional CSS classes for header */
8199
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
8200
+ headerClasses = computed(() => clsx(tableCardHeaderVariants({ color: this.color() }), this.className()), ...(ngDevMode ? [{ debugName: "headerClasses" }] : []));
8201
+ contentClasses = computed(() => {
8202
+ const colorMap = {
8203
+ default: 'text-slate-800',
8204
+ info: 'text-blue-800',
8205
+ success: 'text-green-800',
8206
+ warning: 'text-amber-800',
8207
+ destructive: 'text-red-800',
8208
+ };
8209
+ return clsx('flex', 'items-center', 'gap-3', 'flex-1', 'text-base', 'font-semibold', 'leading-tight', 'tracking-tight', colorMap[this.color()]);
8210
+ }, ...(ngDevMode ? [{ debugName: "contentClasses" }] : []));
8211
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableCardHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8212
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.15", type: TableCardHeaderComponent, isStandalone: true, selector: "bsg-tableCard-header", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
8213
+ <div [class]="headerClasses()">
8214
+ <!-- Content (icon + title) -->
8215
+ <div [class]="contentClasses()">
8216
+ <ng-content />
8217
+ </div>
8218
+
8219
+ <!-- Action slot -->
8220
+ <div class="ml-auto flex items-center gap-2">
8221
+ <ng-content select="[slot='action']" />
8222
+ </div>
8223
+ </div>
8224
+ `, isInline: true, styles: [":host{display:block}\n"] });
8225
+ }
8226
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableCardHeaderComponent, decorators: [{
8227
+ type: Component,
8228
+ args: [{ selector: 'bsg-tableCard-header', standalone: true, template: `
8229
+ <div [class]="headerClasses()">
8230
+ <!-- Content (icon + title) -->
8231
+ <div [class]="contentClasses()">
8232
+ <ng-content />
8233
+ </div>
8234
+
8235
+ <!-- Action slot -->
8236
+ <div class="ml-auto flex items-center gap-2">
8237
+ <ng-content select="[slot='action']" />
8238
+ </div>
8239
+ </div>
8240
+ `, styles: [":host{display:block}\n"] }]
8241
+ }], propDecorators: { color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }] } });
8242
+
8243
+ /**
8244
+ * Table Card Footer Component
8245
+ *
8246
+ * Footer section for table cards, typically used for pagination,
8247
+ * summary info, or action buttons.
8248
+ *
8249
+ * Usage:
8250
+ * ```html
8251
+ * <bsg-tableCard-footer>
8252
+ * <span>Showing 1-10 of 100</span>
8253
+ * <div>
8254
+ * <button>Previous</button>
8255
+ * <button>Next</button>
8256
+ * </div>
8257
+ * </bsg-tableCard-footer>
8258
+ * ```
8259
+ */
8260
+ class TableCardFooterComponent {
8261
+ /** Additional CSS classes */
8262
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
8263
+ footerClasses = computed(() => clsx(tableCardFooterVariants(), this.className()), ...(ngDevMode ? [{ debugName: "footerClasses" }] : []));
8264
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableCardFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8265
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.15", type: TableCardFooterComponent, isStandalone: true, selector: "bsg-tableCard-footer", inputs: { className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
8266
+ <div [class]="footerClasses()">
8267
+ <ng-content />
8268
+ </div>
8269
+ `, isInline: true, styles: [":host{display:block}\n"] });
8270
+ }
8271
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableCardFooterComponent, decorators: [{
8272
+ type: Component,
8273
+ args: [{ selector: 'bsg-tableCard-footer', standalone: true, template: `
8274
+ <div [class]="footerClasses()">
8275
+ <ng-content />
8276
+ </div>
8277
+ `, styles: [":host{display:block}\n"] }]
8278
+ }], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }] } });
8279
+
8280
+ /**
8281
+ * Pagination container variants
8282
+ *
8283
+ * Main wrapper for the pagination component
8284
+ */
8285
+ const paginationContainerVariants = cva(clsx(
8286
+ // Layout
8287
+ 'flex items-center gap-4',
8288
+ // Size
8289
+ 'h-[29px]',
8290
+ // Typography
8291
+ 'font-sans',
8292
+ // Responsive
8293
+ 'max-md:flex-wrap max-md:h-auto max-md:gap-3'));
8294
+ /**
8295
+ * Pagination section left variants
8296
+ *
8297
+ * Contains page number input
8298
+ */
8299
+ const paginationSectionLeftVariants = cva(clsx(
8300
+ // Layout
8301
+ 'flex items-center gap-2'));
8302
+ /**
8303
+ * Pagination section middle variants
8304
+ *
8305
+ * Contains page size selector
8306
+ */
8307
+ const paginationSectionMiddleVariants = cva(clsx(
8308
+ // Layout
8309
+ 'flex items-center gap-2.5'));
8310
+ /**
8311
+ * Pagination section right variants
8312
+ *
8313
+ * Contains range label and navigation controls
8314
+ */
8315
+ const paginationSectionRightVariants = cva(clsx(
8316
+ // Layout
8317
+ 'flex items-center gap-[17px]',
8318
+ // Positioning
8319
+ 'ml-auto',
8320
+ // Responsive
8321
+ 'max-md:ml-0 max-md:w-full max-md:justify-between'));
8322
+ /**
8323
+ * Pagination label variants
8324
+ *
8325
+ * Standard label text style
8326
+ */
8327
+ const paginationLabelVariants = cva(clsx(
8328
+ // Typography
8329
+ 'text-muted-foreground text-[13px] font-medium leading-normal tracking-[-0.26px]'));
8330
+ /**
8331
+ * Pagination range label variants
8332
+ *
8333
+ * Range display text (e.g., "1 - 5 de 5 ítems")
8334
+ */
8335
+ const paginationRangeLabelVariants = cva(clsx(
8336
+ // Typography
8337
+ 'text-muted-foreground text-[13px] font-medium leading-normal tracking-[-0.26px]',
8338
+ // Text behavior
8339
+ 'whitespace-nowrap'));
8340
+ /**
8341
+ * Pagination input variants
8342
+ *
8343
+ * Page number input field
8344
+ */
8345
+ const paginationInputVariants = cva(clsx(
8346
+ // Size
8347
+ 'w-[42px] h-[29px]',
8348
+ // Spacing
8349
+ 'px-2',
8350
+ // Border
8351
+ 'rounded-md border border-border',
8352
+ // Background
8353
+ 'bg-background',
8354
+ // Typography
8355
+ 'text-muted-foreground font-sans text-[13px] font-medium leading-normal tracking-[-0.26px] text-center',
8356
+ // Focus
8357
+ 'outline-none',
8358
+ // Transitions
8359
+ 'transition-all duration-200',
8360
+ // Remove number input spinners
8361
+ '[appearance:textfield]', '[&::-webkit-outer-spin-button]:appearance-none', '[&::-webkit-inner-spin-button]:appearance-none',
8362
+ // States
8363
+ 'hover:enabled:border-muted-foreground/30', 'focus:border-ring focus:ring-2 focus:ring-ring/30', 'disabled:bg-muted disabled:cursor-not-allowed disabled:opacity-50'));
8364
+ /**
8365
+ * Pagination select wrapper variants
8366
+ *
8367
+ * Wrapper for the select dropdown
8368
+ */
8369
+ const paginationSelectWrapperVariants = cva(clsx(
8370
+ // Position
8371
+ 'relative',
8372
+ // Display
8373
+ 'inline-block'));
8374
+ /**
8375
+ * Pagination select variants
8376
+ *
8377
+ * Page size select dropdown
8378
+ */
8379
+ const paginationSelectVariants = cva(clsx(
8380
+ // Size
8381
+ 'w-[47px] h-[29px]',
8382
+ // Spacing
8383
+ 'pl-2 pr-6',
8384
+ // Border
8385
+ 'rounded-md border border-border',
8386
+ // Background
8387
+ 'bg-background',
8388
+ // Typography
8389
+ 'text-muted-foreground font-sans text-[13px] font-medium leading-normal tracking-[-0.26px]',
8390
+ // Focus
8391
+ 'outline-none',
8392
+ // Cursor
8393
+ 'cursor-pointer',
8394
+ // Appearance
8395
+ 'appearance-none',
8396
+ // Transitions
8397
+ 'transition-all duration-200',
8398
+ // States
8399
+ 'hover:enabled:border-muted-foreground/30', 'focus:border-ring focus:ring-2 focus:ring-ring/30'));
8400
+ /**
8401
+ * Pagination select icon variants
8402
+ *
8403
+ * Dropdown chevron icon
8404
+ */
8405
+ const paginationSelectIconVariants = cva(clsx(
8406
+ // Position
8407
+ 'absolute right-[7px] top-1/2 -translate-y-1/2',
8408
+ // Pointer events
8409
+ 'pointer-events-none'));
8410
+ /**
8411
+ * Pagination navigation controls variants
8412
+ *
8413
+ * Container for navigation buttons
8414
+ */
8415
+ const paginationNavControlsVariants = cva(clsx(
8416
+ // Layout
8417
+ 'flex items-center gap-[7px]'));
8418
+ /**
8419
+ * Pagination navigation button variants
8420
+ *
8421
+ * Navigation buttons (first, prev, next, last, refresh)
8422
+ */
8423
+ const paginationNavButtonVariants = cva(clsx(
8424
+ // Size
8425
+ 'w-[29px] h-[29px]',
8426
+ // Layout
8427
+ 'flex items-center justify-center',
8428
+ // Border
8429
+ 'rounded-md border border-border',
8430
+ // Background
8431
+ 'bg-background',
8432
+ // Cursor
8433
+ 'cursor-pointer',
8434
+ // Focus
8435
+ 'outline-none',
8436
+ // Spacing
8437
+ 'p-0',
8438
+ // Transitions
8439
+ 'transition-all duration-200',
8440
+ // States
8441
+ 'hover:enabled:bg-muted hover:enabled:border-muted-foreground/30', 'active:enabled:bg-muted/80', 'focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/30', 'disabled:cursor-not-allowed disabled:opacity-40',
8442
+ // Disabled SVG color
8443
+ '[&:disabled_svg_path]:fill-muted-foreground'), {
8444
+ variants: {
8445
+ isRefresh: {
8446
+ true: 'w-[30px]',
8447
+ false: '',
8448
+ },
8449
+ },
8450
+ defaultVariants: {
8451
+ isRefresh: false,
8452
+ },
8453
+ });
8454
+
8455
+ class PaginationComponent {
8456
+ /** Inputs (API existente) */
8457
+ currentPage = input(1, ...(ngDevMode ? [{ debugName: "currentPage" }] : []));
8458
+ totalPages = input(1, ...(ngDevMode ? [{ debugName: "totalPages" }] : [])); // se mantiene, pero se "resuelve" automáticamente
8459
+ pageSize = input(5, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
8460
+ pageSizeOptions = input([5, 10, 20], ...(ngDevMode ? [{ debugName: "pageSizeOptions" }] : []));
8461
+ totalItems = input(5, ...(ngDevMode ? [{ debugName: "totalItems" }] : []));
8462
+ rangeLabel = input('', ...(ngDevMode ? [{ debugName: "rangeLabel" }] : [])); // se mantiene, pero ahora el label se calcula
8463
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
8464
+ /** Outputs (API existente) */
8465
+ pageChange = output();
8466
+ pageSizeChange = output();
8467
+ paginationChange = output();
8468
+ refresh = output();
8469
+ /** Estado interno (para que el componente funcione sin que el padre lo controle) */
8470
+ pageSig = signal(1, ...(ngDevMode ? [{ debugName: "pageSig" }] : []));
8471
+ pageSizeSig = signal(5, ...(ngDevMode ? [{ debugName: "pageSizeSig" }] : []));
8472
+ /** Buffer para edición del input */
8473
+ tempPageValue = signal('', ...(ngDevMode ? [{ debugName: "tempPageValue" }] : []));
8474
+ constructor() {
8475
+ // Sincroniza estado interno si el padre cambia inputs desde afuera (Storybook Controls o app real)
8476
+ effect(() => {
8477
+ this.pageSig.set(this.currentPage());
8478
+ });
8479
+ effect(() => {
8480
+ this.pageSizeSig.set(this.pageSize());
8481
+ });
8482
+ // Si cambia pageSizeOptions y el pageSize actual ya no existe, cae al primero
8483
+ effect(() => {
8484
+ const opts = this.pageSizeOptions();
8485
+ if (opts.length === 0)
8486
+ return;
8487
+ const current = this.pageSizeSig();
8488
+ if (!opts.includes(current)) {
8489
+ this.setPageSize(opts[0]);
8490
+ }
8491
+ });
8492
+ }
8493
+ /** Total pages calculado con totalItems/pageSize */
8494
+ resolvedTotalPages = computed(() => {
8495
+ const totalItems = this.totalItems();
8496
+ const size = this.pageSizeSig();
8497
+ if (totalItems > 0 && size > 0) {
8498
+ return Math.max(0, Math.ceil(totalItems / size));
8499
+ }
8500
+ // fallback si no hay totalItems (o es 0) => respeta el input
8501
+ return Math.max(0, this.totalPages());
8502
+ }, ...(ngDevMode ? [{ debugName: "resolvedTotalPages" }] : []));
8503
+ /** Range label calculado (siempre) */
8504
+ computedRangeLabel = computed(() => {
8505
+ const total = this.totalItems();
8506
+ const page = this.pageSig();
8507
+ const size = this.pageSizeSig();
8508
+ if (total <= 0 || size <= 0 || this.resolvedTotalPages() === 0) {
8509
+ return `0 - 0 de ${Math.max(0, total)} ítems`;
8510
+ }
8511
+ const start = (page - 1) * size + 1;
8512
+ const end = Math.min(total, page * size);
8513
+ return `${start} - ${end} de ${total} ítems`;
8514
+ }, ...(ngDevMode ? [{ debugName: "computedRangeLabel" }] : []));
8515
+ /** Valor visible en el input de página */
8516
+ pageInputValue = computed(() => {
8517
+ const tmp = this.tempPageValue();
8518
+ return tmp !== '' ? tmp : String(this.pageSig());
8519
+ }, ...(ngDevMode ? [{ debugName: "pageInputValue" }] : []));
8520
+ // Classes
8521
+ containerClasses = computed(() => clsx(paginationContainerVariants(), this.className()), ...(ngDevMode ? [{ debugName: "containerClasses" }] : []));
8522
+ sectionLeftClasses = computed(() => clsx(paginationSectionLeftVariants()), ...(ngDevMode ? [{ debugName: "sectionLeftClasses" }] : []));
8523
+ sectionMiddleClasses = computed(() => clsx(paginationSectionMiddleVariants()), ...(ngDevMode ? [{ debugName: "sectionMiddleClasses" }] : []));
8524
+ sectionRightClasses = computed(() => clsx(paginationSectionRightVariants()), ...(ngDevMode ? [{ debugName: "sectionRightClasses" }] : []));
8525
+ labelClasses = computed(() => clsx(paginationLabelVariants()), ...(ngDevMode ? [{ debugName: "labelClasses" }] : []));
8526
+ rangeLabelClasses = computed(() => clsx(paginationRangeLabelVariants()), ...(ngDevMode ? [{ debugName: "rangeLabelClasses" }] : []));
8527
+ inputClasses = computed(() => clsx(paginationInputVariants()), ...(ngDevMode ? [{ debugName: "inputClasses" }] : []));
8528
+ selectWrapperClasses = computed(() => clsx(paginationSelectWrapperVariants()), ...(ngDevMode ? [{ debugName: "selectWrapperClasses" }] : []));
8529
+ selectClasses = computed(() => clsx(paginationSelectVariants()), ...(ngDevMode ? [{ debugName: "selectClasses" }] : []));
8530
+ selectIconClasses = computed(() => clsx(paginationSelectIconVariants()), ...(ngDevMode ? [{ debugName: "selectIconClasses" }] : []));
8531
+ navControlsClasses = computed(() => clsx(paginationNavControlsVariants()), ...(ngDevMode ? [{ debugName: "navControlsClasses" }] : []));
8532
+ navButtonClasses = computed(() => clsx(paginationNavButtonVariants({ isRefresh: false })), ...(ngDevMode ? [{ debugName: "navButtonClasses" }] : []));
8533
+ refreshButtonClasses = computed(() => clsx(paginationNavButtonVariants({ isRefresh: true })), ...(ngDevMode ? [{ debugName: "refreshButtonClasses" }] : []));
8534
+ // Navigation
8535
+ goToFirstPage() {
8536
+ if (this.resolvedTotalPages() > 0)
8537
+ this.updatePage(1);
8538
+ }
8539
+ goToPreviousPage() {
8540
+ if (this.pageSig() > 1)
8541
+ this.updatePage(this.pageSig() - 1);
8542
+ }
8543
+ goToNextPage() {
8544
+ if (this.pageSig() < this.resolvedTotalPages())
8545
+ this.updatePage(this.pageSig() + 1);
8546
+ }
8547
+ goToLastPage() {
8548
+ const last = this.resolvedTotalPages();
8549
+ if (last > 0)
8550
+ this.updatePage(last);
8551
+ }
8552
+ // Page input handling
8553
+ onPageInputFocus() {
8554
+ this.tempPageValue.set(String(this.pageSig()));
8555
+ }
8556
+ onPageInputChange(event) {
8557
+ const inputEl = event.target;
8558
+ this.tempPageValue.set(inputEl.value);
8559
+ }
8560
+ onPageInputBlur() {
8561
+ const tempValue = this.tempPageValue().trim();
8562
+ if (tempValue === '') {
8563
+ this.tempPageValue.set('');
8564
+ return;
8565
+ }
8566
+ let page = parseInt(tempValue, 10);
8567
+ if (Number.isNaN(page)) {
8568
+ this.tempPageValue.set('');
8569
+ return;
8570
+ }
8571
+ page = Math.max(1, Math.min(page, this.resolvedTotalPages() || 1));
8572
+ this.updatePage(page);
8573
+ this.tempPageValue.set('');
8574
+ }
8575
+ // Page size change
8576
+ onPageSizeSelectChange(event) {
8577
+ const select = event.target;
8578
+ const newSize = parseInt(select.value, 10);
8579
+ if (Number.isNaN(newSize) || newSize <= 0)
8580
+ return;
8581
+ if (newSize !== this.pageSizeSig()) {
8582
+ this.setPageSize(newSize);
8583
+ }
8584
+ }
8585
+ setPageSize(newSize) {
8586
+ this.pageSizeSig.set(newSize);
8587
+ // Ajusta página actual si se sale del rango con el nuevo totalPages
8588
+ const max = this.resolvedTotalPages();
8589
+ const nextPage = Math.max(1, Math.min(this.pageSig(), max || 1));
8590
+ // Si prefieres resetear siempre a 1 al cambiar tamaño, cambia por: this.updatePage(1)
8591
+ this.pageSig.set(nextPage);
8592
+ this.pageSizeChange.emit(newSize);
8593
+ this.paginationChange.emit({ currentPage: nextPage, pageSize: newSize });
8594
+ // Si el clamp cambió la página, también notificamos pageChange
8595
+ if (nextPage !== this.currentPage()) {
8596
+ this.pageChange.emit(nextPage);
8597
+ }
8598
+ }
8599
+ onRefresh() {
8600
+ this.refresh.emit();
8601
+ }
8602
+ updatePage(page) {
8603
+ const max = this.resolvedTotalPages();
8604
+ const clamped = Math.max(1, Math.min(page, max || 1));
8605
+ this.pageSig.set(clamped);
8606
+ this.tempPageValue.set('');
8607
+ this.pageChange.emit(clamped);
8608
+ this.paginationChange.emit({
8609
+ currentPage: clamped,
8610
+ pageSize: this.pageSizeSig(),
8611
+ });
8612
+ }
8613
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: PaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8614
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: PaginationComponent, isStandalone: true, selector: "bsg-pagination", inputs: { currentPage: { classPropertyName: "currentPage", publicName: "currentPage", isSignal: true, isRequired: false, transformFunction: null }, totalPages: { classPropertyName: "totalPages", publicName: "totalPages", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: false, transformFunction: null }, rangeLabel: { classPropertyName: "rangeLabel", publicName: "rangeLabel", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageChange: "pageChange", pageSizeChange: "pageSizeChange", paginationChange: "paginationChange", refresh: "refresh" }, ngImport: i0, template: `
8615
+ <div [class]="containerClasses()">
8616
+ <!-- Left section: Current page -->
8617
+ <div [class]="sectionLeftClasses()">
8618
+ <span [class]="labelClasses()">Página</span>
8619
+ <input
8620
+ type="number"
8621
+ [class]="inputClasses()"
8622
+ [value]="pageInputValue()"
8623
+ [min]="1"
8624
+ [max]="resolvedTotalPages()"
8625
+ (focus)="onPageInputFocus()"
8626
+ (input)="onPageInputChange($event)"
8627
+ (keydown.enter)="onPageInputBlur()"
8628
+ (blur)="onPageInputBlur()"
8629
+ [disabled]="resolvedTotalPages() === 0"
8630
+ />
8631
+ <span [class]="labelClasses()">de {{ resolvedTotalPages() }}</span>
8632
+ </div>
8633
+
8634
+ <!-- Middle section: Page size selector -->
8635
+ <div [class]="sectionMiddleClasses()">
8636
+ <div [class]="selectWrapperClasses()">
8637
+ <select
8638
+ [class]="selectClasses()"
8639
+ [value]="pageSizeSig()"
8640
+ (change)="onPageSizeSelectChange($event)"
8641
+ >
8642
+ @for (option of pageSizeOptions(); track option) {
8643
+ <option [value]="option">{{ option }}</option>
8644
+ }
8645
+ </select>
8646
+
8647
+ <svg
8648
+ [class]="selectIconClasses()"
8649
+ width="15"
8650
+ height="15"
8651
+ viewBox="0 0 15 15"
8652
+ fill="none"
8653
+ xmlns="http://www.w3.org/2000/svg"
8654
+ >
8655
+ <path
8656
+ d="M10.8081 5.18312C11.0522 4.93904 11.4478 4.93904 11.6919 5.18312C11.936 5.4272 11.936 5.82283 11.6919 6.06691L7.94191 9.81691C7.69783 10.061 7.3022 10.061 7.05812 9.81691L3.30812 6.06691C3.06404 5.82283 3.06404 5.4272 3.30812 5.18312C3.5522 4.93904 3.94783 4.93904 4.19191 5.18312L7.50001 8.49122L10.8081 5.18312Z"
8657
+ fill="#848485"
8658
+ />
8659
+ </svg>
8660
+ </div>
8661
+ <span [class]="labelClasses()">ítems por página</span>
8662
+ </div>
8663
+
8664
+ <!-- Right section: Range label and navigation -->
8665
+ <div [class]="sectionRightClasses()">
8666
+ <span [class]="rangeLabelClasses()">{{ computedRangeLabel() }}</span>
8667
+
8668
+ <div [class]="navControlsClasses()">
8669
+ <!-- First page -->
8670
+ <button
8671
+ type="button"
8672
+ [class]="navButtonClasses()"
8673
+ [disabled]="pageSig() === 1 || resolvedTotalPages() === 0"
8674
+ (click)="goToFirstPage()"
8675
+ aria-label="Primera página"
8676
+ >
8677
+ <svg
8678
+ width="15"
8679
+ height="15"
8680
+ viewBox="0 0 15 15"
8681
+ fill="none"
8682
+ xmlns="http://www.w3.org/2000/svg"
8683
+ >
8684
+ <path
8685
+ d="M6.43312 3.93312C6.6772 3.68904 7.07283 3.68904 7.31691 3.93312C7.56099 4.1772 7.56099 4.57283 7.31691 4.81691L4.6338 7.50001L7.31691 10.1831C7.56099 10.4272 7.56099 10.8228 7.31691 11.0669C7.07283 11.311 6.6772 11.311 6.43312 11.0669L3.30812 7.94191C3.06404 7.69783 3.06404 7.3022 3.30812 7.05812L6.43312 3.93312ZM10.8081 3.93312C11.0522 3.68904 11.4478 3.68904 11.6919 3.93312C11.936 4.1772 11.936 4.57283 11.6919 4.81691L9.0088 7.50001L11.6919 10.1831C11.936 10.4272 11.936 10.8228 11.6919 11.0669C11.4478 11.311 11.0522 11.311 10.8081 11.0669L7.68312 7.94191C7.43904 7.69783 7.43904 7.3022 7.68312 7.05812L10.8081 3.93312Z"
8686
+ fill="#939394"
8687
+ />
8688
+ </svg>
8689
+ </button>
8690
+
8691
+ <!-- Previous page -->
8692
+ <button
8693
+ type="button"
8694
+ [class]="navButtonClasses()"
8695
+ [disabled]="pageSig() === 1 || resolvedTotalPages() === 0"
8696
+ (click)="goToPreviousPage()"
8697
+ aria-label="Página anterior"
8698
+ >
8699
+ <svg
8700
+ width="14"
8701
+ height="14"
8702
+ viewBox="0 0 14 14"
8703
+ fill="none"
8704
+ xmlns="http://www.w3.org/2000/svg"
8705
+ >
8706
+ <path
8707
+ d="M8.33754 3.08754C8.56535 2.85974 8.93461 2.85974 9.16241 3.08754C9.39022 3.31535 9.39022 3.68461 9.16241 3.91241L6.07485 6.99998L9.16241 10.0875C9.39022 10.3153 9.39022 10.6846 9.16241 10.9124C8.93461 11.1402 8.56535 11.1402 8.33754 10.9124L4.83754 7.41241C4.60974 7.18461 4.60974 6.81535 4.83754 6.58754L8.33754 3.08754Z"
8708
+ fill="#939394"
8709
+ />
8710
+ </svg>
8711
+ </button>
8712
+
8713
+ <!-- Next page -->
8714
+ <button
8715
+ type="button"
8716
+ [class]="navButtonClasses()"
8717
+ [disabled]="
8718
+ pageSig() >= resolvedTotalPages() || resolvedTotalPages() === 0
8719
+ "
8720
+ (click)="goToNextPage()"
8721
+ aria-label="Página siguiente"
8722
+ >
8723
+ <svg
8724
+ width="16"
8725
+ height="16"
8726
+ viewBox="0 0 16 16"
8727
+ fill="none"
8728
+ xmlns="http://www.w3.org/2000/svg"
8729
+ >
8730
+ <path
8731
+ d="M5.52864 3.52864C5.78899 3.26829 6.21099 3.26829 6.47134 3.52864L10.4713 7.52864C10.7317 7.78899 10.7317 8.211 10.4713 8.47134L6.47134 12.4713C6.21099 12.7317 5.78899 12.7317 5.52864 12.4713C5.26829 12.211 5.26829 11.789 5.52864 11.5286L9.05728 7.99999L5.52864 4.47134C5.26829 4.21099 5.26829 3.78899 5.52864 3.52864Z"
8732
+ fill="#939394"
8733
+ />
8734
+ </svg>
8735
+ </button>
8736
+
8737
+ <!-- Last page -->
8738
+ <button
8739
+ type="button"
8740
+ [class]="navButtonClasses()"
8741
+ [disabled]="
8742
+ pageSig() >= resolvedTotalPages() || resolvedTotalPages() === 0
8743
+ "
8744
+ (click)="goToLastPage()"
8745
+ aria-label="Última página"
8746
+ >
8747
+ <svg
8748
+ width="16"
8749
+ height="16"
8750
+ viewBox="0 0 16 16"
8751
+ fill="none"
8752
+ xmlns="http://www.w3.org/2000/svg"
8753
+ >
8754
+ <path
8755
+ d="M3.52864 4.19532C3.78899 3.93497 4.21099 3.93497 4.47134 4.19532L7.80468 7.52866C8.06503 7.78901 8.06503 8.21102 7.80468 8.47136L4.47134 11.8047C4.21099 12.065 3.78899 12.065 3.52864 11.8047C3.26829 11.5443 3.26829 11.1223 3.52864 10.862L6.39062 8.00001L3.52864 5.13803C3.26829 4.87768 3.26829 4.45567 3.52864 4.19532ZM8.1953 4.19532C8.45565 3.93497 8.87766 3.93497 9.13801 4.19532L12.4713 7.52866C12.7317 7.78901 12.7317 8.21102 12.4713 8.47136L9.13801 11.8047C8.87766 12.065 8.45565 12.065 8.1953 11.8047C7.93495 11.5443 7.93495 11.1223 8.1953 10.862L11.0573 8.00001L8.1953 5.13803C7.93495 4.87768 7.93495 4.45567 8.1953 4.19532Z"
8756
+ fill="#939394"
8757
+ />
8758
+ </svg>
8759
+ </button>
8760
+
8761
+ <!-- Refresh -->
8762
+ <button
8763
+ type="button"
8764
+ [class]="refreshButtonClasses()"
8765
+ (click)="onRefresh()"
8766
+ aria-label="Refrescar"
8767
+ >
8768
+ <svg
8769
+ width="14"
8770
+ height="14"
8771
+ viewBox="0 0 14 14"
8772
+ fill="none"
8773
+ xmlns="http://www.w3.org/2000/svg"
8774
+ >
8775
+ <path
8776
+ d="M1.16663 12.25V9.33332C1.16663 9.01116 1.42779 8.74999 1.74996 8.74999H4.66663C4.98879 8.74999 5.24996 9.01116 5.24996 9.33332C5.24996 9.65549 4.98879 9.91666 4.66663 9.91666H3.15816L3.47376 10.2322L3.65491 10.3992C4.57867 11.2098 5.76662 11.6612 7.0011 11.6661C8.23836 11.6658 9.42511 11.1749 10.3 10.3C11.1752 9.42487 11.6666 8.23767 11.6666 6.99999C11.6666 6.67782 11.9278 6.41666 12.25 6.41666C12.5721 6.41666 12.8333 6.67782 12.8333 6.99999C12.8333 8.54709 12.2188 10.0309 11.1249 11.1249C10.0309 12.2189 8.54706 12.8333 6.99996 12.8333H6.99768C5.48052 12.8276 4.02054 12.2721 2.88529 11.2759L2.65572 11.064L2.33329 10.7415V12.25C2.33329 12.5722 2.07213 12.8333 1.74996 12.8333C1.42779 12.8333 1.16663 12.5722 1.16663 12.25ZM1.16663 6.99999C1.16663 5.45289 1.78108 3.96903 2.87504 2.87507C3.969 1.78111 5.45286 1.16666 6.99996 1.16666H7.00224L7.30473 1.1752C8.71256 1.24848 10.055 1.79424 11.1146 2.72411L11.3442 2.93603L11.6666 3.25845V1.74999C11.6666 1.42782 11.9278 1.16666 12.25 1.16666C12.5721 1.16666 12.8333 1.42782 12.8333 1.74999V4.66666C12.8333 4.98882 12.5721 5.24999 12.25 5.24999H9.33329C9.01113 5.24999 8.74996 4.98882 8.74996 4.66666C8.74996 4.34449 9.01113 4.08332 9.33329 4.08332H10.8418L10.5262 3.76773L10.345 3.60082C9.4211 2.79008 8.23293 2.33809 6.99825 2.33332C5.76119 2.33378 4.57468 2.82517 3.69991 3.69994C2.82474 4.57511 2.33329 5.76231 2.33329 6.99999C2.33329 7.32216 2.07213 7.58332 1.74996 7.58332C1.42779 7.58332 1.16663 7.32216 1.16663 6.99999Z"
8777
+ fill="#939394"
8778
+ />
8779
+ </svg>
8780
+ </button>
8781
+ </div>
8782
+ </div>
8783
+ </div>
8784
+ `, isInline: true, styles: [":host{display:block}\n"] });
8785
+ }
8786
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: PaginationComponent, decorators: [{
8787
+ type: Component,
8788
+ args: [{ selector: 'bsg-pagination', standalone: true, template: `
8789
+ <div [class]="containerClasses()">
8790
+ <!-- Left section: Current page -->
8791
+ <div [class]="sectionLeftClasses()">
8792
+ <span [class]="labelClasses()">Página</span>
8793
+ <input
8794
+ type="number"
8795
+ [class]="inputClasses()"
8796
+ [value]="pageInputValue()"
8797
+ [min]="1"
8798
+ [max]="resolvedTotalPages()"
8799
+ (focus)="onPageInputFocus()"
8800
+ (input)="onPageInputChange($event)"
8801
+ (keydown.enter)="onPageInputBlur()"
8802
+ (blur)="onPageInputBlur()"
8803
+ [disabled]="resolvedTotalPages() === 0"
8804
+ />
8805
+ <span [class]="labelClasses()">de {{ resolvedTotalPages() }}</span>
8806
+ </div>
8807
+
8808
+ <!-- Middle section: Page size selector -->
8809
+ <div [class]="sectionMiddleClasses()">
8810
+ <div [class]="selectWrapperClasses()">
8811
+ <select
8812
+ [class]="selectClasses()"
8813
+ [value]="pageSizeSig()"
8814
+ (change)="onPageSizeSelectChange($event)"
8815
+ >
8816
+ @for (option of pageSizeOptions(); track option) {
8817
+ <option [value]="option">{{ option }}</option>
8818
+ }
8819
+ </select>
8820
+
8821
+ <svg
8822
+ [class]="selectIconClasses()"
8823
+ width="15"
8824
+ height="15"
8825
+ viewBox="0 0 15 15"
8826
+ fill="none"
8827
+ xmlns="http://www.w3.org/2000/svg"
8828
+ >
8829
+ <path
8830
+ d="M10.8081 5.18312C11.0522 4.93904 11.4478 4.93904 11.6919 5.18312C11.936 5.4272 11.936 5.82283 11.6919 6.06691L7.94191 9.81691C7.69783 10.061 7.3022 10.061 7.05812 9.81691L3.30812 6.06691C3.06404 5.82283 3.06404 5.4272 3.30812 5.18312C3.5522 4.93904 3.94783 4.93904 4.19191 5.18312L7.50001 8.49122L10.8081 5.18312Z"
8831
+ fill="#848485"
8832
+ />
8833
+ </svg>
8834
+ </div>
8835
+ <span [class]="labelClasses()">ítems por página</span>
8836
+ </div>
8837
+
8838
+ <!-- Right section: Range label and navigation -->
8839
+ <div [class]="sectionRightClasses()">
8840
+ <span [class]="rangeLabelClasses()">{{ computedRangeLabel() }}</span>
8841
+
8842
+ <div [class]="navControlsClasses()">
8843
+ <!-- First page -->
8844
+ <button
8845
+ type="button"
8846
+ [class]="navButtonClasses()"
8847
+ [disabled]="pageSig() === 1 || resolvedTotalPages() === 0"
8848
+ (click)="goToFirstPage()"
8849
+ aria-label="Primera página"
8850
+ >
8851
+ <svg
8852
+ width="15"
8853
+ height="15"
8854
+ viewBox="0 0 15 15"
8855
+ fill="none"
8856
+ xmlns="http://www.w3.org/2000/svg"
8857
+ >
8858
+ <path
8859
+ d="M6.43312 3.93312C6.6772 3.68904 7.07283 3.68904 7.31691 3.93312C7.56099 4.1772 7.56099 4.57283 7.31691 4.81691L4.6338 7.50001L7.31691 10.1831C7.56099 10.4272 7.56099 10.8228 7.31691 11.0669C7.07283 11.311 6.6772 11.311 6.43312 11.0669L3.30812 7.94191C3.06404 7.69783 3.06404 7.3022 3.30812 7.05812L6.43312 3.93312ZM10.8081 3.93312C11.0522 3.68904 11.4478 3.68904 11.6919 3.93312C11.936 4.1772 11.936 4.57283 11.6919 4.81691L9.0088 7.50001L11.6919 10.1831C11.936 10.4272 11.936 10.8228 11.6919 11.0669C11.4478 11.311 11.0522 11.311 10.8081 11.0669L7.68312 7.94191C7.43904 7.69783 7.43904 7.3022 7.68312 7.05812L10.8081 3.93312Z"
8860
+ fill="#939394"
8861
+ />
8862
+ </svg>
8863
+ </button>
8864
+
8865
+ <!-- Previous page -->
8866
+ <button
8867
+ type="button"
8868
+ [class]="navButtonClasses()"
8869
+ [disabled]="pageSig() === 1 || resolvedTotalPages() === 0"
8870
+ (click)="goToPreviousPage()"
8871
+ aria-label="Página anterior"
8872
+ >
8873
+ <svg
8874
+ width="14"
8875
+ height="14"
8876
+ viewBox="0 0 14 14"
8877
+ fill="none"
8878
+ xmlns="http://www.w3.org/2000/svg"
8879
+ >
8880
+ <path
8881
+ d="M8.33754 3.08754C8.56535 2.85974 8.93461 2.85974 9.16241 3.08754C9.39022 3.31535 9.39022 3.68461 9.16241 3.91241L6.07485 6.99998L9.16241 10.0875C9.39022 10.3153 9.39022 10.6846 9.16241 10.9124C8.93461 11.1402 8.56535 11.1402 8.33754 10.9124L4.83754 7.41241C4.60974 7.18461 4.60974 6.81535 4.83754 6.58754L8.33754 3.08754Z"
8882
+ fill="#939394"
8883
+ />
8884
+ </svg>
8885
+ </button>
8886
+
8887
+ <!-- Next page -->
8888
+ <button
8889
+ type="button"
8890
+ [class]="navButtonClasses()"
8891
+ [disabled]="
8892
+ pageSig() >= resolvedTotalPages() || resolvedTotalPages() === 0
8893
+ "
8894
+ (click)="goToNextPage()"
8895
+ aria-label="Página siguiente"
8896
+ >
8897
+ <svg
8898
+ width="16"
8899
+ height="16"
8900
+ viewBox="0 0 16 16"
8901
+ fill="none"
8902
+ xmlns="http://www.w3.org/2000/svg"
8903
+ >
8904
+ <path
8905
+ d="M5.52864 3.52864C5.78899 3.26829 6.21099 3.26829 6.47134 3.52864L10.4713 7.52864C10.7317 7.78899 10.7317 8.211 10.4713 8.47134L6.47134 12.4713C6.21099 12.7317 5.78899 12.7317 5.52864 12.4713C5.26829 12.211 5.26829 11.789 5.52864 11.5286L9.05728 7.99999L5.52864 4.47134C5.26829 4.21099 5.26829 3.78899 5.52864 3.52864Z"
8906
+ fill="#939394"
8907
+ />
8908
+ </svg>
8909
+ </button>
8910
+
8911
+ <!-- Last page -->
8912
+ <button
8913
+ type="button"
8914
+ [class]="navButtonClasses()"
8915
+ [disabled]="
8916
+ pageSig() >= resolvedTotalPages() || resolvedTotalPages() === 0
8917
+ "
8918
+ (click)="goToLastPage()"
8919
+ aria-label="Última página"
8920
+ >
8921
+ <svg
8922
+ width="16"
8923
+ height="16"
8924
+ viewBox="0 0 16 16"
8925
+ fill="none"
8926
+ xmlns="http://www.w3.org/2000/svg"
8927
+ >
8928
+ <path
8929
+ d="M3.52864 4.19532C3.78899 3.93497 4.21099 3.93497 4.47134 4.19532L7.80468 7.52866C8.06503 7.78901 8.06503 8.21102 7.80468 8.47136L4.47134 11.8047C4.21099 12.065 3.78899 12.065 3.52864 11.8047C3.26829 11.5443 3.26829 11.1223 3.52864 10.862L6.39062 8.00001L3.52864 5.13803C3.26829 4.87768 3.26829 4.45567 3.52864 4.19532ZM8.1953 4.19532C8.45565 3.93497 8.87766 3.93497 9.13801 4.19532L12.4713 7.52866C12.7317 7.78901 12.7317 8.21102 12.4713 8.47136L9.13801 11.8047C8.87766 12.065 8.45565 12.065 8.1953 11.8047C7.93495 11.5443 7.93495 11.1223 8.1953 10.862L11.0573 8.00001L8.1953 5.13803C7.93495 4.87768 7.93495 4.45567 8.1953 4.19532Z"
8930
+ fill="#939394"
8931
+ />
8932
+ </svg>
8933
+ </button>
8934
+
8935
+ <!-- Refresh -->
8936
+ <button
8937
+ type="button"
8938
+ [class]="refreshButtonClasses()"
8939
+ (click)="onRefresh()"
8940
+ aria-label="Refrescar"
8941
+ >
8942
+ <svg
8943
+ width="14"
8944
+ height="14"
8945
+ viewBox="0 0 14 14"
8946
+ fill="none"
8947
+ xmlns="http://www.w3.org/2000/svg"
8948
+ >
8949
+ <path
8950
+ d="M1.16663 12.25V9.33332C1.16663 9.01116 1.42779 8.74999 1.74996 8.74999H4.66663C4.98879 8.74999 5.24996 9.01116 5.24996 9.33332C5.24996 9.65549 4.98879 9.91666 4.66663 9.91666H3.15816L3.47376 10.2322L3.65491 10.3992C4.57867 11.2098 5.76662 11.6612 7.0011 11.6661C8.23836 11.6658 9.42511 11.1749 10.3 10.3C11.1752 9.42487 11.6666 8.23767 11.6666 6.99999C11.6666 6.67782 11.9278 6.41666 12.25 6.41666C12.5721 6.41666 12.8333 6.67782 12.8333 6.99999C12.8333 8.54709 12.2188 10.0309 11.1249 11.1249C10.0309 12.2189 8.54706 12.8333 6.99996 12.8333H6.99768C5.48052 12.8276 4.02054 12.2721 2.88529 11.2759L2.65572 11.064L2.33329 10.7415V12.25C2.33329 12.5722 2.07213 12.8333 1.74996 12.8333C1.42779 12.8333 1.16663 12.5722 1.16663 12.25ZM1.16663 6.99999C1.16663 5.45289 1.78108 3.96903 2.87504 2.87507C3.969 1.78111 5.45286 1.16666 6.99996 1.16666H7.00224L7.30473 1.1752C8.71256 1.24848 10.055 1.79424 11.1146 2.72411L11.3442 2.93603L11.6666 3.25845V1.74999C11.6666 1.42782 11.9278 1.16666 12.25 1.16666C12.5721 1.16666 12.8333 1.42782 12.8333 1.74999V4.66666C12.8333 4.98882 12.5721 5.24999 12.25 5.24999H9.33329C9.01113 5.24999 8.74996 4.98882 8.74996 4.66666C8.74996 4.34449 9.01113 4.08332 9.33329 4.08332H10.8418L10.5262 3.76773L10.345 3.60082C9.4211 2.79008 8.23293 2.33809 6.99825 2.33332C5.76119 2.33378 4.57468 2.82517 3.69991 3.69994C2.82474 4.57511 2.33329 5.76231 2.33329 6.99999C2.33329 7.32216 2.07213 7.58332 1.74996 7.58332C1.42779 7.58332 1.16663 7.32216 1.16663 6.99999Z"
8951
+ fill="#939394"
8952
+ />
8953
+ </svg>
8954
+ </button>
8955
+ </div>
8956
+ </div>
8957
+ </div>
8958
+ `, styles: [":host{display:block}\n"] }]
8959
+ }], ctorParameters: () => [], propDecorators: { currentPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentPage", required: false }] }], totalPages: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalPages", required: false }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], totalItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalItems", required: false }] }], rangeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "rangeLabel", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], pageChange: [{ type: i0.Output, args: ["pageChange"] }], pageSizeChange: [{ type: i0.Output, args: ["pageSizeChange"] }], paginationChange: [{ type: i0.Output, args: ["paginationChange"] }], refresh: [{ type: i0.Output, args: ["refresh"] }] } });
8960
+
8961
+ /**
8962
+ * Separator variants
8963
+ *
8964
+ * Controls the visual separator line between content sections
8965
+ */
8966
+ const separatorVariants = cva(clsx(
8967
+ // Base
8968
+ 'shrink-0',
8969
+ // Background color (semantic token)
8970
+ 'bg-border',
8971
+ // Reset
8972
+ 'border-none'), {
8973
+ variants: {
8974
+ orientation: {
8975
+ horizontal: 'w-full h-px',
8976
+ vertical: 'h-full w-px self-stretch',
8977
+ },
8978
+ },
8979
+ defaultVariants: {
8980
+ orientation: 'horizontal',
8981
+ },
8982
+ });
8983
+
8984
+ /**
8985
+ * Separator Component
8986
+ *
8987
+ * A visual divider between content sections.
8988
+ *
8989
+ * Usage:
8990
+ * ```html
8991
+ * <bsg-separator />
8992
+ * <bsg-separator orientation="vertical" />
8993
+ * ```
8994
+ */
8995
+ class SeparatorComponent {
8996
+ /** Separator orientation */
8997
+ orientation = input('horizontal', ...(ngDevMode ? [{ debugName: "orientation" }] : []));
8998
+ /** Additional CSS classes */
8999
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
9000
+ /** Computed separator classes */
9001
+ separatorClasses = computed(() => clsx(separatorVariants({ orientation: this.orientation() }), this.className()), ...(ngDevMode ? [{ debugName: "separatorClasses" }] : []));
9002
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SeparatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9003
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.15", type: SeparatorComponent, isStandalone: true, selector: "bsg-separator", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
9004
+ <div
9005
+ [class]="separatorClasses()"
9006
+ role="separator"
9007
+ [attr.aria-orientation]="orientation()"
9008
+ ></div>
9009
+ `, isInline: true, styles: [":host{display:block}:host([orientation=\"vertical\"]){display:inline-block;height:100%}\n"] });
9010
+ }
9011
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: SeparatorComponent, decorators: [{
9012
+ type: Component,
9013
+ args: [{ selector: 'bsg-separator', standalone: true, template: `
9014
+ <div
9015
+ [class]="separatorClasses()"
9016
+ role="separator"
9017
+ [attr.aria-orientation]="orientation()"
9018
+ ></div>
9019
+ `, styles: [":host{display:block}:host([orientation=\"vertical\"]){display:inline-block;height:100%}\n"] }]
9020
+ }], propDecorators: { orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }] } });
9021
+
9022
+ /**
9023
+ * @deprecated Use the new composable table components (TableComponent, TableHeader, TableBody, etc.) instead.
9024
+ * This component is kept for backwards compatibility.
9025
+ */
9026
+ class TableContainerComponent {
9027
+ /** Container title */
9028
+ title = 'Título del Contenedor';
9029
+ /** Display variant */
9030
+ variant = 'table-basic';
9031
+ /** Header action button (e.g., "Nuevo mensaje") */
9032
+ headerAction;
9033
+ // Collapsible mode inputs
9034
+ isCollapsible = false;
9035
+ isExpanded = true;
9036
+ disableExpansion = false;
9037
+ // Table variant inputs
9038
+ tableColumns = [];
9039
+ tableRows = [];
9040
+ tablePagination;
9041
+ // Table-actions specific
9042
+ showActionsColumn = true;
9043
+ actionsColumnLabel = 'Acciones';
9044
+ actionsColumnWidth = '200px';
9045
+ // List variant inputs
9046
+ listItems = [];
9047
+ // Tabs variant inputs
9048
+ tabs = [];
9049
+ activeTabIndex = 0;
9050
+ tabsPagination = [];
9051
+ // Events
9052
+ headerActionClick = new EventEmitter();
9053
+ collapseToggle = new EventEmitter();
9054
+ tabChange = new EventEmitter();
9055
+ tablePageChange = new EventEmitter();
9056
+ tablePageSizeChange = new EventEmitter();
9057
+ tableRefresh = new EventEmitter();
9058
+ tabPageChange = new EventEmitter();
9059
+ tabPageSizeChange = new EventEmitter();
9060
+ tabRefresh = new EventEmitter();
9061
+ rowAction = new EventEmitter();
9062
+ get containerClasses() {
9063
+ const classes = [`table-${this.variant}`];
9064
+ if (this.isCollapsible && !this.isExpanded) {
9065
+ classes.push('table-collapsed');
9066
+ }
9067
+ return classes;
9068
+ }
9069
+ toggleCollapse() {
9070
+ this.isExpanded = !this.isExpanded;
9071
+ this.collapseToggle.emit(this.isExpanded);
9072
+ }
9073
+ onHeaderAction() {
9074
+ this.headerActionClick.emit();
9075
+ }
9076
+ onTabChange(index) {
9077
+ this.activeTabIndex = index;
9078
+ this.tabChange.emit(index);
9079
+ }
9080
+ onTablePageChange(page) {
9081
+ this.tablePageChange.emit(page);
9082
+ }
9083
+ onTablePageSizeChange(pageSize) {
9084
+ this.tablePageSizeChange.emit(pageSize);
9085
+ }
9086
+ onTableRefresh() {
9087
+ this.tableRefresh.emit();
9088
+ }
9089
+ onTabPageChange(tabIndex, page) {
9090
+ this.tabPageChange.emit({ tabIndex, page });
9091
+ }
9092
+ onTabPageSizeChange(tabIndex, pageSize) {
9093
+ this.tabPageSizeChange.emit({ tabIndex, pageSize });
9094
+ }
9095
+ onTabRefresh(tabIndex) {
9096
+ this.tabRefresh.emit(tabIndex);
9097
+ }
9098
+ onRowAction(rowIndex, action) {
9099
+ this.rowAction.emit({ rowIndex, action });
9100
+ if (action.onClick) {
9101
+ action.onClick();
9102
+ }
9103
+ }
9104
+ getActionVariant(actionVariant) {
9105
+ switch (actionVariant) {
9106
+ case 'approve':
9107
+ return 'default'; // Green variant
9108
+ case 'reject':
9109
+ return 'destructive'; // Red variant
9110
+ case 'view':
9111
+ return 'ghost'; // Light blue variant
9112
+ default:
9113
+ return 'default';
9114
+ }
9115
+ }
9116
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9117
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: TableContainerComponent, isStandalone: true, selector: "bsg-table-container", inputs: { title: "title", variant: "variant", headerAction: "headerAction", isCollapsible: "isCollapsible", isExpanded: "isExpanded", disableExpansion: "disableExpansion", tableColumns: "tableColumns", tableRows: "tableRows", tablePagination: "tablePagination", showActionsColumn: "showActionsColumn", actionsColumnLabel: "actionsColumnLabel", actionsColumnWidth: "actionsColumnWidth", listItems: "listItems", tabs: "tabs", activeTabIndex: "activeTabIndex", tabsPagination: "tabsPagination" }, outputs: { headerActionClick: "headerActionClick", collapseToggle: "collapseToggle", tabChange: "tabChange", tablePageChange: "tablePageChange", tablePageSizeChange: "tablePageSizeChange", tableRefresh: "tableRefresh", tabPageChange: "tabPageChange", tabPageSizeChange: "tabPageSizeChange", tabRefresh: "tabRefresh", rowAction: "rowAction" }, ngImport: i0, template: `
9118
+ <div class="table" [class]="containerClasses">
9119
+ <!-- Header -->
9120
+ <div
9121
+ class="table-header"
9122
+ [class.table-header-collapsible]="isCollapsible"
9123
+ >
9124
+ <!-- Icon -->
9125
+ @if (!isCollapsible) {
9126
+ <div class="table-icon">
9127
+ <svg
9128
+ width="28"
9129
+ height="28"
9130
+ viewBox="0 0 28 28"
9131
+ fill="none"
9132
+ xmlns="http://www.w3.org/2000/svg"
9133
+ >
9134
+ <circle cx="14" cy="14" r="14" fill="#2563EB" />
9135
+ </svg>
9136
+ <svg
9137
+ class="table-check-icon"
9138
+ width="15"
9139
+ height="15"
9140
+ viewBox="0 0 15 15"
9141
+ fill="none"
9142
+ xmlns="http://www.w3.org/2000/svg"
9143
+ >
9144
+ <g clip-path="url(#clip0_check)">
9145
+ <path
9146
+ d="M6.43155 0.706459C7.98492 0.461733 9.5751 0.757369 10.9372 1.54325C11.2361 1.71571 11.339 2.09758 11.1667 2.39652C10.9942 2.6955 10.6118 2.79791 10.3128 2.6254C9.19841 1.98244 7.89713 1.74102 6.62625 1.9412C5.35534 2.14143 4.19126 2.77142 3.32852 3.72587C2.4658 4.68036 1.95624 5.90193 1.88504 7.18656C1.81386 8.47123 2.18527 9.74182 2.93729 10.7858C3.6893 11.8297 4.77673 12.5845 6.01773 12.9239C7.25873 13.2632 8.57877 13.167 9.75736 12.651C10.936 12.1351 11.9023 11.2303 12.4948 10.0882C13.0872 8.94613 13.2698 7.63546 13.013 6.37479C12.9441 6.03664 13.1625 5.7065 13.5006 5.63749C13.8389 5.56857 14.169 5.78696 14.2379 6.12516C14.5519 7.66605 14.328 9.26786 13.6038 10.6637C12.8796 12.0596 11.699 13.1654 10.2585 13.7961C8.818 14.4266 7.20487 14.5441 5.68814 14.1293C4.17132 13.7145 2.84201 12.7923 1.92288 11.5164C1.00377 10.2404 0.549897 8.68771 0.636872 7.11759C0.72387 5.54744 1.34693 4.05449 2.4014 2.88786C3.45585 1.7213 4.87821 0.951184 6.43155 0.706459ZM13.3084 2.05778C13.5525 1.81398 13.9482 1.81382 14.1922 2.05778C14.4362 2.30185 14.4362 2.6981 14.1922 2.94218L7.94217 9.19218C7.69818 9.43613 7.30247 9.43597 7.05838 9.19218L5.18338 7.31718C4.9393 7.0731 4.9393 6.67686 5.18338 6.43278C5.42747 6.18898 5.82318 6.18882 6.06717 6.43278L7.50028 7.86588L13.3084 2.05778Z"
9147
+ fill="white"
9148
+ />
9149
+ </g>
9150
+ <defs>
9151
+ <clipPath id="clip0_check">
9152
+ <rect width="15" height="15" fill="white" />
9153
+ </clipPath>
9154
+ </defs>
9155
+ </svg>
9156
+ </div>
9157
+ }
9158
+
9159
+ <!-- Title -->
9160
+ <h2 class="table-title">{{ title }}</h2>
9161
+
9162
+ <!-- Header Actions (e.g., "Nuevo mensaje" button) -->
9163
+ @if (headerAction && !isCollapsible) {
9164
+ <div class="table-header-actions">
9165
+ <bsg-button
9166
+ [label]="headerAction.label"
9167
+ [variant]="headerAction.variant || 'default'"
9168
+ [size]="headerAction.size || 'md'"
9169
+ (onClick)="onHeaderAction()"
9170
+ ></bsg-button>
9171
+ </div>
9172
+ }
9173
+
9174
+ <!-- Chevron Icon for Collapsible Mode (right side) -->
9175
+ @if (isCollapsible) {
9176
+ <button
9177
+ type="button"
9178
+ class="table-collapse-chevron"
9179
+ [class.table-chevron-expanded]="isExpanded"
9180
+ (click)="toggleCollapse()"
9181
+ [attr.aria-expanded]="isExpanded"
9182
+ [attr.aria-label]="isExpanded ? 'Contraer' : 'Expandir'"
9183
+ >
9184
+ <svg
9185
+ width="24"
9186
+ height="24"
9187
+ viewBox="0 0 24 24"
9188
+ fill="none"
9189
+ xmlns="http://www.w3.org/2000/svg"
9190
+ >
9191
+ <path
9192
+ d="M11.3691 8.22462C11.7618 7.90427 12.3408 7.92686 12.707 8.29298L18.707 14.293C19.0975 14.6835 19.0975 15.3165 18.707 15.707C18.3164 16.0976 17.6834 16.0976 17.2929 15.707L11.9999 10.4141L6.70696 15.707C6.31643 16.0976 5.68342 16.0976 5.29289 15.707C4.90237 15.3165 4.90237 14.6835 5.29289 14.293L11.2929 8.29298L11.3691 8.22462Z"
9193
+ fill="currentColor"
9194
+ />
9195
+ </svg>
9196
+ </button>
9197
+ }
9198
+ </div>
9199
+
9200
+ <!-- Body -->
9201
+ <div class="table-body">
9202
+ <!-- Table Variants (table-basic, table-actions) -->
9203
+ @if (variant === 'table-basic' || variant === 'table-actions') {
9204
+ <div class="table-content">
9205
+ <!-- Table Header -->
9206
+ <div class="table-content-header">
9207
+ @for (column of tableColumns; track column.key) {
9208
+ <div
9209
+ class="table-header-cell"
9210
+ [style.width]="column.width || 'auto'"
9211
+ >
9212
+ {{ column.label }}
9213
+ </div>
9214
+ }
9215
+ @if (variant === 'table-actions' && showActionsColumn) {
9216
+ <div
9217
+ class="table-header-cell table-actions-header"
9218
+ [style.width]="actionsColumnWidth || 'auto'"
9219
+ >
9220
+ {{ actionsColumnLabel || 'Acciones' }}
9221
+ </div>
9222
+ }
9223
+ </div>
9224
+
9225
+ <bsg-separator></bsg-separator>
9226
+
9227
+ <!-- Table Rows -->
9228
+ <div class="table-content-body">
9229
+ @for (row of tableRows; track $index; let i = $index) {
9230
+ <div class="table-row">
9231
+ @for (column of tableColumns; track column.key) {
9232
+ <div
9233
+ class="table-cell"
9234
+ [style.width]="column.width || 'auto'"
9235
+ >
9236
+ <!-- Render badge if specified -->
9237
+ @if (row[column.key + '_badge']) {
9238
+ <bsg-badge
9239
+ [variant]="row[column.key + '_badge_variant'] || 'default'"
9240
+ [value]="row[column.key]"
9241
+ [size]="row[column.key + '_badge_size'] || 'default'"
9242
+ ></bsg-badge>
9243
+ } @else if (row[column.key + '_label']) {
9244
+ <!-- Render label if specified -->
9245
+ <bsg-label [text]="row[column.key]"></bsg-label>
9246
+ } @else {
9247
+ <!-- Render plain text otherwise -->
9248
+ <span>{{ row[column.key] }}</span>
9249
+ }
9250
+ </div>
9251
+ }
9252
+
9253
+ <!-- Actions Column (for table-actions variant) -->
9254
+ @if (variant === 'table-actions' && row['actions']) {
9255
+ <div
9256
+ class="table-cell table-actions-cell"
9257
+ [style.width]="actionsColumnWidth || 'auto'"
9258
+ >
9259
+ <div class="table-actions">
9260
+ @for (action of row['actions']; track $index) {
9261
+ <bsg-button
9262
+ [label]="action.label"
9263
+ [variant]="getActionVariant(action.variant)"
9264
+ [size]="'md'"
9265
+ [shape]="'rectangular'"
9266
+ (onClick)="onRowAction(i, action)"
9267
+ class="table-action-btn"
9268
+ ></bsg-button>
9269
+ }
9270
+ </div>
9271
+ </div>
9272
+ }
9273
+ </div>
9274
+ }
9275
+ </div>
9276
+
9277
+ <!-- Pagination -->
9278
+ @if (tablePagination) {
9279
+ <div class="table-pagination">
9280
+ <bsg-separator></bsg-separator>
9281
+ <bsg-pagination
9282
+ [currentPage]="tablePagination.currentPage"
9283
+ [totalPages]="tablePagination.totalPages"
9284
+ [pageSize]="tablePagination.pageSize"
9285
+ [pageSizeOptions]="tablePagination.pageSizeOptions"
9286
+ [totalItems]="tablePagination.totalItems"
9287
+ [rangeLabel]="tablePagination.rangeLabel"
9288
+ (pageChange)="onTablePageChange($event)"
9289
+ (pageSizeChange)="onTablePageSizeChange($event)"
9290
+ (refresh)="onTableRefresh()"
9291
+ ></bsg-pagination>
9292
+ </div>
9293
+ }
9294
+ </div>
9295
+ }
9296
+
9297
+ <!-- List Variant (list-content) -->
9298
+ @if (variant === 'list-content') {
9299
+ <div class="table-list">
9300
+ @for (item of listItems; track $index; let i = $index) {
9301
+ <div class="table-list-item">
9302
+ <div class="table-list-number">
9303
+ <svg
9304
+ width="27"
9305
+ height="26"
9306
+ viewBox="0 0 27 26"
9307
+ fill="none"
9308
+ xmlns="http://www.w3.org/2000/svg"
9309
+ >
9310
+ <ellipse cx="13.5" cy="13" rx="13.5" ry="13" fill="#2563EB" />
9311
+ </svg>
9312
+ <span class="table-list-number-text">{{ i + 1 }}</span>
9313
+ </div>
9314
+ <div class="table-list-text">{{ item.text }}</div>
9315
+ </div>
9316
+ }
9317
+ </div>
9318
+ }
9319
+
9320
+ <!-- Tabs Variant (table-tabs) -->
9321
+ @if (variant === 'table-tabs') {
9322
+ <div class="table-tabs-wrapper">
9323
+ <!-- Tab Navigation -->
9324
+ <bsg-tab-navigation
9325
+ [tabs]="tabs"
9326
+ [activeIndex]="activeTabIndex"
9327
+ [size]="'md'"
9328
+ [variant]="'text'"
9329
+ (tabChange)="onTabChange($event)"
9330
+ ></bsg-tab-navigation>
9331
+
9332
+ <!-- Tab Content -->
9333
+ <div class="table-tab-content">
9334
+ @for (tab of tabs; track $index; let i = $index) {
9335
+ @if (i === activeTabIndex && tab.tableData) {
9336
+ <div class="table-content">
9337
+ <!-- Table Header -->
9338
+ <div class="table-content-header">
9339
+ @for (column of tab.tableData.columns; track column.key) {
9340
+ <div
9341
+ class="table-header-cell"
9342
+ [style.width]="column.width || 'auto'"
9343
+ >
9344
+ {{ column.label }}
9345
+ </div>
9346
+ }
9347
+ </div>
9348
+
9349
+ <bsg-separator></bsg-separator>
9350
+
9351
+ <!-- Table Rows -->
9352
+ <div class="table-content-body">
9353
+ @for (row of tab.tableData.rows; track $index) {
9354
+ <div class="table-row">
9355
+ @for (column of tab.tableData.columns; track column.key) {
9356
+ <div
9357
+ class="table-cell"
9358
+ [style.width]="column.width || 'auto'"
9359
+ >
9360
+ <!-- Render badge if specified -->
9361
+ @if (row[column.key + '_badge']) {
9362
+ <bsg-badge
9363
+ [variant]="row[column.key + '_badge_variant'] || 'default'"
9364
+ [value]="row[column.key]"
9365
+ [size]="row[column.key + '_badge_size'] || 'default'"
9366
+ ></bsg-badge>
9367
+ } @else if (row[column.key + '_label']) {
9368
+ <!-- Render label if specified -->
9369
+ <bsg-label [text]="row[column.key]"></bsg-label>
9370
+ } @else {
9371
+ <!-- Render plain text otherwise -->
9372
+ <span>{{ row[column.key] }}</span>
9373
+ }
9374
+ </div>
9375
+ }
9376
+ </div>
9377
+ }
9378
+ </div>
9379
+
9380
+ <!-- Pagination for this tab -->
9381
+ @if (tabsPagination && tabsPagination[i]) {
9382
+ <div class="table-pagination">
9383
+ <bsg-separator></bsg-separator>
9384
+ <bsg-pagination
9385
+ [currentPage]="tabsPagination[i].currentPage"
9386
+ [totalPages]="tabsPagination[i].totalPages"
9387
+ [pageSize]="tabsPagination[i].pageSize"
9388
+ [pageSizeOptions]="tabsPagination[i].pageSizeOptions"
9389
+ [totalItems]="tabsPagination[i].totalItems"
9390
+ [rangeLabel]="tabsPagination[i].rangeLabel"
9391
+ (pageChange)="onTabPageChange(i, $event)"
9392
+ (pageSizeChange)="onTabPageSizeChange(i, $event)"
9393
+ (refresh)="onTabRefresh(i)"
9394
+ ></bsg-pagination>
9395
+ </div>
9396
+ }
9397
+ </div>
9398
+ }
9399
+ }
9400
+ </div>
9401
+ </div>
9402
+ }
9403
+ </div>
9404
+ </div>
9405
+ `, isInline: true, styles: [".table{width:100%;border-radius:12px;border:1px solid #cbd5e1;background:#fff;overflow:hidden;font-family:Inter,-apple-system,Roboto,Helvetica,sans-serif}.table-header{display:flex;align-items:center;gap:14px;padding:20px;background:#dbeafe;border-radius:12px 12px 0 0;position:relative}.table-header-collapsible{padding:16px 20px;gap:12px;justify-content:space-between}.table-header-collapsible .table-title{flex:1}.table-icon{position:relative;width:28px;height:28px;flex-shrink:0}.table-check-icon{position:absolute;left:7px;top:6px}.table-title{flex:1;margin:0;color:#2563eb;font-size:16px;font-weight:600;line-height:normal}.table-header-actions{margin-left:auto;margin-right:16px}.table-collapse-chevron{width:24px;height:24px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;cursor:pointer;padding:0;outline:none;transition:transform .3s ease;flex-shrink:0;color:#2563eb;margin-left:auto;margin-right:0}.table-collapse-chevron:hover{opacity:.8}.table-collapse-chevron:focus-visible{outline:2px solid #7c3aed;outline-offset:-2px;border-radius:4px}.table-chevron-expanded{transform:rotate(180deg)}.table-body,.table-content{padding:0}.table-content-header{display:flex;gap:16px;padding:12px 20px;background:#eff6ff;margin:0;align-items:flex-start}.table-header-cell{color:#2563eb;font-size:14px;font-weight:500;line-height:1.5;flex-shrink:1;word-break:break-word;overflow-wrap:break-word;white-space:normal}.table-actions-header{text-align:center}.table-content-body{padding:0 20px}.table-row{display:flex;gap:16px;padding:20px 0;border-bottom:1px solid #cbd5e1;align-items:flex-start}.table-row:last-child{border-bottom:none}.table-cell{color:#334155;font-size:14px;font-weight:500;line-height:1.5;display:flex;align-items:flex-start;flex-shrink:1;word-break:break-word;overflow-wrap:break-word;white-space:normal}.table-actions-cell{justify-content:center}.table-actions{display:flex;flex-direction:column;gap:16px;width:100%}.table-action-btn{width:83px;height:26px}.table-pagination{padding:20px}.table-pagination bsg-separator{margin-bottom:20px}.table-list{padding:20px;display:flex;flex-direction:column;gap:24px}.table-list-item{display:flex;align-items:flex-start;gap:17px}.table-list-number{position:relative;width:27px;height:26px;flex-shrink:0}.table-list-number-text{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff;font-size:14px;font-weight:500;line-height:normal}.table-list-text{flex:1;color:#334155;font-size:14px;font-weight:500;line-height:normal}.table-tabs-wrapper{padding:0}.table-tabs-wrapper bsg-tab-navigation{display:block;padding:20px}.table-tabs-wrapper bsg-tab-navigation .tab-navigation{display:flex;gap:8px;flex-wrap:wrap}.table-tab-content{margin-top:0;padding:0}.table-tab-content .table-content{padding:0}.table-tab-content .table-content-header{margin:0;padding:12px 20px;background:#eff6ff}.table-tab-content .table-content-body{margin-top:0;padding:0 20px}.table-tab-content .table-row{padding:20px 0}.table-tab-content .table-pagination{padding:20px}.table-collapsed,.table-collapsed .table-header{border-radius:12px}.table-collapsed .table-body{display:none}@media (max-width: 768px){.table-header{padding:16px}.table-title{font-size:14px}.table-content,.table-list,.table-tabs-wrapper{padding:16px}.table-content-header,.table-row{flex-direction:column;gap:8px}.table-header-cell,.table-cell{width:100%!important}.table-actions{flex-direction:row;justify-content:center}.table-pagination{padding:16px}}.table-action-btn bsg-button{width:100%}.table-actions .table-action-btn:first-child bsg-button{--button-bg: #16a34a;--button-color: #ffffff}.table-actions .table-action-btn:last-child bsg-button{--button-bg: #dc2626;--button-color: #ffffff}\n"], dependencies: [{ kind: "component", type: TabNavigationComponent, selector: "bsg-tab-navigation", inputs: ["size", "variant", "color", "disabled", "tabs", "activeIndex", "className"], outputs: ["tabChange"] }, { kind: "component", type: PaginationComponent, selector: "bsg-pagination", inputs: ["currentPage", "totalPages", "pageSize", "pageSizeOptions", "totalItems", "rangeLabel", "className"], outputs: ["pageChange", "pageSizeChange", "paginationChange", "refresh"] }, { kind: "component", type: SeparatorComponent, selector: "bsg-separator", inputs: ["orientation", "className"] }, { kind: "component", type: LabelComponent, selector: "bsg-label", inputs: ["text", "className"] }, { kind: "component", type: ButtonComponent, selector: "bsg-button", inputs: ["size", "variant", "shape", "label", "disabled", "spinner", "ariaLabel", "className"], outputs: ["Click"] }, { kind: "component", type: BadgeComponent, selector: "bsg-badge", inputs: ["variant", "size", "layout", "value", "className"] }] });
9406
+ }
9407
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: TableContainerComponent, decorators: [{
9408
+ type: Component,
9409
+ args: [{ selector: 'bsg-table-container', standalone: true, imports: [
9410
+ TabNavigationComponent,
9411
+ PaginationComponent,
9412
+ SeparatorComponent,
9413
+ LabelComponent,
9414
+ ButtonComponent,
9415
+ BadgeComponent,
9416
+ ], template: `
9417
+ <div class="table" [class]="containerClasses">
9418
+ <!-- Header -->
9419
+ <div
9420
+ class="table-header"
9421
+ [class.table-header-collapsible]="isCollapsible"
9422
+ >
9423
+ <!-- Icon -->
9424
+ @if (!isCollapsible) {
9425
+ <div class="table-icon">
9426
+ <svg
9427
+ width="28"
9428
+ height="28"
9429
+ viewBox="0 0 28 28"
9430
+ fill="none"
9431
+ xmlns="http://www.w3.org/2000/svg"
9432
+ >
9433
+ <circle cx="14" cy="14" r="14" fill="#2563EB" />
9434
+ </svg>
9435
+ <svg
9436
+ class="table-check-icon"
9437
+ width="15"
9438
+ height="15"
9439
+ viewBox="0 0 15 15"
9440
+ fill="none"
9441
+ xmlns="http://www.w3.org/2000/svg"
9442
+ >
9443
+ <g clip-path="url(#clip0_check)">
9444
+ <path
9445
+ d="M6.43155 0.706459C7.98492 0.461733 9.5751 0.757369 10.9372 1.54325C11.2361 1.71571 11.339 2.09758 11.1667 2.39652C10.9942 2.6955 10.6118 2.79791 10.3128 2.6254C9.19841 1.98244 7.89713 1.74102 6.62625 1.9412C5.35534 2.14143 4.19126 2.77142 3.32852 3.72587C2.4658 4.68036 1.95624 5.90193 1.88504 7.18656C1.81386 8.47123 2.18527 9.74182 2.93729 10.7858C3.6893 11.8297 4.77673 12.5845 6.01773 12.9239C7.25873 13.2632 8.57877 13.167 9.75736 12.651C10.936 12.1351 11.9023 11.2303 12.4948 10.0882C13.0872 8.94613 13.2698 7.63546 13.013 6.37479C12.9441 6.03664 13.1625 5.7065 13.5006 5.63749C13.8389 5.56857 14.169 5.78696 14.2379 6.12516C14.5519 7.66605 14.328 9.26786 13.6038 10.6637C12.8796 12.0596 11.699 13.1654 10.2585 13.7961C8.818 14.4266 7.20487 14.5441 5.68814 14.1293C4.17132 13.7145 2.84201 12.7923 1.92288 11.5164C1.00377 10.2404 0.549897 8.68771 0.636872 7.11759C0.72387 5.54744 1.34693 4.05449 2.4014 2.88786C3.45585 1.7213 4.87821 0.951184 6.43155 0.706459ZM13.3084 2.05778C13.5525 1.81398 13.9482 1.81382 14.1922 2.05778C14.4362 2.30185 14.4362 2.6981 14.1922 2.94218L7.94217 9.19218C7.69818 9.43613 7.30247 9.43597 7.05838 9.19218L5.18338 7.31718C4.9393 7.0731 4.9393 6.67686 5.18338 6.43278C5.42747 6.18898 5.82318 6.18882 6.06717 6.43278L7.50028 7.86588L13.3084 2.05778Z"
9446
+ fill="white"
9447
+ />
9448
+ </g>
9449
+ <defs>
9450
+ <clipPath id="clip0_check">
9451
+ <rect width="15" height="15" fill="white" />
9452
+ </clipPath>
9453
+ </defs>
9454
+ </svg>
9455
+ </div>
9456
+ }
9457
+
9458
+ <!-- Title -->
9459
+ <h2 class="table-title">{{ title }}</h2>
9460
+
9461
+ <!-- Header Actions (e.g., "Nuevo mensaje" button) -->
9462
+ @if (headerAction && !isCollapsible) {
9463
+ <div class="table-header-actions">
9464
+ <bsg-button
9465
+ [label]="headerAction.label"
9466
+ [variant]="headerAction.variant || 'default'"
9467
+ [size]="headerAction.size || 'md'"
9468
+ (onClick)="onHeaderAction()"
9469
+ ></bsg-button>
9470
+ </div>
9471
+ }
9472
+
9473
+ <!-- Chevron Icon for Collapsible Mode (right side) -->
9474
+ @if (isCollapsible) {
9475
+ <button
9476
+ type="button"
9477
+ class="table-collapse-chevron"
9478
+ [class.table-chevron-expanded]="isExpanded"
9479
+ (click)="toggleCollapse()"
9480
+ [attr.aria-expanded]="isExpanded"
9481
+ [attr.aria-label]="isExpanded ? 'Contraer' : 'Expandir'"
9482
+ >
9483
+ <svg
9484
+ width="24"
9485
+ height="24"
9486
+ viewBox="0 0 24 24"
9487
+ fill="none"
9488
+ xmlns="http://www.w3.org/2000/svg"
9489
+ >
9490
+ <path
9491
+ d="M11.3691 8.22462C11.7618 7.90427 12.3408 7.92686 12.707 8.29298L18.707 14.293C19.0975 14.6835 19.0975 15.3165 18.707 15.707C18.3164 16.0976 17.6834 16.0976 17.2929 15.707L11.9999 10.4141L6.70696 15.707C6.31643 16.0976 5.68342 16.0976 5.29289 15.707C4.90237 15.3165 4.90237 14.6835 5.29289 14.293L11.2929 8.29298L11.3691 8.22462Z"
9492
+ fill="currentColor"
9493
+ />
9494
+ </svg>
9495
+ </button>
9496
+ }
9497
+ </div>
9498
+
9499
+ <!-- Body -->
9500
+ <div class="table-body">
9501
+ <!-- Table Variants (table-basic, table-actions) -->
9502
+ @if (variant === 'table-basic' || variant === 'table-actions') {
9503
+ <div class="table-content">
9504
+ <!-- Table Header -->
9505
+ <div class="table-content-header">
9506
+ @for (column of tableColumns; track column.key) {
9507
+ <div
9508
+ class="table-header-cell"
9509
+ [style.width]="column.width || 'auto'"
9510
+ >
9511
+ {{ column.label }}
9512
+ </div>
9513
+ }
9514
+ @if (variant === 'table-actions' && showActionsColumn) {
9515
+ <div
9516
+ class="table-header-cell table-actions-header"
9517
+ [style.width]="actionsColumnWidth || 'auto'"
9518
+ >
9519
+ {{ actionsColumnLabel || 'Acciones' }}
9520
+ </div>
9521
+ }
9522
+ </div>
9523
+
9524
+ <bsg-separator></bsg-separator>
9525
+
9526
+ <!-- Table Rows -->
9527
+ <div class="table-content-body">
9528
+ @for (row of tableRows; track $index; let i = $index) {
9529
+ <div class="table-row">
9530
+ @for (column of tableColumns; track column.key) {
9531
+ <div
9532
+ class="table-cell"
9533
+ [style.width]="column.width || 'auto'"
9534
+ >
9535
+ <!-- Render badge if specified -->
9536
+ @if (row[column.key + '_badge']) {
9537
+ <bsg-badge
9538
+ [variant]="row[column.key + '_badge_variant'] || 'default'"
9539
+ [value]="row[column.key]"
9540
+ [size]="row[column.key + '_badge_size'] || 'default'"
9541
+ ></bsg-badge>
9542
+ } @else if (row[column.key + '_label']) {
9543
+ <!-- Render label if specified -->
9544
+ <bsg-label [text]="row[column.key]"></bsg-label>
9545
+ } @else {
9546
+ <!-- Render plain text otherwise -->
9547
+ <span>{{ row[column.key] }}</span>
9548
+ }
9549
+ </div>
9550
+ }
9551
+
9552
+ <!-- Actions Column (for table-actions variant) -->
9553
+ @if (variant === 'table-actions' && row['actions']) {
9554
+ <div
9555
+ class="table-cell table-actions-cell"
9556
+ [style.width]="actionsColumnWidth || 'auto'"
9557
+ >
9558
+ <div class="table-actions">
9559
+ @for (action of row['actions']; track $index) {
9560
+ <bsg-button
9561
+ [label]="action.label"
9562
+ [variant]="getActionVariant(action.variant)"
9563
+ [size]="'md'"
9564
+ [shape]="'rectangular'"
9565
+ (onClick)="onRowAction(i, action)"
9566
+ class="table-action-btn"
9567
+ ></bsg-button>
9568
+ }
9569
+ </div>
9570
+ </div>
9571
+ }
9572
+ </div>
9573
+ }
9574
+ </div>
9575
+
9576
+ <!-- Pagination -->
9577
+ @if (tablePagination) {
9578
+ <div class="table-pagination">
9579
+ <bsg-separator></bsg-separator>
9580
+ <bsg-pagination
9581
+ [currentPage]="tablePagination.currentPage"
9582
+ [totalPages]="tablePagination.totalPages"
9583
+ [pageSize]="tablePagination.pageSize"
9584
+ [pageSizeOptions]="tablePagination.pageSizeOptions"
9585
+ [totalItems]="tablePagination.totalItems"
9586
+ [rangeLabel]="tablePagination.rangeLabel"
9587
+ (pageChange)="onTablePageChange($event)"
9588
+ (pageSizeChange)="onTablePageSizeChange($event)"
9589
+ (refresh)="onTableRefresh()"
9590
+ ></bsg-pagination>
9591
+ </div>
9592
+ }
9593
+ </div>
9594
+ }
9595
+
9596
+ <!-- List Variant (list-content) -->
9597
+ @if (variant === 'list-content') {
9598
+ <div class="table-list">
9599
+ @for (item of listItems; track $index; let i = $index) {
9600
+ <div class="table-list-item">
9601
+ <div class="table-list-number">
9602
+ <svg
9603
+ width="27"
9604
+ height="26"
9605
+ viewBox="0 0 27 26"
9606
+ fill="none"
9607
+ xmlns="http://www.w3.org/2000/svg"
9608
+ >
9609
+ <ellipse cx="13.5" cy="13" rx="13.5" ry="13" fill="#2563EB" />
9610
+ </svg>
9611
+ <span class="table-list-number-text">{{ i + 1 }}</span>
9612
+ </div>
9613
+ <div class="table-list-text">{{ item.text }}</div>
9614
+ </div>
9615
+ }
9616
+ </div>
9617
+ }
9618
+
9619
+ <!-- Tabs Variant (table-tabs) -->
9620
+ @if (variant === 'table-tabs') {
9621
+ <div class="table-tabs-wrapper">
9622
+ <!-- Tab Navigation -->
9623
+ <bsg-tab-navigation
9624
+ [tabs]="tabs"
9625
+ [activeIndex]="activeTabIndex"
9626
+ [size]="'md'"
9627
+ [variant]="'text'"
9628
+ (tabChange)="onTabChange($event)"
9629
+ ></bsg-tab-navigation>
9630
+
9631
+ <!-- Tab Content -->
9632
+ <div class="table-tab-content">
9633
+ @for (tab of tabs; track $index; let i = $index) {
9634
+ @if (i === activeTabIndex && tab.tableData) {
9635
+ <div class="table-content">
9636
+ <!-- Table Header -->
9637
+ <div class="table-content-header">
9638
+ @for (column of tab.tableData.columns; track column.key) {
9639
+ <div
9640
+ class="table-header-cell"
9641
+ [style.width]="column.width || 'auto'"
9642
+ >
9643
+ {{ column.label }}
9644
+ </div>
9645
+ }
9646
+ </div>
9647
+
9648
+ <bsg-separator></bsg-separator>
9649
+
9650
+ <!-- Table Rows -->
9651
+ <div class="table-content-body">
9652
+ @for (row of tab.tableData.rows; track $index) {
9653
+ <div class="table-row">
9654
+ @for (column of tab.tableData.columns; track column.key) {
9655
+ <div
9656
+ class="table-cell"
9657
+ [style.width]="column.width || 'auto'"
9658
+ >
9659
+ <!-- Render badge if specified -->
9660
+ @if (row[column.key + '_badge']) {
9661
+ <bsg-badge
9662
+ [variant]="row[column.key + '_badge_variant'] || 'default'"
9663
+ [value]="row[column.key]"
9664
+ [size]="row[column.key + '_badge_size'] || 'default'"
9665
+ ></bsg-badge>
9666
+ } @else if (row[column.key + '_label']) {
9667
+ <!-- Render label if specified -->
9668
+ <bsg-label [text]="row[column.key]"></bsg-label>
9669
+ } @else {
9670
+ <!-- Render plain text otherwise -->
9671
+ <span>{{ row[column.key] }}</span>
9672
+ }
9673
+ </div>
9674
+ }
9675
+ </div>
9676
+ }
9677
+ </div>
9678
+
9679
+ <!-- Pagination for this tab -->
9680
+ @if (tabsPagination && tabsPagination[i]) {
9681
+ <div class="table-pagination">
9682
+ <bsg-separator></bsg-separator>
9683
+ <bsg-pagination
9684
+ [currentPage]="tabsPagination[i].currentPage"
9685
+ [totalPages]="tabsPagination[i].totalPages"
9686
+ [pageSize]="tabsPagination[i].pageSize"
9687
+ [pageSizeOptions]="tabsPagination[i].pageSizeOptions"
9688
+ [totalItems]="tabsPagination[i].totalItems"
9689
+ [rangeLabel]="tabsPagination[i].rangeLabel"
9690
+ (pageChange)="onTabPageChange(i, $event)"
9691
+ (pageSizeChange)="onTabPageSizeChange(i, $event)"
9692
+ (refresh)="onTabRefresh(i)"
9693
+ ></bsg-pagination>
9694
+ </div>
9695
+ }
9696
+ </div>
9697
+ }
9698
+ }
9699
+ </div>
9700
+ </div>
9701
+ }
9702
+ </div>
9703
+ </div>
9704
+ `, styles: [".table{width:100%;border-radius:12px;border:1px solid #cbd5e1;background:#fff;overflow:hidden;font-family:Inter,-apple-system,Roboto,Helvetica,sans-serif}.table-header{display:flex;align-items:center;gap:14px;padding:20px;background:#dbeafe;border-radius:12px 12px 0 0;position:relative}.table-header-collapsible{padding:16px 20px;gap:12px;justify-content:space-between}.table-header-collapsible .table-title{flex:1}.table-icon{position:relative;width:28px;height:28px;flex-shrink:0}.table-check-icon{position:absolute;left:7px;top:6px}.table-title{flex:1;margin:0;color:#2563eb;font-size:16px;font-weight:600;line-height:normal}.table-header-actions{margin-left:auto;margin-right:16px}.table-collapse-chevron{width:24px;height:24px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;cursor:pointer;padding:0;outline:none;transition:transform .3s ease;flex-shrink:0;color:#2563eb;margin-left:auto;margin-right:0}.table-collapse-chevron:hover{opacity:.8}.table-collapse-chevron:focus-visible{outline:2px solid #7c3aed;outline-offset:-2px;border-radius:4px}.table-chevron-expanded{transform:rotate(180deg)}.table-body,.table-content{padding:0}.table-content-header{display:flex;gap:16px;padding:12px 20px;background:#eff6ff;margin:0;align-items:flex-start}.table-header-cell{color:#2563eb;font-size:14px;font-weight:500;line-height:1.5;flex-shrink:1;word-break:break-word;overflow-wrap:break-word;white-space:normal}.table-actions-header{text-align:center}.table-content-body{padding:0 20px}.table-row{display:flex;gap:16px;padding:20px 0;border-bottom:1px solid #cbd5e1;align-items:flex-start}.table-row:last-child{border-bottom:none}.table-cell{color:#334155;font-size:14px;font-weight:500;line-height:1.5;display:flex;align-items:flex-start;flex-shrink:1;word-break:break-word;overflow-wrap:break-word;white-space:normal}.table-actions-cell{justify-content:center}.table-actions{display:flex;flex-direction:column;gap:16px;width:100%}.table-action-btn{width:83px;height:26px}.table-pagination{padding:20px}.table-pagination bsg-separator{margin-bottom:20px}.table-list{padding:20px;display:flex;flex-direction:column;gap:24px}.table-list-item{display:flex;align-items:flex-start;gap:17px}.table-list-number{position:relative;width:27px;height:26px;flex-shrink:0}.table-list-number-text{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff;font-size:14px;font-weight:500;line-height:normal}.table-list-text{flex:1;color:#334155;font-size:14px;font-weight:500;line-height:normal}.table-tabs-wrapper{padding:0}.table-tabs-wrapper bsg-tab-navigation{display:block;padding:20px}.table-tabs-wrapper bsg-tab-navigation .tab-navigation{display:flex;gap:8px;flex-wrap:wrap}.table-tab-content{margin-top:0;padding:0}.table-tab-content .table-content{padding:0}.table-tab-content .table-content-header{margin:0;padding:12px 20px;background:#eff6ff}.table-tab-content .table-content-body{margin-top:0;padding:0 20px}.table-tab-content .table-row{padding:20px 0}.table-tab-content .table-pagination{padding:20px}.table-collapsed,.table-collapsed .table-header{border-radius:12px}.table-collapsed .table-body{display:none}@media (max-width: 768px){.table-header{padding:16px}.table-title{font-size:14px}.table-content,.table-list,.table-tabs-wrapper{padding:16px}.table-content-header,.table-row{flex-direction:column;gap:8px}.table-header-cell,.table-cell{width:100%!important}.table-actions{flex-direction:row;justify-content:center}.table-pagination{padding:16px}}.table-action-btn bsg-button{width:100%}.table-actions .table-action-btn:first-child bsg-button{--button-bg: #16a34a;--button-color: #ffffff}.table-actions .table-action-btn:last-child bsg-button{--button-bg: #dc2626;--button-color: #ffffff}\n"] }]
9705
+ }], propDecorators: { title: [{
9706
+ type: Input
9707
+ }], variant: [{
9708
+ type: Input
9709
+ }], headerAction: [{
9710
+ type: Input
9711
+ }], isCollapsible: [{
9712
+ type: Input
9713
+ }], isExpanded: [{
9714
+ type: Input
9715
+ }], disableExpansion: [{
9716
+ type: Input
9717
+ }], tableColumns: [{
9718
+ type: Input
9719
+ }], tableRows: [{
9720
+ type: Input
9721
+ }], tablePagination: [{
9722
+ type: Input
9723
+ }], showActionsColumn: [{
9724
+ type: Input
9725
+ }], actionsColumnLabel: [{
9726
+ type: Input
9727
+ }], actionsColumnWidth: [{
9728
+ type: Input
9729
+ }], listItems: [{
9730
+ type: Input
9731
+ }], tabs: [{
9732
+ type: Input
9733
+ }], activeTabIndex: [{
9734
+ type: Input
9735
+ }], tabsPagination: [{
9736
+ type: Input
9737
+ }], headerActionClick: [{
9738
+ type: Output
9739
+ }], collapseToggle: [{
9740
+ type: Output
9741
+ }], tabChange: [{
9742
+ type: Output
9743
+ }], tablePageChange: [{
9744
+ type: Output
9745
+ }], tablePageSizeChange: [{
9746
+ type: Output
9747
+ }], tableRefresh: [{
9748
+ type: Output
9749
+ }], tabPageChange: [{
9750
+ type: Output
9751
+ }], tabPageSizeChange: [{
9752
+ type: Output
9753
+ }], tabRefresh: [{
9754
+ type: Output
9755
+ }], rowAction: [{
9756
+ type: Output
9757
+ }] } });
9758
+
9759
+ // Table components (shadcn-style primitives)
9760
+
6654
9761
  const textareaVariants = cva(clsx(
6655
9762
  // Layout & sizing
6656
9763
  'w-full min-w-0', 'min-h-[80px]',
@@ -8325,5 +11432,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
8325
11432
  * Generated bundle index. Do not edit.
8326
11433
  */
8327
11434
 
8328
- export { AccordionComponent, AccordionContentComponent, AccordionItemComponent, AccordionTriggerComponent, AlertComponent, AvatarComponent, BadgeComponent, ButtonComponent, CardBodyComponent, CardComponent, CardFooterComponent, CardHeaderComponent, CarouselComponent, CarouselItemComponent, CheckboxComponent, CollapsibleComponent, CollapsibleContentComponent, CollapsibleTriggerDirective, ComboboxComponent, DialogComponent, InputComponent, LabelComponent, RadioComponent, RadioGroupComponent, SelectComponent, SidebarComponent, SidebarContentComponent, SidebarFooterComponent, SidebarGroupActionComponent, SidebarGroupComponent, SidebarGroupContentComponent, SidebarGroupLabelComponent, SidebarHeaderComponent, SidebarInsetComponent, SidebarMenuActionComponent, SidebarMenuBadgeComponent, SidebarMenuButtonComponent, SidebarMenuComponent, SidebarMenuItemComponent, SidebarMenuSubButtonComponent, SidebarMenuSubComponent, SidebarMenuSubItemComponent, SidebarProviderComponent, SidebarRailComponent, SidebarSeparatorComponent, SidebarService, SidebarTriggerComponent, SkeletonComponent, SwitchComponent, TextareaComponent, TimePickerComponent, ToastComponent, TooltipComponent, accordionContentVariants, accordionItemVariants, accordionTriggerVariants, accordionVariants, alertCloseVariants, alertContentVariants, alertIconVariants, alertVariants, avatarIconVariants, avatarImgVariants, avatarInitialsVariants, avatarVariants, badgeIconVariants, badgeVariants, buttonIconOnlyVariants, buttonIconVariants, buttonLabelVariants, buttonVariants, cardActionIconVariants, cardCurrencyContentVariants, cardCurrencyIconVariants, cardCurrencyLabelVariants, cardCurrencyTextVariants, cardHeaderRowVariants, cardHeaderVariants, cardHelperDescriptionVariants, cardHelperRowVariants, cardHelperVariants, cardInfoIconVariants, cardInfoLabelVariants, cardInfoTextVariants, cardMetricTitleVariants, cardMetricValueVariants, cardSlotBodyVariants, cardSlotFooterVariants, cardSlotHeaderVariants, cardValueVariants, cardVariants, carouselArrowVariants, carouselChevronVariants, carouselContainerVariants, carouselIndicatorVariants, carouselIndicatorsVariants, carouselRootVariants, carouselTrackVariants, carouselViewportVariants, checkboxVariants, comboboxDropdownVariants, comboboxEmptyStateVariants, comboboxErrorMessageVariants, comboboxIconVariants, comboboxOptionVariants, comboboxOptionsContainerVariants, comboboxSearchInputVariants, comboboxSearchWrapperVariants, comboboxTriggerVariants, comboboxValueVariants, comboboxWrapperVariants, dialogBodyVariants, dialogContentVariants, dialogFooterVariants, dialogHeaderVariants, dialogOverlayVariants, inputVariants, labelVariants, radioFocusRingVariants, radioGroupVariants, radioInnerVariants, radioLabelVariants, radioOptionVariants, radioOuterVariants, radioWrapperVariants, selectDropdownVariants, selectErrorVariants, selectIconVariants, selectOptionVariants, selectTriggerVariants, selectValueVariants, selectWrapperVariants, sidebarChevronVariants, sidebarContentVariants, sidebarFooterVariants, sidebarGroupActionVariants, sidebarGroupContentVariants, sidebarGroupLabelVariants, sidebarGroupVariants, sidebarHeaderVariants, sidebarInsetVariants, sidebarMenuActionVariants, sidebarMenuBadgeVariants, sidebarMenuButtonVariants, sidebarMenuItemVariants, sidebarMenuSkeletonVariants, sidebarMenuSubButtonVariants, sidebarMenuSubItemVariants, sidebarMenuSubVariants, sidebarMenuVariants, sidebarProviderVariants, sidebarRailVariants, sidebarSeparatorVariants, sidebarTriggerVariants, sidebarVariants, sidebarWrapperVariants, skeletonVariants, switchRootVariants, switchThumbVariants, textareaVariants, timepickerActionButtonVariants, timepickerActionsVariants, timepickerColumnHeaderVariants, timepickerColumnVariants, timepickerDropdownVariants, timepickerErrorMessageVariants, timepickerFieldVariants, timepickerIconButtonVariants, timepickerInputVariants, timepickerLabelVariants, timepickerListVariants, timepickerOptionVariants, timepickerSelectionAreaVariants, timepickerSeparatorVariants, timepickerWrapperVariants, toastAccentVariants, toastCloseVariants, toastContentVariants, toastIconVariants, toastVariants, tooltipArrowVariants, tooltipContentVariants, tooltipTriggerVariants };
11435
+ export { AccordionComponent, AccordionContentComponent, AccordionItemComponent, AccordionTriggerComponent, AlertComponent, AvatarComponent, BadgeComponent, ButtonComponent, CardBodyComponent, CardComponent, CardFooterComponent, CardHeaderComponent, CarouselComponent, CarouselItemComponent, CheckboxComponent, CollapsibleComponent, CollapsibleContentComponent, CollapsibleTriggerDirective, ComboboxComponent, DialogComponent, InputComponent, LabelComponent, RadioComponent, RadioGroupComponent, SelectComponent, SidebarComponent, SidebarContentComponent, SidebarFooterComponent, SidebarGroupActionComponent, SidebarGroupComponent, SidebarGroupContentComponent, SidebarGroupLabelComponent, SidebarHeaderComponent, SidebarInsetComponent, SidebarMenuActionComponent, SidebarMenuBadgeComponent, SidebarMenuButtonComponent, SidebarMenuComponent, SidebarMenuItemComponent, SidebarMenuSubButtonComponent, SidebarMenuSubComponent, SidebarMenuSubItemComponent, SidebarProviderComponent, SidebarRailComponent, SidebarSeparatorComponent, SidebarService, SidebarTriggerComponent, SkeletonComponent, SpinnerComponent, SwitchComponent, TabContentDirective, TabNavigationComponent, TableBodyComponent, TableCardComponent, TableCardFooterComponent, TableCardHeaderComponent, TableCellComponent, TableComponent, TableContainerComponent, TableFooterComponent, TableHeadComponent, TableHeaderComponent, TableRowComponent, TabsComponent, TabsContentComponent, TabsListComponent, TabsTriggerComponent, TextareaComponent, TimePickerComponent, ToastComponent, TooltipComponent, accordionContentVariants, accordionItemVariants, accordionTriggerVariants, accordionVariants, alertCloseVariants, alertContentVariants, alertIconVariants, alertVariants, avatarIconVariants, avatarImgVariants, avatarInitialsVariants, avatarVariants, badgeIconVariants, badgeVariants, buttonIconOnlyVariants, buttonIconVariants, buttonLabelVariants, buttonSpinnerVariants, buttonVariants, cardActionIconVariants, cardCurrencyContentVariants, cardCurrencyIconVariants, cardCurrencyLabelVariants, cardCurrencyTextVariants, cardHeaderRowVariants, cardHeaderVariants, cardHelperDescriptionVariants, cardHelperRowVariants, cardHelperVariants, cardInfoIconVariants, cardInfoLabelVariants, cardInfoTextVariants, cardMetricTitleVariants, cardMetricValueVariants, cardSlotBodyVariants, cardSlotFooterVariants, cardSlotHeaderVariants, cardValueVariants, cardVariants, carouselArrowVariants, carouselChevronVariants, carouselContainerVariants, carouselIndicatorVariants, carouselIndicatorsVariants, carouselRootVariants, carouselTrackVariants, carouselViewportVariants, checkboxVariants, comboboxDropdownVariants, comboboxEmptyStateVariants, comboboxErrorMessageVariants, comboboxIconVariants, comboboxOptionVariants, comboboxOptionsContainerVariants, comboboxSearchInputVariants, comboboxSearchWrapperVariants, comboboxTriggerVariants, comboboxValueVariants, comboboxWrapperVariants, dialogBodyVariants, dialogContentVariants, dialogFooterVariants, dialogHeaderVariants, dialogOverlayVariants, inputVariants, labelVariants, radioFocusRingVariants, radioGroupVariants, radioInnerVariants, radioLabelVariants, radioOptionVariants, radioOuterVariants, radioWrapperVariants, selectDropdownVariants, selectErrorVariants, selectIconVariants, selectOptionVariants, selectTriggerVariants, selectValueVariants, selectWrapperVariants, sidebarChevronVariants, sidebarContentVariants, sidebarFooterVariants, sidebarGroupActionVariants, sidebarGroupContentVariants, sidebarGroupLabelVariants, sidebarGroupVariants, sidebarHeaderVariants, sidebarInsetVariants, sidebarMenuActionVariants, sidebarMenuBadgeVariants, sidebarMenuButtonVariants, sidebarMenuItemVariants, sidebarMenuSkeletonVariants, sidebarMenuSubButtonVariants, sidebarMenuSubItemVariants, sidebarMenuSubVariants, sidebarMenuVariants, sidebarProviderVariants, sidebarRailVariants, sidebarSeparatorVariants, sidebarTriggerVariants, sidebarVariants, sidebarWrapperVariants, skeletonVariants, spinnerVariants, switchRootVariants, switchThumbVariants, tabIconCircleVariants, tabIconContentVariants, tabItemVariants, tabLabelVariants, tabNavigationVariants, tabTextContentVariants, tableBodyVariants, tableCardFooterVariants, tableCardHeaderVariants, tableCellVariants, tableCompactVariants, tableEmptyStateVariants, tableFooterVariants, tableHeadVariants, tableHeaderVariants, tableLoadingVariants, tablePaginationVariants, tableRowVariants, tableStripedVariants, tableVariants, tableWrapperVariants, textareaVariants, timepickerActionButtonVariants, timepickerActionsVariants, timepickerColumnHeaderVariants, timepickerColumnVariants, timepickerDropdownVariants, timepickerErrorMessageVariants, timepickerFieldVariants, timepickerIconButtonVariants, timepickerInputVariants, timepickerLabelVariants, timepickerListVariants, timepickerOptionVariants, timepickerSelectionAreaVariants, timepickerSeparatorVariants, timepickerWrapperVariants, toastAccentVariants, toastCloseVariants, toastContentVariants, toastIconVariants, toastVariants, tooltipArrowVariants, tooltipContentVariants, tooltipTriggerVariants };
8329
11436
  //# sourceMappingURL=bsginstitute-bsg-integra.mjs.map