sdga-ui 1.0.18 → 1.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sdga-ui",
3
- "version": "1.0.18",
3
+ "version": "1.0.20",
4
4
  "description": "DGA UI - Government-Style Bootstrap Theme",
5
5
  "keywords": [
6
6
  "sdga",
@@ -32,7 +32,8 @@ $tab-v-height-sm: map-get($spacers, 5); // 24px
32
32
  .nav {
33
33
  padding: 0;
34
34
  }
35
- // Sizes Mixin
35
+
36
+ // Sizes Mixin (Helper for Horizontal)
36
37
  @mixin nav-size($height, $padding-y, $padding-x, $font-size) {
37
38
  .nav-link {
38
39
  height: $height !important;
@@ -45,18 +46,24 @@ $tab-v-height-sm: map-get($spacers, 5); // 24px
45
46
  }
46
47
  }
47
48
 
48
- .nav-tabs {
49
+ // ============================================
50
+ // MIXINS DEFINITION
51
+ // ============================================
52
+
53
+ @mixin tabs-horizontal {
49
54
  --#{$prefix}nav-tabs-border-width: 0;
50
55
  --#{$prefix}nav-tabs-border-radius: 0;
51
56
  --#{$prefix}nav-tabs-link-active-bg: transparent;
52
57
 
53
58
  position: relative; // Establish positioning context
54
59
  border-bottom: 3px solid transparent; // Maintain space but make transparent
60
+ border-right: 0; // Reset vertical
55
61
  gap: map-get($spacers, 2); // 8px
56
62
 
57
63
  // Rounded bottom border line
58
64
  &::before {
59
65
  content: '';
66
+ display: block; // Ensure it's visible (reset display:none from vertical)
60
67
  position: absolute;
61
68
  left: 0;
62
69
  bottom: -3px; // Align with the transparent border
@@ -78,6 +85,11 @@ $tab-v-height-sm: map-get($spacers, 5); // 24px
78
85
  display: flex;
79
86
  align-items: center;
80
87
  gap: map-get($spacers, 1); // 4px gap between icon and text (from sample)
88
+
89
+ // Reset vertical specific
90
+ width: auto;
91
+ justify-content: center;
92
+ margin-bottom: 0;
81
93
 
82
94
  // Hover State & Pseudo-Hover (exclude active tabs)
83
95
  &:hover:not(.disabled):not(.active),
@@ -106,135 +118,130 @@ $tab-v-height-sm: map-get($spacers, 5); // 24px
106
118
  pointer-events: none;
107
119
  cursor: not-allowed;
108
120
  }
109
- }
110
- }
111
121
 
112
- // ============================================
113
- // HORIZONTAL TABS - ACTIVE INDICATOR
114
- // ============================================
115
- // Bottom underline indicator for horizontal tabs only
116
- // Bumped specificity to override _nav.scss
117
- .nav-tabs.nav-tabs:not(.flex-column) .nav-link {
122
+ // Active indicator as ::before pseudo-element (bottom underline)
123
+ &::before {
124
+ content: '';
125
+ position: absolute;
126
+ inset-inline-start: map-get($spacers, 4); // 16px from start
127
+ inset-inline-end: map-get($spacers, 4); // 16px from end
128
+ bottom: 0;
129
+ top: auto; // Reset vertical
130
+ width: auto; // Reset vertical
131
+ height: 3px;
132
+ background-color: transparent;
133
+ border-radius: $radius-full; // Rounded ends
134
+ z-index: 1; // Ensure it sits on top of the border
135
+ transition: background-color 0.2s ease; // Smooth transition
136
+ margin-bottom: -2.75px;
137
+ }
118
138
 
119
- // Active indicator as ::before pseudo-element (bottom underline)
120
- // Changed from ::after to avoid conflict with dropdown caret
121
- &::before {
122
- content: '';
123
- position: absolute;
124
- inset-inline-start: map-get($spacers, 4); // 16px from start
125
- inset-inline-end: map-get($spacers, 4); // 16px from end
126
- bottom: 0;
127
- height: 3px;
128
- background-color: transparent;
129
- border-radius: $radius-full; // Rounded ends
130
- z-index: 1; // Ensure it sits on top of the border
131
- transition: background-color 0.2s ease; // Smooth transition
132
- margin-bottom: -2.75px;
139
+ // Flush variant (no left/right gap for indicator)
140
+ // Using @at-root to break out of .nav-link nesting but keep context if needed,
141
+ // actually inside mixin standard nesting works best.
142
+ // However, flush needs to target the generic parent .flush class.
143
+ // Since we are inside .nav-tabs context when including, & refers to .nav-tabs
144
+ // We need to check if parent has flush.
145
+ // Simpler: Just rely on the fact that standard BS navs work.
146
+ // The original code used @at-root .nav-tabs.flush .nav-link...
133
147
  }
134
-
135
- // Flush variant (no left/right gap for indicator)
136
- @at-root .nav-tabs.nav-tabs.flush .nav-link::before {
137
- inset-inline-start: 0;
138
- inset-inline-end: 0;
148
+
149
+ // Flush handling needs to be careful about not breaking when inside responsive classes
150
+ &.flush .nav-link::before {
151
+ inset-inline-start: 0;
152
+ inset-inline-end: 0;
139
153
  }
140
154
 
141
- &.active::before {
142
- background-color: $nav-link-selection-indicator; // #1B8354 green
143
- }
155
+ // Links styling (Continued)
156
+ .nav-link {
157
+ &.active::before {
158
+ background-color: $nav-link-selection-indicator; // #1B8354 green
159
+ }
144
160
 
145
- // Hover & Pressed state for non-active, non-disabled tabs
146
- &:hover:not(.active):not(.disabled)::before,
147
- &.pseudo-hover:not(.active):not(.disabled)::before,
148
- &:active:not(.active):not(.disabled)::before,
149
- &.pseudo-active:not(.active):not(.disabled)::before {
150
- background-color: $nav-link-selection-indicator-default;
151
- }
161
+ // Hover & Pressed state for non-active
162
+ &:hover:not(.active):not(.disabled)::before,
163
+ &.pseudo-hover:not(.active):not(.disabled)::before,
164
+ &:active:not(.active):not(.disabled)::before,
165
+ &.pseudo-active:not(.active):not(.disabled)::before {
166
+ background-color: $nav-link-selection-indicator-default;
167
+ }
152
168
 
153
- // If disabled AND active, show gray indicator
154
- &.disabled.active::before {
155
- background-color: $nav-link-disabled-color; // Gray indicator for disabled selected tabs
169
+ // If disabled AND active, show gray indicator
170
+ &.disabled.active::before {
171
+ background-color: $nav-link-disabled-color;
172
+ }
156
173
  }
157
- }
158
-
159
- // ============================================
160
- // HORIZONTAL TABS - SIZES
161
- // ============================================
162
- // Bumped specificity to override _nav.scss
163
- .nav-tabs.nav-tabs:not(.flex-column) {
164
174
 
165
- // Sizes
175
+ // Sizes logic embedded
166
176
  &.nav-lg {
167
- @include nav-size($tab-height-lg, map-get($spacers, 4), map-get($spacers, 4), $font-size-sm); // 16px padding, 14px font
177
+ @include nav-size($tab-height-lg, map-get($spacers, 4), map-get($spacers, 4), $font-size-sm);
168
178
  }
169
179
 
170
180
  &.nav-md {
171
- @include nav-size($tab-height-md, map-get($spacers, 3), map-get($spacers, 4), $font-size-sm); // 12px padding, 14px font
181
+ @include nav-size($tab-height-md, map-get($spacers, 3), map-get($spacers, 4), $font-size-sm);
172
182
  }
173
183
 
174
184
  &.nav-sm {
175
- @include nav-size($tab-height-sm, map-get($spacers, 2), map-get($spacers, 3), $font-size-sm); // 8px padding, 12px padding, 14px font
185
+ @include nav-size($tab-height-sm, map-get($spacers, 2), map-get($spacers, 3), $font-size-sm);
176
186
  }
177
187
  }
178
188
 
179
- // Vertical Tabs Customization
180
- // Based on samples in: c:\Users\amro_\source\repos\dga-ui\samples\vertical tabs
181
- // Applies ONLY to vertical tabs (.nav.flex-column.nav-tabs), not horizontal tabs
182
- .nav.flex-column.nav-tabs {
189
+ @mixin tabs-vertical {
183
190
  border-bottom: 0;
191
+ border-right: 0;
192
+ gap: 0;
193
+
184
194
  &::before {
185
195
  display: none; // Hide the rounded horizontal border
186
196
  }
187
- border-right: 0;
188
- gap: 0;
189
197
 
190
198
  .nav-link {
191
199
  width: 100%;
192
200
  justify-content: flex-start;
193
- border: none; // Remove all default button/link borders
201
+ border: none;
194
202
  border-bottom: none;
195
203
  border-radius: $radius-sm;
196
204
  margin-bottom: map-get($spacers, 1); // 4px
197
- font-weight: $font-weight-base; // 400 (default from samples)
198
- color: $nav-link-color; // #384250 default
199
- position: relative; // For ::before positioning
205
+ font-weight: $font-weight-base;
206
+ color: $nav-link-color;
207
+ position: relative;
200
208
  display: flex;
201
- align-items: center; // Vertically center content
202
- gap: map-get($spacers, 2); // 8px gap between icon and text
209
+ align-items: center;
210
+ gap: map-get($spacers, 2);
203
211
 
204
212
  // Enable indicator rendering but keep transparent by default
205
213
  &::before {
206
214
  content: '';
207
215
  position: absolute;
208
216
  inset-inline-start: 0; // Logical property for LTR left / RTL right
217
+ inset-inline-end: auto; // Reset horizontal
209
218
  top: map-get($spacers, 1); // 4px from top
210
219
  bottom: map-get($spacers, 1); // 4px from bottom
211
220
  width: 3px;
221
+ height: auto; // Reset horizontal
212
222
  background-color: transparent;
213
- border-radius: $radius-full; // rounded ends like in samples
223
+ border-radius: $radius-full;
214
224
  transition: background-color 0.2s ease;
225
+ margin-bottom: 0; // Reset horizontal
215
226
  }
216
227
 
217
- // Ensure icon is vertically centered
218
- i,
219
- img,
220
- svg {
228
+ // Icons
229
+ i, img, svg {
221
230
  display: inline-flex;
222
231
  align-items: center;
223
232
  justify-content: center;
224
233
  }
225
234
 
226
- // Remove default button outline for buttons used as nav-links
227
- &:focus,
228
- &:focus-visible {
229
- outline: none; // Remove browser default outline
235
+ &:focus, &:focus-visible {
236
+ outline: none;
230
237
  border: none;
231
238
  }
232
239
 
233
- // Hover State for non-active
240
+ // Hover State
234
241
  &:hover:not(.disabled):not(.active),
235
242
  &.pseudo-hover:not(.active) {
236
- background-color: $nav-link-hover-bg; // #f3f4f6
237
- color: $nav-link-color; // No color change on hover
243
+ background-color: $nav-link-hover-bg;
244
+ color: $nav-link-color;
238
245
 
239
246
  &::before {
240
247
  background-color: $nav-link-selection-indicator-default;
@@ -244,7 +251,7 @@ $tab-v-height-sm: map-get($spacers, 5); // 24px
244
251
  // Pressed State
245
252
  &:active:not(.disabled):not(.active),
246
253
  &.pseudo-active:not(.active) {
247
- background-color: $nav-link-pressed-bg; // #e5e7eb
254
+ background-color: $nav-link-pressed-bg;
248
255
  color: $black;
249
256
 
250
257
  &::before {
@@ -255,41 +262,38 @@ $tab-v-height-sm: map-get($spacers, 5); // 24px
255
262
  // Selected/Active State
256
263
  &.active {
257
264
  background-color: transparent;
258
- color: $nav-link-active-color; // #161616
265
+ color: $nav-link-active-color;
259
266
  font-weight: $font-weight-semibold; // 600
260
267
  position: relative;
261
268
 
262
269
  &::before {
263
- background-color: $nav-link-selection-indicator; // #1B8354 green
270
+ background-color: $nav-link-selection-indicator;
264
271
  }
265
272
 
266
273
  // When selected tab is hovered
267
274
  &:hover:not(.disabled),
268
275
  &.pseudo-hover {
269
- background-color: transparent; // No background change on hover for selected
276
+ background-color: transparent;
270
277
  }
271
278
 
272
279
  // When selected tab is pressed
273
280
  &:active:not(.disabled),
274
281
  &.pseudo-active {
275
- background-color: transparent; // No background change on press for selected
282
+ background-color: transparent;
276
283
  }
277
284
  }
278
285
 
279
286
  // Disabled State
280
- &.disabled,
281
- &:disabled {
282
- color: $nav-link-disabled-color; // #9da4ae
283
- background-color: transparent !important; // Override any hover/pressed backgrounds
287
+ &.disabled, &:disabled {
288
+ color: $nav-link-disabled-color;
289
+ background-color: transparent !important;
284
290
  pointer-events: none;
285
291
  cursor: not-allowed;
286
292
 
287
- // If disabled AND active/selected, show gray indicator instead of green
288
293
  &.active::before {
289
- background-color: $nav-link-disabled-color; // Gray indicator for disabled selected tabs
294
+ background-color: $nav-link-disabled-color;
290
295
  }
291
296
 
292
- // If disabled but NOT selected, hide indicator (transparent)
293
297
  &:not(.active)::before {
294
298
  background-color: transparent;
295
299
  }
@@ -299,37 +303,70 @@ $tab-v-height-sm: map-get($spacers, 5); // 24px
299
303
  // Size Variants - matches samples for large/medium/small
300
304
  &.nav-lg {
301
305
  .nav-link {
302
- min-height: $tab-v-height-lg; // 40px
303
- padding: map-get($spacers, 2) map-get($spacers, 2); // 8px vertical, 8px horizontal (reduced gap from indicator)
304
- font-size: $font-size-base; // 16px
306
+ height: auto !important; // Reset nav-size mixin if previously applied
307
+ min-height: $tab-v-height-lg; // 40px
308
+ padding: map-get($spacers, 2) map-get($spacers, 2) !important;
309
+ font-size: $font-size-base;
305
310
 
306
311
  &.active {
307
- font-weight: $font-weight-semibold; // 600
312
+ font-weight: $font-weight-semibold;
308
313
  }
309
314
  }
310
315
  }
311
316
 
312
317
  &.nav-md {
313
318
  .nav-link {
314
- min-height: $tab-v-height-md; // 32px
315
- padding: map-get($spacing-tokens, 'spacing-sm') map-get($spacers, 2); // 6px vertical, 8px horizontal (reduced gap from indicator)
316
- font-size: $font-size-sm; // 14px
319
+ height: auto !important;
320
+ min-height: $tab-v-height-md; // 32px
321
+ padding: map-get($spacing-tokens, 'spacing-sm') map-get($spacers, 2) !important;
322
+ font-size: $font-size-sm;
317
323
 
318
324
  &.active {
319
- font-weight: $font-weight-semibold; // 600 for selected medium tabs
325
+ font-weight: $font-weight-semibold;
320
326
  }
321
327
  }
322
328
  }
323
329
 
324
330
  &.nav-sm {
325
331
  .nav-link {
326
- min-height: $tab-v-height-sm; // 24px
327
- padding: map-get($spacing-tokens, 'spacing-xxs') map-get($spacing-tokens, 'spacing-sm'); // 2px vertical, 6px horizontal
328
- font-size: $font-size-sm; // 14px
332
+ height: auto !important;
333
+ min-height: $tab-v-height-sm; // 24px
334
+ padding: map-get($spacing-tokens, 'spacing-xxs') map-get($spacing-tokens, 'spacing-sm') !important;
335
+ font-size: $font-size-sm;
329
336
 
330
337
  &.active {
331
- font-weight: $font-weight-medium; // 500 for small tabs (from sample analysis)
338
+ font-weight: $font-weight-medium;
332
339
  }
333
340
  }
334
341
  }
342
+ }
343
+
344
+ // ============================================
345
+ // APPLY STYLES
346
+ // ============================================
347
+
348
+ .nav-tabs {
349
+ @include tabs-horizontal;
350
+ }
351
+
352
+ .nav-tabs.flex-column {
353
+ @include tabs-vertical;
354
+ }
355
+
356
+ // Responsive Loops
357
+ // Iterate over breakpoints to generate classes like .flex-md-row, .flex-lg-column
358
+ @each $breakpoint in map-keys($grid-breakpoints) {
359
+ @include media-breakpoint-up($breakpoint) {
360
+ $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
361
+
362
+ // If class is flex-*-row, use horizontal tabs
363
+ .nav-tabs.flex#{$infix}-row {
364
+ @include tabs-horizontal;
365
+ }
366
+
367
+ // If class is flex-*-column, use vertical tabs
368
+ .nav-tabs.flex#{$infix}-column {
369
+ @include tabs-vertical;
370
+ }
371
+ }
335
372
  }