@bsginstitute/bsg-integra 0.0.1 → 0.0.3

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,11 +1,12 @@
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, Injectable, PLATFORM_ID, model, 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, 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
- import * as i1$1 from '@angular/common';
6
+ import * as i1$2 from '@angular/common';
7
7
  import { DOCUMENT, CommonModule, isPlatformBrowser } from '@angular/common';
8
- import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
8
+ import * as i1$1 from '@angular/forms';
9
+ import { NG_VALUE_ACCESSOR, FormsModule, NG_VALIDATORS } from '@angular/forms';
9
10
 
10
11
  /**
11
12
  * Accordion container variants
@@ -1156,7 +1157,9 @@ const buttonVariants = cva(clsx(
1156
1157
  // Whitespace
1157
1158
  'whitespace-nowrap',
1158
1159
  // Border reset
1159
- 'border-0'), {
1160
+ 'border-0',
1161
+ // Focus outline reset (prevent focus ring on click)
1162
+ 'outline-none'), {
1160
1163
  variants: {
1161
1164
  size: {
1162
1165
  sm: 'h-[27px] py-2 px-4',
@@ -1164,18 +1167,18 @@ const buttonVariants = cva(clsx(
1164
1167
  lg: 'h-[43px] py-4 px-8',
1165
1168
  },
1166
1169
  variant: {
1167
- default: clsx('bg-violet-600 text-white', 'hover:opacity-90', 'active:shadow-[inset_0_2px_4px_0_rgba(0,0,0,0.12)]', 'focus:bg-violet-900 focus:ring-[3px] focus:ring-white focus:ring-offset-1 focus:ring-offset-violet-950'),
1168
- secondary: clsx('bg-blue-600 text-white', 'hover:opacity-90', 'active:shadow-[inset_0_2px_4px_0_rgba(0,0,0,0.12)]', 'focus:bg-blue-700 focus:ring-[3px] focus:ring-white focus:ring-offset-1 focus:ring-offset-violet-950'),
1169
- 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:border-violet-900 focus:text-violet-900 focus:ring-[3px] focus:ring-white focus:ring-offset-1 focus:ring-offset-violet-950'),
1170
- 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:bg-violet-200 focus:ring-[3px] focus:ring-white focus:ring-offset-1 focus:ring-offset-violet-950'),
1171
- link: clsx('bg-transparent text-blue-600', 'hover:opacity-90', 'active:underline', 'focus:text-blue-700 focus:ring-[3px] focus:ring-white focus:ring-offset-1 focus:ring-offset-violet-950'),
1172
- destructive: clsx('bg-red-600 text-white', 'hover:opacity-90', 'active:shadow-[inset_0_2px_4px_0_rgba(0,0,0,0.12)]', 'focus:bg-red-700 focus:ring-[3px] focus:ring-white focus:ring-offset-1 focus:ring-offset-violet-950'),
1170
+ 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
+ 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'),
1173
+ 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
+ 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
+ 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'),
1173
1176
  },
1174
1177
  shape: {
1175
- rectangular: '',
1178
+ rectangular: 'rounded-md',
1176
1179
  pill: 'rounded-full',
1177
- icon: 'rounded',
1178
- 'icon-text': '',
1180
+ icon: 'rounded-md',
1181
+ 'icon-text': 'rounded-md',
1179
1182
  'icon-only': 'rounded-full p-0',
1180
1183
  },
1181
1184
  disabled: {
@@ -1184,14 +1187,6 @@ const buttonVariants = cva(clsx(
1184
1187
  },
1185
1188
  },
1186
1189
  compoundVariants: [
1187
- // Rectangular shape + size = border radius
1188
- { shape: 'rectangular', size: 'sm', class: 'rounded-sm' },
1189
- { shape: 'rectangular', size: 'md', class: 'rounded' },
1190
- { shape: 'rectangular', size: 'lg', class: 'rounded-md' },
1191
- // Icon-text shape + size = border radius
1192
- { shape: 'icon-text', size: 'sm', class: 'rounded-sm' },
1193
- { shape: 'icon-text', size: 'md', class: 'rounded' },
1194
- { shape: 'icon-text', size: 'lg', class: 'rounded-md' },
1195
1190
  // Icon shape sizes
1196
1191
  { shape: 'icon', size: 'sm', class: 'w-[27px] h-[27px] p-2' },
1197
1192
  { shape: 'icon', size: 'md', class: 'w-[35px] h-[35px] p-2' },
@@ -1216,7 +1211,7 @@ const buttonVariants = cva(clsx(
1216
1211
  {
1217
1212
  shape: 'icon-only',
1218
1213
  variant: 'outline',
1219
- class: 'bg-transparent border border-slate-300 text-purple-600 hover:opacity-90 active:border-purple-600 focus:border-slate-500 focus:text-purple-800 focus:ring-1 focus:ring-purple-900',
1214
+ 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',
1220
1215
  },
1221
1216
  // Icon-only + default variant
1222
1217
  {
@@ -2840,84 +2835,535 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
2840
2835
  }], ctorParameters: () => [], propDecorators: { className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], forceMount: [{ type: i0.Input, args: [{ isSignal: true, alias: "forceMount", required: false }] }] } });
2841
2836
 
2842
2837
  /**
2843
- * Dialog overlay variants
2838
+ * Combobox wrapper variants
2844
2839
  *
2845
- * Controls the backdrop/overlay layer
2840
+ * Controls the overall combobox container layout
2846
2841
  */
2847
- const dialogOverlayVariants = cva(clsx(
2848
- // Position
2849
- 'fixed inset-0',
2850
- // Z-index
2851
- 'z-[9999]',
2842
+ const comboboxWrapperVariants = cva(clsx(
2852
2843
  // Layout
2853
- 'flex items-center justify-center',
2844
+ 'relative', 'inline-block'), {
2845
+ variants: {
2846
+ size: {
2847
+ sm: 'min-w-[133px]',
2848
+ md: 'min-w-[132px]',
2849
+ lg: 'min-w-[133px]',
2850
+ },
2851
+ },
2852
+ defaultVariants: {
2853
+ size: 'sm',
2854
+ },
2855
+ });
2856
+ /**
2857
+ * Combobox trigger variants
2858
+ *
2859
+ * Controls the clickable trigger button
2860
+ */
2861
+ const comboboxTriggerVariants = cva(clsx(
2862
+ // Layout
2863
+ 'flex items-center justify-center w-full',
2864
+ // Gap
2865
+ 'gap-3',
2866
+ // Border
2867
+ 'rounded-md border',
2854
2868
  // Background
2855
- 'bg-black/50',
2856
- // Padding - responsive
2857
- 'p-4 md:p-3',
2858
- // Box sizing
2859
- 'box-border',
2860
- // Animation
2861
- 'animate-in fade-in duration-200',
2862
- // User select
2863
- 'select-none'));
2869
+ 'bg-transparent',
2870
+ // Typography
2871
+ 'text-base font-normal leading-6 tracking-[0.05px]',
2872
+ // Cursor
2873
+ 'cursor-pointer',
2874
+ // Transition
2875
+ 'transition-all duration-200',
2876
+ // Focus
2877
+ 'focus:outline-none',
2878
+ // Hover (only when not disabled)
2879
+ 'hover:not-disabled:opacity-90'), {
2880
+ variants: {
2881
+ size: {
2882
+ sm: 'h-8 py-1 px-3',
2883
+ md: 'h-10 py-1 px-3',
2884
+ lg: 'h-12 py-1 px-3',
2885
+ },
2886
+ state: {
2887
+ default: 'border-border text-foreground',
2888
+ hover: 'border-border text-foreground opacity-90',
2889
+ focus: 'border-primary text-foreground',
2890
+ disabled: 'border-border text-foreground opacity-40 cursor-not-allowed pointer-events-none',
2891
+ error: 'border-destructive text-destructive',
2892
+ },
2893
+ open: {
2894
+ true: 'border-primary',
2895
+ false: '',
2896
+ },
2897
+ },
2898
+ defaultVariants: {
2899
+ size: 'sm',
2900
+ state: 'default',
2901
+ open: false,
2902
+ },
2903
+ });
2864
2904
  /**
2865
- * Dialog content variants
2905
+ * Combobox dropdown variants
2866
2906
  *
2867
- * Controls the main dialog container
2907
+ * Controls the dropdown menu container
2868
2908
  */
2869
- const dialogContentVariants = cva(clsx(
2909
+ const comboboxDropdownVariants = cva(clsx(
2870
2910
  // Position
2871
- 'relative',
2872
- // Layout
2873
- 'flex flex-col',
2911
+ 'absolute top-full mt-1 left-0',
2912
+ // Z-index
2913
+ 'z-50',
2914
+ // Border
2915
+ 'rounded-md border border-border',
2874
2916
  // Background
2875
- 'bg-white',
2876
- // Border radius
2877
- 'rounded-xl',
2917
+ 'bg-background',
2878
2918
  // Shadow
2879
- 'shadow-xl',
2880
- // Max height - responsive
2881
- 'max-h-[90vh] md:max-h-[95vh]',
2882
- // Width
2883
- 'w-full',
2884
- // Box sizing
2885
- 'box-border',
2886
- // Animation
2887
- 'animate-in zoom-in-95 duration-200',
2888
- // User select
2889
- 'select-text',
2890
- // Focus
2891
- 'focus:outline-none'), {
2919
+ 'shadow-lg',
2920
+ // Overflow
2921
+ 'overflow-hidden'), {
2892
2922
  variants: {
2893
2923
  size: {
2894
- sm: 'max-w-[460px] md:max-w-full',
2895
- md: 'max-w-[670px] md:max-w-full',
2896
- lg: 'max-w-[1153px] md:max-w-full',
2924
+ sm: 'min-w-[133px]',
2925
+ md: 'min-w-[132px]',
2926
+ lg: 'min-w-[133px]',
2897
2927
  },
2898
2928
  },
2899
2929
  defaultVariants: {
2900
- size: 'md',
2930
+ size: 'sm',
2901
2931
  },
2902
2932
  });
2903
2933
  /**
2904
- * Dialog header variants
2934
+ * Combobox search wrapper variants
2935
+ *
2936
+ * Controls the search input container
2937
+ */
2938
+ const comboboxSearchWrapperVariants = cva(clsx(
2939
+ // Padding
2940
+ 'p-2',
2941
+ // Border
2942
+ 'border-b border-muted'));
2943
+ /**
2944
+ * Combobox search input variants
2905
2945
  *
2906
- * Controls the header section with tone variants
2946
+ * Controls the search input field
2907
2947
  */
2908
- const dialogHeaderVariants = cva(clsx(
2948
+ const comboboxSearchInputVariants = cva(clsx(
2949
+ // Layout
2950
+ 'w-full',
2951
+ // Padding
2952
+ 'py-1.5 px-2.5',
2953
+ // Border
2954
+ 'rounded border border-border',
2955
+ // Background
2956
+ 'bg-background',
2957
+ // Typography
2958
+ 'text-sm font-normal leading-5 text-foreground',
2959
+ // Placeholder
2960
+ 'placeholder:text-muted-foreground',
2961
+ // Transition
2962
+ 'transition-all duration-200',
2963
+ // Focus
2964
+ 'focus:outline-none focus:border-primary',
2965
+ // Disabled
2966
+ 'disabled:opacity-40 disabled:cursor-not-allowed'));
2967
+ /**
2968
+ * Combobox options container variants
2969
+ *
2970
+ * Controls the scrollable options list
2971
+ */
2972
+ const comboboxOptionsContainerVariants = cva(clsx(
2973
+ // Max height and scroll
2974
+ 'max-h-[200px] overflow-y-auto'));
2975
+ /**
2976
+ * Combobox option variants
2977
+ *
2978
+ * Controls individual dropdown options
2979
+ */
2980
+ const comboboxOptionVariants = cva(clsx(
2909
2981
  // Layout
2910
2982
  'flex items-center',
2911
- // Min height
2912
- 'min-h-[57px]',
2913
- // Padding - responsive
2914
- 'px-[17px] py-5 md:px-3.5 md:py-4',
2915
- // Border radius
2916
- 'rounded-t-xl',
2917
- // Box sizing
2918
- 'box-border',
2983
+ // Size
2984
+ 'min-h-8',
2985
+ // Padding
2986
+ 'py-1 px-3',
2987
+ // Typography
2988
+ 'text-base font-normal leading-6 tracking-[0.05px] text-foreground',
2989
+ // Cursor
2990
+ 'cursor-pointer',
2991
+ // Transition
2992
+ 'transition-colors duration-200',
2993
+ // Hover
2994
+ 'hover:bg-muted/50'), {
2995
+ variants: {
2996
+ selected: {
2997
+ true: 'bg-muted hover:bg-muted',
2998
+ false: '',
2999
+ },
3000
+ },
3001
+ defaultVariants: {
3002
+ selected: false,
3003
+ },
3004
+ });
3005
+ /**
3006
+ * Combobox empty state variants
3007
+ *
3008
+ * Controls the empty state message
3009
+ */
3010
+ const comboboxEmptyStateVariants = cva(clsx(
3011
+ // Padding
3012
+ 'py-4 px-3',
2919
3013
  // Typography
2920
- 'font-sans text-base font-semibold leading-normal', 'md:text-sm'), {
3014
+ 'text-sm font-normal text-muted-foreground text-center'));
3015
+ /**
3016
+ * Combobox error message variants
3017
+ *
3018
+ * Controls the error message display
3019
+ */
3020
+ const comboboxErrorMessageVariants = cva(clsx(
3021
+ // Margin
3022
+ 'mt-1.5',
3023
+ // Typography
3024
+ 'text-xs font-normal leading-[1.4] text-destructive'));
3025
+ /**
3026
+ * Combobox value text variants
3027
+ *
3028
+ * Controls the selected value display
3029
+ */
3030
+ const comboboxValueVariants = cva(clsx(
3031
+ // Layout
3032
+ 'flex-1 text-left'));
3033
+ /**
3034
+ * Combobox icon variants
3035
+ *
3036
+ * Controls the chevron icon
3037
+ */
3038
+ const comboboxIconVariants = cva(clsx(
3039
+ // Size
3040
+ 'shrink-0 w-3.5 h-2'));
3041
+
3042
+ /**
3043
+ * Combobox Component - Searchable dropdown select
3044
+ *
3045
+ * Following shadcn/ui pattern:
3046
+ * ```html
3047
+ * <bsg-combobox
3048
+ * [options]="options"
3049
+ * [placeholder]="'Select...'"
3050
+ * [size]="'md'"
3051
+ * (valueChange)="onValueChange($event)"
3052
+ * />
3053
+ * ```
3054
+ */
3055
+ class ComboboxComponent {
3056
+ /** Size of the combobox */
3057
+ size = input('sm', ...(ngDevMode ? [{ debugName: "size" }] : []));
3058
+ /** Current state */
3059
+ state = input('default', ...(ngDevMode ? [{ debugName: "state" }] : []));
3060
+ /** List of options */
3061
+ options = input([
3062
+ { value: '1', label: 'Opcion 1' },
3063
+ { value: '2', label: 'Opcion 2' },
3064
+ { value: '3', label: 'Opcion 3' },
3065
+ { value: '4', label: 'Opcion 4' },
3066
+ ], ...(ngDevMode ? [{ debugName: "options" }] : []));
3067
+ /** Currently selected value (two-way binding supported) */
3068
+ selectedValue = model('', ...(ngDevMode ? [{ debugName: "selectedValue" }] : []));
3069
+ /** Placeholder text */
3070
+ placeholder = input('Selecciona', ...(ngDevMode ? [{ debugName: "placeholder" }] : []));
3071
+ /** Dropdown open state (two-way binding supported) */
3072
+ open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : []));
3073
+ /** Error message (shown when state is 'error') */
3074
+ errorMessage = input('', ...(ngDevMode ? [{ debugName: "errorMessage" }] : []));
3075
+ /** Additional CSS classes */
3076
+ className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
3077
+ /** Value change event */
3078
+ valueChange = output();
3079
+ /** Selection change event */
3080
+ selectionChange = output();
3081
+ /** Open state change event */
3082
+ openChange = output();
3083
+ /** Internal open state */
3084
+ isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : []));
3085
+ /** Search text for filtering */
3086
+ searchText = signal('', ...(ngDevMode ? [{ debugName: "searchText" }] : []));
3087
+ constructor() {
3088
+ // Sync isOpen with open input
3089
+ effect(() => {
3090
+ this.isOpen.set(this.open());
3091
+ });
3092
+ }
3093
+ // Computed classes
3094
+ wrapperClasses = computed(() => clsx(comboboxWrapperVariants({
3095
+ size: this.size(),
3096
+ }), this.className()), ...(ngDevMode ? [{ debugName: "wrapperClasses" }] : []));
3097
+ triggerClasses = computed(() => clsx(comboboxTriggerVariants({
3098
+ size: this.size(),
3099
+ state: this.state(),
3100
+ open: this.isOpen(),
3101
+ })), ...(ngDevMode ? [{ debugName: "triggerClasses" }] : []));
3102
+ dropdownClasses = computed(() => clsx(comboboxDropdownVariants({
3103
+ size: this.size(),
3104
+ })), ...(ngDevMode ? [{ debugName: "dropdownClasses" }] : []));
3105
+ searchWrapperClasses = computed(() => clsx(comboboxSearchWrapperVariants()), ...(ngDevMode ? [{ debugName: "searchWrapperClasses" }] : []));
3106
+ searchInputClasses = computed(() => clsx(comboboxSearchInputVariants()), ...(ngDevMode ? [{ debugName: "searchInputClasses" }] : []));
3107
+ optionsContainerClasses = computed(() => clsx(comboboxOptionsContainerVariants()), ...(ngDevMode ? [{ debugName: "optionsContainerClasses" }] : []));
3108
+ emptyStateClasses = computed(() => clsx(comboboxEmptyStateVariants()), ...(ngDevMode ? [{ debugName: "emptyStateClasses" }] : []));
3109
+ errorMessageClasses = computed(() => clsx(comboboxErrorMessageVariants()), ...(ngDevMode ? [{ debugName: "errorMessageClasses" }] : []));
3110
+ valueClasses = computed(() => clsx(comboboxValueVariants()), ...(ngDevMode ? [{ debugName: "valueClasses" }] : []));
3111
+ iconClasses = computed(() => clsx(comboboxIconVariants()), ...(ngDevMode ? [{ debugName: "iconClasses" }] : []));
3112
+ selectedLabel = computed(() => {
3113
+ const value = this.selectedValue();
3114
+ if (!value) {
3115
+ return this.placeholder();
3116
+ }
3117
+ const selected = this.options().find((opt) => opt.value === value);
3118
+ return selected ? selected.label : this.placeholder();
3119
+ }, ...(ngDevMode ? [{ debugName: "selectedLabel" }] : []));
3120
+ iconColor = computed(() => {
3121
+ if (this.state() === 'error') {
3122
+ return 'currentColor';
3123
+ }
3124
+ return '#64748B'; // neutral-500
3125
+ }, ...(ngDevMode ? [{ debugName: "iconColor" }] : []));
3126
+ filteredOptions = computed(() => {
3127
+ const term = this.searchText().trim().toLowerCase();
3128
+ if (!term)
3129
+ return this.options();
3130
+ return this.options().filter((option) => option.label.toLowerCase().includes(term));
3131
+ }, ...(ngDevMode ? [{ debugName: "filteredOptions" }] : []));
3132
+ getOptionClasses(value) {
3133
+ return clsx(comboboxOptionVariants({
3134
+ selected: this.selectedValue() === value,
3135
+ }));
3136
+ }
3137
+ toggleDropdown(event) {
3138
+ event.stopPropagation();
3139
+ if (this.state() === 'disabled') {
3140
+ return;
3141
+ }
3142
+ const newState = !this.isOpen();
3143
+ this.isOpen.set(newState);
3144
+ this.open.set(newState);
3145
+ if (newState) {
3146
+ this.searchText.set('');
3147
+ }
3148
+ this.openChange.emit(newState);
3149
+ }
3150
+ closeDropdown() {
3151
+ this.isOpen.set(false);
3152
+ this.open.set(false);
3153
+ this.searchText.set('');
3154
+ this.openChange.emit(false);
3155
+ }
3156
+ selectOption(event, option) {
3157
+ event.stopPropagation();
3158
+ if (this.state() === 'disabled') {
3159
+ return;
3160
+ }
3161
+ // Update internal state
3162
+ this.selectedValue.set(option.value);
3163
+ this.isOpen.set(false);
3164
+ this.open.set(false);
3165
+ this.searchText.set('');
3166
+ // Emit events
3167
+ this.valueChange.emit(option.value);
3168
+ this.selectionChange.emit(option);
3169
+ this.openChange.emit(false);
3170
+ }
3171
+ onDocumentClick(event) {
3172
+ const target = event.target;
3173
+ const hostElement = event.currentTarget.querySelector('bsg-combobox');
3174
+ // Check if click is outside the combobox
3175
+ if (hostElement && !hostElement.contains(target) && this.isOpen()) {
3176
+ this.closeDropdown();
3177
+ }
3178
+ }
3179
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ComboboxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3180
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: ComboboxComponent, isStandalone: true, selector: "bsg-combobox", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, selectedValue: { classPropertyName: "selectedValue", publicName: "selectedValue", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectedValue: "selectedValueChange", open: "openChange", valueChange: "valueChange", selectionChange: "selectionChange", openChange: "openChange" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: `
3181
+ <div [class]="wrapperClasses()">
3182
+ <!-- Combobox trigger -->
3183
+ <button
3184
+ type="button"
3185
+ [class]="triggerClasses()"
3186
+ [disabled]="state() === 'disabled'"
3187
+ [attr.aria-expanded]="isOpen()"
3188
+ [attr.aria-haspopup]="'listbox'"
3189
+ [attr.aria-disabled]="state() === 'disabled'"
3190
+ (click)="toggleDropdown($event)"
3191
+ >
3192
+ <span [class]="valueClasses()">{{ selectedLabel() }}</span>
3193
+ <svg
3194
+ [class]="iconClasses()"
3195
+ width="14"
3196
+ height="8"
3197
+ viewBox="0 0 14 8"
3198
+ fill="none"
3199
+ xmlns="http://www.w3.org/2000/svg"
3200
+ >
3201
+ <path
3202
+ d="M12.2929 0.292893C12.6834 -0.0976311 13.3164 -0.0976311 13.707 0.292893C14.0975 0.683417 14.0975 1.31643 13.707 1.70696L7.70696 7.70696C7.31643 8.09748 6.68342 8.09748 6.29289 7.70696L0.292893 1.70696C-0.0976311 1.31643 -0.0976311 0.683417 0.292893 0.292893C0.683418 -0.0976311 1.31643 -0.0976311 1.70696 0.292893L6.99992 5.58586L12.2929 0.292893Z"
3203
+ [attr.fill]="iconColor()"
3204
+ />
3205
+ </svg>
3206
+ </button>
3207
+
3208
+ <!-- Dropdown menu with search -->
3209
+ @if (isOpen()) {
3210
+ <div [class]="dropdownClasses()" role="listbox">
3211
+ <!-- Search input -->
3212
+ <div [class]="searchWrapperClasses()">
3213
+ <input
3214
+ type="text"
3215
+ [class]="searchInputClasses()"
3216
+ [disabled]="state() === 'disabled'"
3217
+ placeholder="Buscar..."
3218
+ [ngModel]="searchText()"
3219
+ (ngModelChange)="searchText.set($event)"
3220
+ (keydown.escape)="closeDropdown()"
3221
+ (click)="$event.stopPropagation()"
3222
+ aria-label="Search options"
3223
+ />
3224
+ </div>
3225
+
3226
+ <!-- Options list -->
3227
+ <div [class]="optionsContainerClasses()">
3228
+ @for (option of filteredOptions(); track option.value) {
3229
+ <div
3230
+ [class]="getOptionClasses(option.value)"
3231
+ role="option"
3232
+ [attr.aria-selected]="selectedValue() === option.value"
3233
+ (click)="selectOption($event, option)"
3234
+ >
3235
+ {{ option.label }}
3236
+ </div>
3237
+ }
3238
+
3239
+ <!-- Empty state -->
3240
+ @if (filteredOptions().length === 0) {
3241
+ <div [class]="emptyStateClasses()">Sin resultados</div>
3242
+ }
3243
+ </div>
3244
+ </div>
3245
+ }
3246
+
3247
+ <!-- Error message -->
3248
+ @if (state() === 'error' && errorMessage()) {
3249
+ <div [class]="errorMessageClasses()">
3250
+ {{ errorMessage() }}
3251
+ </div>
3252
+ }
3253
+ </div>
3254
+ `, isInline: true, styles: [":host{display:inline-block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
3255
+ }
3256
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: ComboboxComponent, decorators: [{
3257
+ type: Component,
3258
+ args: [{ selector: 'bsg-combobox', standalone: true, imports: [CommonModule, FormsModule], template: `
3259
+ <div [class]="wrapperClasses()">
3260
+ <!-- Combobox trigger -->
3261
+ <button
3262
+ type="button"
3263
+ [class]="triggerClasses()"
3264
+ [disabled]="state() === 'disabled'"
3265
+ [attr.aria-expanded]="isOpen()"
3266
+ [attr.aria-haspopup]="'listbox'"
3267
+ [attr.aria-disabled]="state() === 'disabled'"
3268
+ (click)="toggleDropdown($event)"
3269
+ >
3270
+ <span [class]="valueClasses()">{{ selectedLabel() }}</span>
3271
+ <svg
3272
+ [class]="iconClasses()"
3273
+ width="14"
3274
+ height="8"
3275
+ viewBox="0 0 14 8"
3276
+ fill="none"
3277
+ xmlns="http://www.w3.org/2000/svg"
3278
+ >
3279
+ <path
3280
+ d="M12.2929 0.292893C12.6834 -0.0976311 13.3164 -0.0976311 13.707 0.292893C14.0975 0.683417 14.0975 1.31643 13.707 1.70696L7.70696 7.70696C7.31643 8.09748 6.68342 8.09748 6.29289 7.70696L0.292893 1.70696C-0.0976311 1.31643 -0.0976311 0.683417 0.292893 0.292893C0.683418 -0.0976311 1.31643 -0.0976311 1.70696 0.292893L6.99992 5.58586L12.2929 0.292893Z"
3281
+ [attr.fill]="iconColor()"
3282
+ />
3283
+ </svg>
3284
+ </button>
3285
+
3286
+ <!-- Dropdown menu with search -->
3287
+ @if (isOpen()) {
3288
+ <div [class]="dropdownClasses()" role="listbox">
3289
+ <!-- Search input -->
3290
+ <div [class]="searchWrapperClasses()">
3291
+ <input
3292
+ type="text"
3293
+ [class]="searchInputClasses()"
3294
+ [disabled]="state() === 'disabled'"
3295
+ placeholder="Buscar..."
3296
+ [ngModel]="searchText()"
3297
+ (ngModelChange)="searchText.set($event)"
3298
+ (keydown.escape)="closeDropdown()"
3299
+ (click)="$event.stopPropagation()"
3300
+ aria-label="Search options"
3301
+ />
3302
+ </div>
3303
+
3304
+ <!-- Options list -->
3305
+ <div [class]="optionsContainerClasses()">
3306
+ @for (option of filteredOptions(); track option.value) {
3307
+ <div
3308
+ [class]="getOptionClasses(option.value)"
3309
+ role="option"
3310
+ [attr.aria-selected]="selectedValue() === option.value"
3311
+ (click)="selectOption($event, option)"
3312
+ >
3313
+ {{ option.label }}
3314
+ </div>
3315
+ }
3316
+
3317
+ <!-- Empty state -->
3318
+ @if (filteredOptions().length === 0) {
3319
+ <div [class]="emptyStateClasses()">Sin resultados</div>
3320
+ }
3321
+ </div>
3322
+ </div>
3323
+ }
3324
+
3325
+ <!-- Error message -->
3326
+ @if (state() === 'error' && errorMessage()) {
3327
+ <div [class]="errorMessageClasses()">
3328
+ {{ errorMessage() }}
3329
+ </div>
3330
+ }
3331
+ </div>
3332
+ `, styles: [":host{display:inline-block}\n"] }]
3333
+ }], ctorParameters: () => [], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], selectedValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedValue", required: false }] }, { type: i0.Output, args: ["selectedValueChange"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], openChange: [{ type: i0.Output, args: ["openChange"] }], onDocumentClick: [{
3334
+ type: HostListener,
3335
+ args: ['document:click', ['$event']]
3336
+ }] } });
3337
+
3338
+ // projects/bsg-integra/src/lib/components/dialog/dialog.variants.ts
3339
+ /**
3340
+ * Dialog overlay variants
3341
+ */
3342
+ const dialogOverlayVariants = cva(clsx('fixed inset-0', 'z-[9999]', 'flex justify-center', 'items-start sm:items-center', 'overflow-y-auto', 'bg-black/50', 'p-4 md:p-3', 'box-border', 'animate-in fade-in duration-200', 'select-none'));
3343
+ /**
3344
+ * Dialog content variants
3345
+ */
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'), {
3347
+ variants: {
3348
+ size: {
3349
+ sm: 'max-w-sm',
3350
+ md: 'max-w-md',
3351
+ lg: 'max-w-lg',
3352
+ xl: 'max-w-xl',
3353
+ '2xl': 'max-w-2xl',
3354
+ '3xl': 'max-w-3xl',
3355
+ '4xl': 'max-w-4xl',
3356
+ full: 'max-w-[calc(100vw-2rem)]',
3357
+ },
3358
+ },
3359
+ defaultVariants: {
3360
+ size: 'lg',
3361
+ },
3362
+ });
3363
+ /**
3364
+ * Dialog header variants
3365
+ */
3366
+ 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'), {
2921
3367
  variants: {
2922
3368
  tone: {
2923
3369
  brand: 'bg-orange-600 text-white',
@@ -2931,20 +3377,8 @@ const dialogHeaderVariants = cva(clsx(
2931
3377
  });
2932
3378
  /**
2933
3379
  * Dialog body variants
2934
- *
2935
- * Controls the body/content section
2936
3380
  */
2937
- const dialogBodyVariants = cva(clsx(
2938
- // Flex
2939
- 'flex-1',
2940
- // Padding - responsive
2941
- 'px-[23px] py-5 md:px-3.5 md:py-4',
2942
- // Box sizing
2943
- 'box-border',
2944
- // Typography
2945
- 'font-sans text-sm font-medium leading-normal', 'md:text-[13px]',
2946
- // Color
2947
- 'text-slate-500'), {
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'), {
2948
3382
  variants: {
2949
3383
  scrollable: {
2950
3384
  true: 'overflow-y-auto max-h-[calc(90vh-200px)] md:max-h-[calc(95vh-180px)]',
@@ -2957,45 +3391,15 @@ const dialogBodyVariants = cva(clsx(
2957
3391
  });
2958
3392
  /**
2959
3393
  * Dialog footer variants
2960
- *
2961
- * Controls the footer section with actions
2962
3394
  */
2963
- const dialogFooterVariants = cva(clsx(
2964
- // Layout
2965
- 'flex items-center justify-end flex-nowrap',
2966
- // Gap - responsive
2967
- 'gap-8 md:gap-5',
2968
- // Padding - responsive
2969
- 'px-[23px] py-5 md:px-3.5 md:py-4',
2970
- // Border
2971
- 'border-t border-slate-200',
2972
- // Box sizing
2973
- 'box-border',
2974
- // Width
2975
- 'w-full'));
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'));
2976
3396
 
2977
- /**
2978
- * Dialog Component
2979
- *
2980
- * A modal dialog component with multiple sizes and header tones.
2981
- *
2982
- * Usage:
2983
- * ```html
2984
- * <bsg-dialog [open]="isOpen" size="md" headerTone="brand" (closeDialog)="onClose()">
2985
- * <div dialog-header>Dialog Title</div>
2986
- * <div dialog-body>Dialog content goes here</div>
2987
- * <div dialog-footer>
2988
- * <button>Cancel</button>
2989
- * <button>Confirm</button>
2990
- * </div>
2991
- * </bsg-dialog>
2992
- * ```
2993
- */
3397
+ // projects/bsg-integra/src/lib/components/dialog/dialog.component.ts
2994
3398
  class DialogComponent {
2995
3399
  /** Controls dialog visibility */
2996
3400
  open = input(false, ...(ngDevMode ? [{ debugName: "open" }] : []));
2997
3401
  /** Dialog size */
2998
- size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : []));
3402
+ size = input('lg', ...(ngDevMode ? [{ debugName: "size" }] : []));
2999
3403
  /** Header tone/theme */
3000
3404
  headerTone = input('brand', ...(ngDevMode ? [{ debugName: "headerTone" }] : []));
3001
3405
  /** Enable scrollable body */
@@ -3014,22 +3418,33 @@ class DialogComponent {
3014
3418
  headerClasses = computed(() => clsx(dialogHeaderVariants({ tone: this.headerTone() })), ...(ngDevMode ? [{ debugName: "headerClasses" }] : []));
3015
3419
  bodyClasses = computed(() => clsx(dialogBodyVariants({ scrollable: this.scrollable() })), ...(ngDevMode ? [{ debugName: "bodyClasses" }] : []));
3016
3420
  footerClasses = computed(() => clsx(dialogFooterVariants()), ...(ngDevMode ? [{ debugName: "footerClasses" }] : []));
3421
+ // Fallback sizing (prevents min-content collapse in some Storybook setups)
3422
+ contentMaxWidth = computed(() => {
3423
+ const map = {
3424
+ sm: '384px',
3425
+ md: '448px',
3426
+ lg: '512px',
3427
+ xl: '576px',
3428
+ '2xl': '672px',
3429
+ '3xl': '768px',
3430
+ '4xl': '896px',
3431
+ full: 'calc(100vw - 2rem)',
3432
+ };
3433
+ return map[this.size()];
3434
+ }, ...(ngDevMode ? [{ debugName: "contentMaxWidth" }] : []));
3017
3435
  onOverlayClick() {
3018
- if (this.dismissible()) {
3436
+ if (this.dismissible())
3019
3437
  this.close();
3020
- }
3021
3438
  }
3022
3439
  close() {
3023
3440
  this.closeDialog.emit();
3024
3441
  }
3025
- onEscapeKey(event) {
3026
- if (this.open() && this.dismissible()) {
3027
- event.preventDefault();
3442
+ onEscapeKey() {
3443
+ if (this.open() && this.dismissible())
3028
3444
  this.close();
3029
- }
3030
3445
  }
3031
3446
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: DialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3032
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DialogComponent, isStandalone: true, selector: "bsg-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, headerTone: { classPropertyName: "headerTone", publicName: "headerTone", isSignal: true, isRequired: false, transformFunction: null }, scrollable: { classPropertyName: "scrollable", publicName: "scrollable", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null }, hasFooter: { classPropertyName: "hasFooter", publicName: "hasFooter", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closeDialog: "closeDialog" }, host: { listeners: { "document:keydown.escape": "onEscapeKey($event)" } }, ngImport: i0, template: `
3447
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: DialogComponent, isStandalone: true, selector: "bsg-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, headerTone: { classPropertyName: "headerTone", publicName: "headerTone", isSignal: true, isRequired: false, transformFunction: null }, scrollable: { classPropertyName: "scrollable", publicName: "scrollable", isSignal: true, isRequired: false, transformFunction: null }, dismissible: { classPropertyName: "dismissible", publicName: "dismissible", isSignal: true, isRequired: false, transformFunction: null }, hasFooter: { classPropertyName: "hasFooter", publicName: "hasFooter", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closeDialog: "closeDialog" }, host: { listeners: { "document:keydown.escape": "onEscapeKey()" } }, ngImport: i0, template: `
3033
3448
  @if (open()) {
3034
3449
  <!-- Dialog Overlay -->
3035
3450
  <div [class]="overlayClasses()" (click)="onOverlayClick()">
@@ -3040,6 +3455,11 @@ class DialogComponent {
3040
3455
  role="dialog"
3041
3456
  [attr.aria-modal]="true"
3042
3457
  aria-labelledby="dialog-title"
3458
+ [style.width]="'100%'"
3459
+ [style.maxWidth]="contentMaxWidth()"
3460
+ [style.minWidth]="'280px'"
3461
+ [style.margin]="'24px auto'"
3462
+ [style.flex]="'0 0 auto'"
3043
3463
  >
3044
3464
  <!-- Dialog Header -->
3045
3465
  <div [class]="headerClasses()">
@@ -3078,6 +3498,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
3078
3498
  role="dialog"
3079
3499
  [attr.aria-modal]="true"
3080
3500
  aria-labelledby="dialog-title"
3501
+ [style.width]="'100%'"
3502
+ [style.maxWidth]="contentMaxWidth()"
3503
+ [style.minWidth]="'280px'"
3504
+ [style.margin]="'24px auto'"
3505
+ [style.flex]="'0 0 auto'"
3081
3506
  >
3082
3507
  <!-- Dialog Header -->
3083
3508
  <div [class]="headerClasses()">
@@ -3102,7 +3527,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
3102
3527
  }]
3103
3528
  }], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], headerTone: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerTone", required: false }] }], scrollable: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollable", required: false }] }], dismissible: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissible", required: false }] }], hasFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasFooter", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], closeDialog: [{ type: i0.Output, args: ["closeDialog"] }], onEscapeKey: [{
3104
3529
  type: HostListener,
3105
- args: ['document:keydown.escape', ['$event']]
3530
+ args: ['document:keydown.escape']
3106
3531
  }] } });
3107
3532
 
3108
3533
  const inputVariants = cva(clsx(
@@ -3487,35 +3912,23 @@ class RadioComponent {
3487
3912
  focusRingSize = computed(() => {
3488
3913
  return this.size() === 'sm' ? 22 : 26;
3489
3914
  }, ...(ngDevMode ? [{ debugName: "focusRingSize" }] : []));
3490
- // Outer stroke color based on state
3491
- outerStrokeColor = computed(() => {
3915
+ // Outer circle classes based on state (using semantic tokens)
3916
+ outerCircleClasses = computed(() => {
3492
3917
  const current = this.currentState();
3493
3918
  if (current === 'disabled') {
3494
- return '#64748B'; // neutral-500
3919
+ return 'stroke-muted-foreground fill-muted-foreground';
3495
3920
  }
3496
3921
  if (current === 'hover') {
3497
- return '#8B5CF6'; // Violet-500
3922
+ return 'stroke-primary/70 fill-none';
3498
3923
  }
3499
3924
  if (current === 'checked') {
3500
- return '#7C3AED'; // Violet-600
3925
+ return 'stroke-primary fill-none';
3501
3926
  }
3502
3927
  if (current === 'focus') {
3503
- return '#64748B'; // neutral-500
3928
+ return 'stroke-muted-foreground fill-none';
3504
3929
  }
3505
- return '#64748B'; // neutral-500 (default)
3506
- }, ...(ngDevMode ? [{ debugName: "outerStrokeColor" }] : []));
3507
- // Outer fill color
3508
- outerFillColor = computed(() => {
3509
- const current = this.currentState();
3510
- if (current === 'disabled') {
3511
- return '#64748B'; // neutral-500 with opacity applied via CSS
3512
- }
3513
- return 'none';
3514
- }, ...(ngDevMode ? [{ debugName: "outerFillColor" }] : []));
3515
- // Focus ring color
3516
- focusRingColor = computed(() => {
3517
- return this.size() === 'sm' ? '#7C3AED' : '#9333EA'; // Violet-600 for sm, Purple-600 for md
3518
- }, ...(ngDevMode ? [{ debugName: "focusRingColor" }] : []));
3930
+ return 'stroke-muted-foreground fill-none'; // default
3931
+ }, ...(ngDevMode ? [{ debugName: "outerCircleClasses" }] : []));
3519
3932
  // Handle click events
3520
3933
  handleClick() {
3521
3934
  if (this.currentState() === 'disabled') {
@@ -3555,7 +3968,7 @@ class RadioComponent {
3555
3968
  [attr.cx]="focusRingSize() / 2"
3556
3969
  [attr.cy]="focusRingSize() / 2"
3557
3970
  [attr.r]="focusRingSize() / 2 - 0.5"
3558
- [attr.stroke]="focusRingColor()"
3971
+ class="stroke-primary"
3559
3972
  stroke-width="1"
3560
3973
  />
3561
3974
  </svg>
@@ -3573,8 +3986,7 @@ class RadioComponent {
3573
3986
  [attr.cx]="outerSize() / 2"
3574
3987
  [attr.cy]="outerSize() / 2"
3575
3988
  [attr.r]="outerSize() / 2 - 0.5"
3576
- [attr.stroke]="outerStrokeColor()"
3577
- [attr.fill]="outerFillColor()"
3989
+ [class]="outerCircleClasses()"
3578
3990
  stroke-width="1"
3579
3991
  />
3580
3992
  </svg>
@@ -3593,13 +4005,12 @@ class RadioComponent {
3593
4005
  [attr.cx]="innerSize() / 2"
3594
4006
  [attr.cy]="innerSize() / 2"
3595
4007
  [attr.r]="innerSize() / 2 - 0.5"
3596
- fill="#7C3AED"
3597
- stroke="#7C3AED"
4008
+ class="fill-primary stroke-primary"
3598
4009
  stroke-width="1"
3599
4010
  />
3600
4011
  </svg>
3601
4012
  </div>
3602
- `, isInline: true, styles: [":host{display:inline-block}.radio-wrapper:focus-visible{outline:none}.radio-wrapper:focus-visible svg circle[stroke]{stroke:#7c3aed}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
4013
+ `, isInline: true, styles: [":host{display:inline-block}.radio-wrapper:focus-visible{outline:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
3603
4014
  }
3604
4015
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RadioComponent, decorators: [{
3605
4016
  type: Component,
@@ -3626,7 +4037,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
3626
4037
  [attr.cx]="focusRingSize() / 2"
3627
4038
  [attr.cy]="focusRingSize() / 2"
3628
4039
  [attr.r]="focusRingSize() / 2 - 0.5"
3629
- [attr.stroke]="focusRingColor()"
4040
+ class="stroke-primary"
3630
4041
  stroke-width="1"
3631
4042
  />
3632
4043
  </svg>
@@ -3644,8 +4055,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
3644
4055
  [attr.cx]="outerSize() / 2"
3645
4056
  [attr.cy]="outerSize() / 2"
3646
4057
  [attr.r]="outerSize() / 2 - 0.5"
3647
- [attr.stroke]="outerStrokeColor()"
3648
- [attr.fill]="outerFillColor()"
4058
+ [class]="outerCircleClasses()"
3649
4059
  stroke-width="1"
3650
4060
  />
3651
4061
  </svg>
@@ -3664,13 +4074,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
3664
4074
  [attr.cx]="innerSize() / 2"
3665
4075
  [attr.cy]="innerSize() / 2"
3666
4076
  [attr.r]="innerSize() / 2 - 0.5"
3667
- fill="#7C3AED"
3668
- stroke="#7C3AED"
4077
+ class="fill-primary stroke-primary"
3669
4078
  stroke-width="1"
3670
4079
  />
3671
4080
  </svg>
3672
4081
  </div>
3673
- `, styles: [":host{display:inline-block}.radio-wrapper:focus-visible{outline:none}.radio-wrapper:focus-visible svg circle[stroke]{stroke:#7c3aed}\n"] }]
4082
+ `, styles: [":host{display:inline-block}.radio-wrapper:focus-visible{outline:none}\n"] }]
3674
4083
  }], ctorParameters: () => [], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], stateChange: [{ type: i0.Output, args: ["stateChange"] }], checkedChange: [{ type: i0.Output, args: ["checkedChange"] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
3675
4084
 
3676
4085
  /**
@@ -3758,14 +4167,16 @@ const radioOptionVariants = cva(clsx(
3758
4167
  */
3759
4168
  const radioLabelVariants = cva(clsx(
3760
4169
  // Typography
3761
- 'font-normal', 'tracking-[0.05px]', 'text-[#202020]'), {
4170
+ 'font-normal', 'tracking-[0.05px]',
4171
+ // Color (semantic token)
4172
+ 'text-foreground'), {
3762
4173
  variants: {
3763
4174
  size: {
3764
4175
  sm: 'text-sm leading-[21px]', // 14px / 21px
3765
4176
  md: 'text-base leading-6', // 16px / 24px
3766
4177
  },
3767
4178
  disabled: {
3768
- true: 'text-slate-500 opacity-60',
4179
+ true: 'text-muted-foreground opacity-60',
3769
4180
  false: '',
3770
4181
  },
3771
4182
  },
@@ -3869,7 +4280,7 @@ class RadioGroupComponent {
3869
4280
  <span [class]="getLabelClasses(option)">{{ option.label }}</span>
3870
4281
  </label>
3871
4282
  </div>
3872
- `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: RadioComponent, selector: "bsg-radio", inputs: ["size", "state", "checked", "className"], outputs: ["stateChange", "checkedChange", "valueChange"] }] });
4283
+ `, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: RadioComponent, selector: "bsg-radio", inputs: ["size", "state", "checked", "className"], outputs: ["stateChange", "checkedChange", "valueChange"] }] });
3873
4284
  }
3874
4285
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RadioGroupComponent, decorators: [{
3875
4286
  type: Component,
@@ -4002,10 +4413,12 @@ const selectDropdownVariants = cva(clsx(
4002
4413
  'absolute top-[calc(100%+4px)] left-0 z-50',
4003
4414
  // Border
4004
4415
  'rounded-md border border-border',
4005
- // Background
4416
+ // Background (semantic token)
4006
4417
  'bg-popover',
4007
- // Shadow
4008
- 'shadow-md',
4418
+ // Text color (semantic token)
4419
+ 'text-popover-foreground',
4420
+ // Shadow (semantic token)
4421
+ 'shadow-(--shadow-dropdown)',
4009
4422
  // Layout
4010
4423
  'overflow-hidden box-border'), {
4011
4424
  variants: {
@@ -5986,8 +6399,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
5986
6399
  * Skeleton variants
5987
6400
  */
5988
6401
  const skeletonVariants = cva(clsx(
5989
- // Base
5990
- 'block bg-slate-200 border-none shrink-0',
6402
+ // Base (semantic token for skeleton background)
6403
+ 'block bg-muted border-none shrink-0',
6404
+ // Animation
6405
+ 'animate-pulse',
5991
6406
  // Non-interactive
5992
6407
  'pointer-events-none select-none'), {
5993
6408
  variants: {
@@ -6070,13 +6485,13 @@ const switchRootVariants = cva(clsx(
6070
6485
  'h-5 w-9',
6071
6486
  // Border & Shape
6072
6487
  'rounded-full border border-transparent',
6073
- // Shadow
6074
- 'shadow-xs',
6488
+ // Shadow (semantic token)
6489
+ 'shadow-(--shadow-xs)',
6075
6490
  // Cursor
6076
6491
  'cursor-pointer',
6077
6492
  // Transition
6078
6493
  'transition-all duration-200',
6079
- // Focus
6494
+ // Focus (semantic tokens)
6080
6495
  'outline-none', 'focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',
6081
6496
  // Remove tap highlight on mobile
6082
6497
  '[&]:tap-highlight-transparent'), {
@@ -6109,10 +6524,10 @@ const switchRootVariants = cva(clsx(
6109
6524
  const switchThumbVariants = cva(clsx(
6110
6525
  // Layout
6111
6526
  'pointer-events-none block rounded-full',
6112
- // Background
6527
+ // Background (semantic token)
6113
6528
  'bg-background',
6114
- // Shadow
6115
- 'shadow-lg',
6529
+ // Shadow (semantic token)
6530
+ 'shadow-(--shadow-lg)',
6116
6531
  // Ring
6117
6532
  'ring-0',
6118
6533
  // Transition
@@ -6123,7 +6538,7 @@ const switchThumbVariants = cva(clsx(
6123
6538
  false: 'translate-x-0',
6124
6539
  },
6125
6540
  size: {
6126
- sm: 'size-3 data-[checked=true]:translate-x-3',
6541
+ sm: 'size-3 data-[checked=true]:translate-x-5',
6127
6542
  default: 'size-4 data-[checked=true]:translate-x-4',
6128
6543
  lg: 'size-5 data-[checked=true]:translate-x-5',
6129
6544
  },
@@ -6433,7 +6848,9 @@ const timepickerWrapperVariants = cva(clsx(
6433
6848
  // Transition
6434
6849
  'transition-all duration-200',
6435
6850
  // Width
6436
- 'w-full'), {
6851
+ 'w-full',
6852
+ // Background
6853
+ 'bg-background'), {
6437
6854
  variants: {
6438
6855
  size: {
6439
6856
  sm: 'h-8 py-1 px-2 pr-2 pl-3',
@@ -6441,11 +6858,11 @@ const timepickerWrapperVariants = cva(clsx(
6441
6858
  lg: 'h-12 py-1 px-2 pr-2 pl-3',
6442
6859
  },
6443
6860
  state: {
6444
- default: 'border-slate-300 bg-transparent hover:border-slate-400',
6445
- hover: 'border-slate-400 bg-transparent',
6446
- focus: 'border-slate-500 bg-transparent ring-2 ring-offset-2 ring-violet-600',
6447
- disabled: 'border-slate-300 bg-transparent opacity-40 cursor-not-allowed pointer-events-none',
6448
- error: 'border-red-600 bg-transparent',
6861
+ default: 'border-input hover:border-ring/50',
6862
+ hover: 'border-ring/50',
6863
+ focus: 'border-ring ring-2 ring-offset-2 ring-ring',
6864
+ disabled: 'border-input opacity-40 cursor-not-allowed pointer-events-none',
6865
+ error: 'border-destructive',
6449
6866
  },
6450
6867
  },
6451
6868
  defaultVariants: {
@@ -6463,10 +6880,10 @@ const timepickerInputVariants = cva(clsx(
6463
6880
  'border-none outline-none bg-transparent',
6464
6881
  // Typography
6465
6882
  'text-base font-normal leading-6 tracking-tight',
6466
- // Color
6467
- 'text-slate-800',
6468
- // Placeholder
6469
- 'placeholder:text-slate-500',
6883
+ // Color (semantic token)
6884
+ 'text-foreground',
6885
+ // Placeholder (semantic token)
6886
+ 'placeholder:text-muted-foreground',
6470
6887
  // Cursor
6471
6888
  'cursor-pointer',
6472
6889
  // Disabled
@@ -6475,9 +6892,9 @@ const timepickerInputVariants = cva(clsx(
6475
6892
  state: {
6476
6893
  default: '',
6477
6894
  hover: '',
6478
- focus: 'text-slate-800',
6895
+ focus: 'text-foreground',
6479
6896
  disabled: 'cursor-not-allowed',
6480
- error: 'text-red-600 placeholder:text-red-600',
6897
+ error: 'text-destructive placeholder:text-destructive',
6481
6898
  },
6482
6899
  },
6483
6900
  defaultVariants: {
@@ -6489,19 +6906,19 @@ const timepickerInputVariants = cva(clsx(
6489
6906
  */
6490
6907
  const timepickerIconButtonVariants = cva(clsx(
6491
6908
  // Size
6492
- 'shrink-0 w-6 h-6 mr-1',
6909
+ 'shrink-0 size-6 mr-1',
6493
6910
  // Layout
6494
6911
  'flex items-center justify-center',
6495
6912
  // Reset
6496
6913
  'bg-transparent border-none p-0',
6497
6914
  // Cursor
6498
6915
  'cursor-pointer',
6499
- // Color
6500
- 'text-current',
6916
+ // Color (semantic token)
6917
+ 'text-muted-foreground',
6501
6918
  // Transition
6502
6919
  'transition-opacity duration-200',
6503
6920
  // Hover
6504
- 'hover:opacity-70',
6921
+ 'hover:opacity-70 hover:text-foreground',
6505
6922
  // Disabled
6506
6923
  'disabled:cursor-not-allowed disabled:opacity-40'));
6507
6924
  /**
@@ -6512,12 +6929,14 @@ const timepickerDropdownVariants = cva(clsx(
6512
6929
  'absolute top-[calc(100%+4px)] left-0 z-[10000]',
6513
6930
  // Shape
6514
6931
  'rounded-md',
6515
- // Border
6516
- 'border border-slate-300',
6517
- // Background
6518
- 'bg-white',
6519
- // Shadow
6520
- 'shadow-md',
6932
+ // Border (semantic token)
6933
+ 'border border-border',
6934
+ // Background (semantic token)
6935
+ 'bg-popover',
6936
+ // Text color (semantic token)
6937
+ 'text-popover-foreground',
6938
+ // Shadow (semantic token)
6939
+ 'shadow-(--shadow-dropdown)',
6521
6940
  // Layout
6522
6941
  'flex flex-col overflow-hidden'), {
6523
6942
  variants: {
@@ -6539,8 +6958,8 @@ const timepickerSelectionAreaVariants = cva(clsx(
6539
6958
  'flex items-center justify-center gap-2',
6540
6959
  // Spacing
6541
6960
  'p-2',
6542
- // Border
6543
- 'border-b border-slate-200'));
6961
+ // Border (semantic token)
6962
+ 'border-b border-border'));
6544
6963
  /**
6545
6964
  * TimePicker column variants
6546
6965
  */
@@ -6553,8 +6972,8 @@ const timepickerColumnVariants = cva(clsx(
6553
6972
  const timepickerColumnHeaderVariants = cva(clsx(
6554
6973
  // Typography
6555
6974
  'text-xs font-semibold uppercase tracking-wide',
6556
- // Color
6557
- 'text-slate-500',
6975
+ // Color (semantic token)
6976
+ 'text-muted-foreground',
6558
6977
  // Alignment
6559
6978
  'text-center',
6560
6979
  // Spacing
@@ -6571,8 +6990,8 @@ const timepickerListVariants = cva(clsx(
6571
6990
  'flex flex-col gap-0.5',
6572
6991
  // Spacing
6573
6992
  'py-1',
6574
- // Scrollbar (Tailwind custom scrollbar classes)
6575
- 'scrollbar-thin scrollbar-thumb-slate-300 scrollbar-track-transparent'));
6993
+ // Scrollbar (semantic token for thumb color)
6994
+ 'scrollbar-thin scrollbar-thumb-border scrollbar-track-transparent'));
6576
6995
  /**
6577
6996
  * TimePicker option variants
6578
6997
  */
@@ -6581,8 +7000,8 @@ const timepickerOptionVariants = cva(clsx(
6581
7000
  'p-2',
6582
7001
  // Typography
6583
7002
  'text-sm font-normal leading-5',
6584
- // Color
6585
- 'text-slate-700',
7003
+ // Color (semantic token)
7004
+ 'text-foreground',
6586
7005
  // Alignment
6587
7006
  'text-center',
6588
7007
  // Cursor
@@ -6597,11 +7016,11 @@ const timepickerOptionVariants = cva(clsx(
6597
7016
  'transition-all duration-150'), {
6598
7017
  variants: {
6599
7018
  selected: {
6600
- true: 'bg-violet-600 text-white font-medium hover:bg-violet-700',
6601
- false: 'hover:bg-slate-100',
7019
+ true: 'bg-primary text-primary-foreground font-medium hover:bg-primary/90',
7020
+ false: 'hover:bg-accent',
6602
7021
  },
6603
7022
  disabled: {
6604
- true: 'opacity-40 cursor-not-allowed text-slate-400 hover:bg-transparent',
7023
+ true: 'opacity-40 cursor-not-allowed text-muted-foreground hover:bg-transparent',
6605
7024
  false: '',
6606
7025
  },
6607
7026
  },
@@ -6616,8 +7035,8 @@ const timepickerOptionVariants = cva(clsx(
6616
7035
  const timepickerSeparatorVariants = cva(clsx(
6617
7036
  // Typography
6618
7037
  'text-xl font-medium',
6619
- // Color
6620
- 'text-slate-500',
7038
+ // Color (semantic token)
7039
+ 'text-muted-foreground',
6621
7040
  // Position
6622
7041
  'mt-5'));
6623
7042
  /**
@@ -6628,8 +7047,8 @@ const timepickerActionsVariants = cva(clsx(
6628
7047
  'flex gap-2',
6629
7048
  // Spacing
6630
7049
  'p-2',
6631
- // Border
6632
- 'border-t border-slate-200'));
7050
+ // Border (semantic token)
7051
+ 'border-t border-border'));
6633
7052
  /**
6634
7053
  * TimePicker action button variants
6635
7054
  */
@@ -6640,24 +7059,24 @@ const timepickerActionButtonVariants = cva(clsx(
6640
7059
  'py-2 px-3',
6641
7060
  // Typography
6642
7061
  'text-[13px] font-medium leading-[18px]',
6643
- // Border
6644
- 'border border-slate-300',
7062
+ // Border (semantic token)
7063
+ 'border border-input',
6645
7064
  // Shape
6646
7065
  'rounded',
6647
7066
  // Background
6648
7067
  'bg-transparent',
6649
- // Color
6650
- 'text-slate-700',
7068
+ // Color (semantic token)
7069
+ 'text-foreground',
6651
7070
  // Cursor
6652
7071
  'cursor-pointer',
6653
7072
  // Transition
6654
7073
  'transition-all duration-150',
6655
7074
  // Alignment
6656
7075
  'text-center',
6657
- // Hover
6658
- 'hover:bg-slate-50 hover:border-slate-400',
6659
- // Active
6660
- 'active:bg-slate-100',
7076
+ // Hover (semantic tokens)
7077
+ 'hover:bg-accent hover:border-ring/50',
7078
+ // Active (semantic token)
7079
+ 'active:bg-accent',
6661
7080
  // Disabled
6662
7081
  'disabled:opacity-40 disabled:cursor-not-allowed'));
6663
7082
  /**
@@ -6666,8 +7085,8 @@ const timepickerActionButtonVariants = cva(clsx(
6666
7085
  const timepickerErrorMessageVariants = cva(clsx(
6667
7086
  // Typography
6668
7087
  'text-xs font-normal leading-4',
6669
- // Color
6670
- 'text-red-600',
7088
+ // Color (semantic token)
7089
+ 'text-destructive',
6671
7090
  // Spacing
6672
7091
  'mt-1'));
6673
7092
 
@@ -6763,7 +7182,7 @@ class TimePickerComponent {
6763
7182
  state: this.displayState(),
6764
7183
  }), this.className()), ...(ngDevMode ? [{ debugName: "wrapperClasses" }] : []));
6765
7184
  inputClasses = computed(() => clsx(timepickerInputVariants({ state: this.displayState() })), ...(ngDevMode ? [{ debugName: "inputClasses" }] : []));
6766
- iconButtonClasses = computed(() => clsx(timepickerIconButtonVariants()), ...(ngDevMode ? [{ debugName: "iconButtonClasses" }] : []));
7185
+ iconButtonClasses = computed(() => clsx(timepickerIconButtonVariants(), this.state() === 'error' && 'text-destructive'), ...(ngDevMode ? [{ debugName: "iconButtonClasses" }] : []));
6767
7186
  dropdownClasses = computed(() => clsx(timepickerDropdownVariants({ size: this.size() })), ...(ngDevMode ? [{ debugName: "dropdownClasses" }] : []));
6768
7187
  selectionAreaClasses = computed(() => clsx(timepickerSelectionAreaVariants()), ...(ngDevMode ? [{ debugName: "selectionAreaClasses" }] : []));
6769
7188
  columnClasses = computed(() => clsx(timepickerColumnVariants()), ...(ngDevMode ? [{ debugName: "columnClasses" }] : []));
@@ -6773,7 +7192,7 @@ class TimePickerComponent {
6773
7192
  actionsClasses = computed(() => clsx(timepickerActionsVariants()), ...(ngDevMode ? [{ debugName: "actionsClasses" }] : []));
6774
7193
  actionButtonClasses = computed(() => clsx(timepickerActionButtonVariants()), ...(ngDevMode ? [{ debugName: "actionButtonClasses" }] : []));
6775
7194
  errorMessageClasses = computed(() => clsx(timepickerErrorMessageVariants()), ...(ngDevMode ? [{ debugName: "errorMessageClasses" }] : []));
6776
- iconColor = computed(() => this.state() === 'error' ? '#DC2626' : '#64748B', ...(ngDevMode ? [{ debugName: "iconColor" }] : []));
7195
+ iconColor = computed(() => this.state() === 'error' ? 'currentColor' : 'currentColor', ...(ngDevMode ? [{ debugName: "iconColor" }] : []));
6777
7196
  getOptionClasses(selected, disabled) {
6778
7197
  return clsx(timepickerOptionVariants({ selected, disabled }));
6779
7198
  }
@@ -6844,6 +7263,35 @@ class TimePickerComponent {
6844
7263
  this.selectedHour.set(hour);
6845
7264
  this.selectedMinute.set(Math.min(snappedMinute, 59));
6846
7265
  this.updateTimeValue();
7266
+ // Scroll to show selected values
7267
+ this.scrollToSelected();
7268
+ }
7269
+ /** Scroll both lists to show the selected values centered */
7270
+ scrollToSelected() {
7271
+ // Use setTimeout to allow Angular to render the changes first
7272
+ setTimeout(() => {
7273
+ this.scrollToElement(this.hoursList, this.selectedHour());
7274
+ this.scrollToElement(this.minutesList, this.selectedMinute());
7275
+ }, 0);
7276
+ }
7277
+ /** Scroll a list to center the element with the given value */
7278
+ scrollToElement(listRef, value) {
7279
+ if (!listRef?.nativeElement)
7280
+ return;
7281
+ const listElement = listRef.nativeElement;
7282
+ const optionElement = listElement.querySelector(`[data-value="${value}"]`);
7283
+ if (optionElement) {
7284
+ // Calculate scroll position to center the element
7285
+ const listHeight = listElement.clientHeight;
7286
+ const optionTop = optionElement.offsetTop;
7287
+ const optionHeight = optionElement.offsetHeight;
7288
+ // Scroll to center the option in the list
7289
+ const scrollTop = optionTop - listHeight / 2 + optionHeight / 2;
7290
+ listElement.scrollTo({
7291
+ top: Math.max(0, scrollTop),
7292
+ behavior: 'smooth',
7293
+ });
7294
+ }
6847
7295
  }
6848
7296
  clearTime() {
6849
7297
  if (this.state() === 'disabled')
@@ -6866,8 +7314,13 @@ class TimePickerComponent {
6866
7314
  toggleDropdown() {
6867
7315
  if (this.state() === 'disabled')
6868
7316
  return;
7317
+ const wasOpen = this.isOpen();
6869
7318
  this.isOpen.update((v) => !v);
6870
7319
  this.openChange.emit(this.isOpen());
7320
+ // Scroll to selected values when opening
7321
+ if (!wasOpen && this.internalValue()) {
7322
+ this.scrollToSelected();
7323
+ }
6871
7324
  }
6872
7325
  openDropdown() {
6873
7326
  if (this.state() === 'disabled')
@@ -6875,6 +7328,10 @@ class TimePickerComponent {
6875
7328
  if (!this.isOpen()) {
6876
7329
  this.isOpen.set(true);
6877
7330
  this.openChange.emit(true);
7331
+ // Scroll to selected values when opening
7332
+ if (this.internalValue()) {
7333
+ this.scrollToSelected();
7334
+ }
6878
7335
  }
6879
7336
  }
6880
7337
  closeDropdown() {
@@ -7633,18 +8090,18 @@ const tooltipTriggerVariants = cva(clsx(
7633
8090
  const tooltipContentVariants = cva(clsx(
7634
8091
  // Position
7635
8092
  'absolute z-50',
7636
- // Colors
7637
- 'bg-primary text-primary-foreground',
7638
- // Shape
7639
- 'rounded-md',
8093
+ // Colors (semantic tokens)
8094
+ 'bg-tooltip text-tooltip-foreground',
8095
+ // Shape (using border token)
8096
+ 'rounded-(--border-tooltip-radius)',
7640
8097
  // Spacing
7641
8098
  'px-3 py-1.5',
7642
8099
  // Typography
7643
8100
  'text-xs font-medium leading-normal',
7644
8101
  // Behavior
7645
8102
  'whitespace-nowrap pointer-events-none select-none',
7646
- // Shadow
7647
- 'shadow-md',
8103
+ // Shadow (semantic token)
8104
+ 'shadow-(--shadow-tooltip)',
7648
8105
  // Animation
7649
8106
  'animate-in fade-in-0 zoom-in-95'), {
7650
8107
  variants: {
@@ -7668,11 +8125,11 @@ const tooltipArrowVariants = cva(clsx(
7668
8125
  // Position
7669
8126
  'absolute',
7670
8127
  // Size
7671
- 'w-2 h-2',
7672
- // Color (inherits from parent)
7673
- 'bg-primary',
8128
+ 'size-2',
8129
+ // Color (semantic token - matches tooltip background)
8130
+ 'bg-tooltip',
7674
8131
  // Shape
7675
- 'rounded-[1px] rotate-45'), {
8132
+ 'rounded-px rotate-45'), {
7676
8133
  variants: {
7677
8134
  placement: {
7678
8135
  top: '-bottom-1 left-1/2 -translate-x-1/2',
@@ -7868,5 +8325,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImpo
7868
8325
  * Generated bundle index. Do not edit.
7869
8326
  */
7870
8327
 
7871
- export { AccordionComponent, AccordionContentComponent, AccordionItemComponent, AccordionTriggerComponent, AlertComponent, AvatarComponent, BadgeComponent, ButtonComponent, CardBodyComponent, CardComponent, CardFooterComponent, CardHeaderComponent, CarouselComponent, CarouselItemComponent, CheckboxComponent, CollapsibleComponent, CollapsibleContentComponent, CollapsibleTriggerDirective, 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, 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 };
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 };
7872
8329
  //# sourceMappingURL=bsginstitute-bsg-integra.mjs.map