sdga-ui 1.0.16 → 1.0.17

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.16",
3
+ "version": "1.0.17",
4
4
  "description": "DGA UI - Government-Style Bootstrap Theme",
5
5
  "keywords": [
6
6
  "sdga",
@@ -41,6 +41,7 @@
41
41
  @import 'components/tooltips';
42
42
  @import 'components/popovers';
43
43
  @import 'components/offcanvas';
44
+ @import 'components/navs';
44
45
  @import 'components/pagination';
45
46
  @import 'components/breadcrumb';
46
47
  @import 'components/list-group';
@@ -0,0 +1,35 @@
1
+ // Bootstrap 5.3 - Navs & Tabs Variables
2
+
3
+ // ============================================
4
+ // NAVS
5
+ // ============================================
6
+
7
+ $nav-link-padding-y: .5rem;
8
+ $nav-link-padding-x: 1rem;
9
+ $nav-link-font-size: null;
10
+ $nav-link-font-weight: null;
11
+ $nav-link-color: var(--#{$prefix}primary);
12
+ $nav-link-hover-color: var(--#{$prefix}primary-emphasis);
13
+ $nav-link-transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out;
14
+ $nav-link-disabled-color: var(--#{$prefix}secondary-color);
15
+ $nav-link-focus-box-shadow: $focus-ring-box-shadow;
16
+
17
+ // ============================================
18
+ // TABS
19
+ // ============================================
20
+
21
+ $nav-tabs-border-width: 1px;
22
+ $nav-tabs-border-color: var(--#{$prefix}border-color);
23
+ $nav-tabs-border-radius: $radius-sm;
24
+ $nav-tabs-link-hover-border-color: var(--#{$prefix}secondary-bg) var(--#{$prefix}secondary-bg) $nav-tabs-border-color;
25
+ $nav-tabs-link-active-color: var(--#{$prefix}emphasis-color);
26
+ $nav-tabs-link-active-bg: var(--#{$prefix}body-bg);
27
+ $nav-tabs-link-active-border-color: var(--#{$prefix}border-color) var(--#{$prefix}border-color) $nav-tabs-link-active-bg;
28
+
29
+ // ============================================
30
+ // PILLS
31
+ // ============================================
32
+
33
+ $nav-pills-border-radius: $radius-sm;
34
+ $nav-pills-link-active-color: $component-active-color;
35
+ $nav-pills-link-active-bg: $component-active-bg;
@@ -0,0 +1,86 @@
1
+ // Navs & Tabs Customizations
2
+
3
+ .navbar {
4
+ .nav-tabs {
5
+ --#{$prefix}nav-tabs-link-active-color: #{$primary-700};
6
+ --#{$prefix}nav-tabs-link-active-bg: #{$white};
7
+ --#{$prefix}nav-tabs-link-active-border-color: #{$gray-200} #{$gray-200} #{$white};
8
+ border-bottom: 1px solid #{$gray-200};
9
+
10
+ .nav-link {
11
+ font-weight: 500;
12
+ color: #{$gray-600};
13
+ border: 1px solid transparent;
14
+ border-top-left-radius: $radius-sm;
15
+ border-top-right-radius: $radius-sm;
16
+ margin-bottom: -1px;
17
+ padding: 0.75rem 1rem;
18
+
19
+ &:hover {
20
+ color: #{$primary-600};
21
+ background-color: #{$gray-50};
22
+ border-color: #{$gray-200} #{$gray-200} #{$gray-200};
23
+ }
24
+
25
+ &.active {
26
+ color: #{$primary-700};
27
+ background-color: #{$white};
28
+ border-color: #{$gray-200} #{$gray-200} transparent;
29
+ }
30
+
31
+ &.disabled {
32
+ color: #{$gray-400};
33
+ }
34
+ }
35
+ }
36
+
37
+ .nav-pills {
38
+ .nav-link {
39
+ font-weight: 500;
40
+ color: #{$gray-600};
41
+ border-radius: $radius-md;
42
+ padding: 0.5rem 1rem;
43
+
44
+ &.active {
45
+ background-color: #{$primary-600};
46
+ color: #{$white};
47
+ }
48
+
49
+ &:hover:not(.active) {
50
+ background-color: #{$gray-100};
51
+ color: #{$gray-900};
52
+ }
53
+ }
54
+ }
55
+
56
+ // Vertical tabs customization
57
+ .flex-column.nav-tabs {
58
+ border-bottom: 0;
59
+ border-inline-end: 1px solid #{$gray-200};
60
+
61
+ .nav-link {
62
+ border-radius: $radius-sm 0 0 $radius-sm;
63
+ margin-bottom: 0;
64
+ margin-inline-end: -1px;
65
+
66
+ &.active {
67
+ border-color: #{$gray-200} transparent #{$gray-200} #{$gray-200};
68
+ }
69
+ }
70
+
71
+ [dir="rtl"] & {
72
+ border-inline-end: 0;
73
+ border-inline-start: 1px solid #{$gray-200};
74
+
75
+ .nav-link {
76
+ border-radius: 0 $radius-sm $radius-sm 0;
77
+ margin-inline-end: 0;
78
+ margin-inline-start: -1px;
79
+
80
+ &.active {
81
+ border-color: #{$gray-200} #{$gray-200} #{$gray-200} transparent;
82
+ }
83
+ }
84
+ }
85
+ }
86
+ }
@@ -0,0 +1,344 @@
1
+ // Tabs Customizations (Strict Separation from Navs)
2
+
3
+ // Using SDGA Variables directly
4
+ // #161616 -> $black
5
+ // #384250 -> $gray-700
6
+ // #9DA4AE -> $gray-400
7
+ // #F3F4F6 -> $gray-100
8
+ // #E5E7EB -> $gray-200
9
+ // #D2D6DB -> $gray-300
10
+ // #1B8354 -> $sa-600 (Selection indicator color from samples)
11
+ // Radius: 4px -> $radius-sm
12
+
13
+ $nav-tabs-border-color: $gray-300;
14
+ $nav-link-color: $gray-700;
15
+ $nav-link-hover-bg: $gray-100;
16
+ $nav-link-active-color: $black;
17
+ $nav-link-disabled-color: $gray-400;
18
+ $nav-link-pressed-bg: $gray-200;
19
+ $nav-link-selection-indicator: $sa-600; // Green from samples
20
+ $nav-link-selection-indicator-default: $black; // Green from samples
21
+
22
+ // Spacing Variables mapped from HTML static values
23
+ // 52px = 3.25rem (Custom) or close to spacer 8 (48px) - keeping calculation
24
+ $tab-height-lg: 3.25rem;
25
+ $tab-height-md: 2.75rem; // 44px
26
+ $tab-height-sm: 2.25rem; // 36px
27
+
28
+ $tab-v-height-lg: map-get($spacers, 7); // 40px
29
+ $tab-v-height-md: map-get($spacers, 6); // 32px
30
+ $tab-v-height-sm: map-get($spacers, 5); // 24px
31
+
32
+ // Sizes Mixin
33
+ @mixin nav-size($height, $padding-y, $padding-x, $font-size) {
34
+ .nav-link {
35
+ height: $height !important;
36
+ padding: $padding-y $padding-x !important;
37
+ font-size: $font-size;
38
+ display: flex;
39
+ align-items: center;
40
+ justify-content: center;
41
+ gap: map-get($spacers, 1); // 4px
42
+ }
43
+ }
44
+
45
+ .nav-tabs {
46
+ --#{$prefix}nav-tabs-border-width: 0;
47
+ --#{$prefix}nav-tabs-border-radius: 0;
48
+ --#{$prefix}nav-tabs-link-active-bg: transparent;
49
+
50
+ position: relative; // Establish positioning context
51
+ border-bottom: 3px solid transparent; // Maintain space but make transparent
52
+ gap: map-get($spacers, 2); // 8px
53
+
54
+ // Rounded bottom border line
55
+ &::before {
56
+ content: '';
57
+ position: absolute;
58
+ left: 0;
59
+ bottom: -3px; // Align with the transparent border
60
+ width: 100%;
61
+ height: 3px;
62
+ background-color: $nav-tabs-border-color;
63
+ border-radius: $radius-full; // Rounded ends
64
+ pointer-events: none; // Prevent interference with clicks/hover
65
+ }
66
+
67
+ .nav-link {
68
+ font-family: $font-family-base;
69
+ font-weight: $font-weight-base; // 400
70
+ color: $nav-link-color;
71
+ border: none;
72
+ border-radius: $radius-sm;
73
+ position: relative;
74
+ transition: all 0.2s ease;
75
+ display: flex;
76
+ align-items: center;
77
+ gap: map-get($spacers, 1); // 4px gap between icon and text (from sample)
78
+
79
+ // Hover State & Pseudo-Hover (exclude active tabs)
80
+ &:hover:not(.disabled):not(.active),
81
+ &.pseudo-hover:not(.active) {
82
+ background-color: $nav-link-hover-bg;
83
+ color: $nav-link-color;
84
+ }
85
+
86
+ // Pressed State & Pseudo-Active (exclude active tabs)
87
+ &:active:not(.disabled):not(.active),
88
+ &.pseudo-active:not(.active) {
89
+ background-color: $nav-link-pressed-bg;
90
+ }
91
+
92
+ // Active State
93
+ &.active {
94
+ color: $nav-link-active-color;
95
+ font-weight: $font-weight-bold; // 700
96
+ background-color: transparent;
97
+ }
98
+
99
+ // Disabled State
100
+ &.disabled {
101
+ color: $nav-link-disabled-color;
102
+ background-color: transparent;
103
+ pointer-events: none;
104
+ cursor: not-allowed;
105
+ }
106
+ }
107
+ }
108
+
109
+ // ============================================
110
+ // HORIZONTAL TABS - ACTIVE INDICATOR
111
+ // ============================================
112
+ // Bottom underline indicator for horizontal tabs only
113
+ // Bumped specificity to override _nav.scss
114
+ .nav-tabs.nav-tabs:not(.flex-column) .nav-link {
115
+
116
+ // Active indicator as ::before pseudo-element (bottom underline)
117
+ // Changed from ::after to avoid conflict with dropdown caret
118
+ &::before {
119
+ content: '';
120
+ position: absolute;
121
+ left: map-get($spacers, 4); // 16px from left
122
+ right: map-get($spacers, 4); // 16px from right
123
+ bottom: 0;
124
+ height: 3px;
125
+ background-color: transparent;
126
+ border-radius: $radius-full; // Rounded ends
127
+ z-index: 1; // Ensure it sits on top of the border
128
+ transition: background-color 0.2s ease; // Smooth transition
129
+ margin-bottom: -2.75px;
130
+ }
131
+
132
+ // Flush variant (no left/right gap for indicator)
133
+ @at-root .nav-tabs.nav-tabs.flush .nav-link::before {
134
+ left: 0;
135
+ right: 0;
136
+ }
137
+
138
+ &.active::before {
139
+ background-color: $nav-link-selection-indicator; // #1B8354 green
140
+ }
141
+
142
+ // Hover & Pressed state for non-active, non-disabled tabs
143
+ &:hover:not(.active):not(.disabled)::before,
144
+ &.pseudo-hover:not(.active):not(.disabled)::before,
145
+ &:active:not(.active):not(.disabled)::before,
146
+ &.pseudo-active:not(.active):not(.disabled)::before {
147
+ background-color: $nav-link-selection-indicator-default;
148
+ }
149
+
150
+ // If disabled AND active, show gray indicator
151
+ &.disabled.active::before {
152
+ background-color: $nav-link-disabled-color; // Gray indicator for disabled selected tabs
153
+ }
154
+ }
155
+
156
+ // ============================================
157
+ // HORIZONTAL TABS - SIZES
158
+ // ============================================
159
+ // Bumped specificity to override _nav.scss
160
+ .nav-tabs.nav-tabs:not(.flex-column) {
161
+
162
+ // Sizes
163
+ &.nav-lg {
164
+ @include nav-size($tab-height-lg, map-get($spacers, 4), map-get($spacers, 4), $font-size-sm); // 16px padding, 14px font
165
+ }
166
+
167
+ &.nav-md {
168
+ @include nav-size($tab-height-md, map-get($spacers, 3), map-get($spacers, 4), $font-size-sm); // 12px padding, 14px font
169
+ }
170
+
171
+ &.nav-sm {
172
+ @include nav-size($tab-height-sm, map-get($spacers, 2), map-get($spacers, 3), $font-size-sm); // 8px padding, 12px padding, 14px font
173
+ }
174
+ }
175
+
176
+ // Vertical Tabs Customization
177
+ // Based on samples in: c:\Users\amro_\source\repos\dga-ui\samples\vertical tabs
178
+ // Applies ONLY to vertical tabs (.nav.flex-column.nav-tabs), not horizontal tabs
179
+ .nav.flex-column.nav-tabs {
180
+ border-bottom: 0;
181
+ &::before {
182
+ display: none; // Hide the rounded horizontal border
183
+ }
184
+ border-right: 0;
185
+ gap: 0;
186
+
187
+ .nav-link {
188
+ width: 100%;
189
+ justify-content: flex-start;
190
+ border: none; // Remove all default button/link borders
191
+ border-bottom: none;
192
+ border-radius: $radius-sm;
193
+ margin-bottom: map-get($spacers, 1); // 4px
194
+ font-weight: $font-weight-base; // 400 (default from samples)
195
+ color: $nav-link-color; // #384250 default
196
+ position: relative; // For ::before positioning
197
+ display: flex;
198
+ align-items: center; // Vertically center content
199
+ gap: map-get($spacers, 2); // 8px gap between icon and text
200
+
201
+ // Enable indicator rendering but keep transparent by default
202
+ &::before {
203
+ content: '';
204
+ position: absolute;
205
+ left: 0;
206
+ top: map-get($spacers, 2); // 8px from top
207
+ bottom: map-get($spacers, 2); // 8px from bottom
208
+ width: 3px;
209
+ background-color: transparent;
210
+ border-radius: $radius-full; // rounded ends like in samples
211
+ transition: background-color 0.2s ease;
212
+ }
213
+
214
+ // Ensure icon is vertically centered
215
+ i,
216
+ img,
217
+ svg {
218
+ display: inline-flex;
219
+ align-items: center;
220
+ justify-content: center;
221
+ }
222
+
223
+ // Remove default button outline for buttons used as nav-links
224
+ &:focus,
225
+ &:focus-visible {
226
+ outline: none; // Remove browser default outline
227
+ border: none;
228
+ }
229
+
230
+ // Hover State for non-active
231
+ &:hover:not(.disabled):not(.active),
232
+ &.pseudo-hover:not(.active) {
233
+ background-color: $nav-link-hover-bg; // #f3f4f6
234
+ color: $nav-link-color; // No color change on hover
235
+
236
+ &::before {
237
+ background-color: $nav-link-selection-indicator-default;
238
+ }
239
+ }
240
+
241
+ // Pressed State
242
+ &:active:not(.disabled):not(.active),
243
+ &.pseudo-active:not(.active) {
244
+ background-color: $nav-link-pressed-bg; // #e5e7eb
245
+ color: $black;
246
+
247
+ &::before {
248
+ background-color: $nav-link-selection-indicator-default;
249
+ }
250
+ }
251
+
252
+ // Selected/Active State
253
+ &.active {
254
+ background-color: transparent;
255
+ color: $nav-link-active-color; // #161616
256
+ font-weight: $font-weight-semibold; // 600
257
+ position: relative;
258
+
259
+ &::before {
260
+ background-color: $nav-link-selection-indicator; // #1B8354 green
261
+ }
262
+
263
+ // When selected tab is hovered
264
+ &:hover:not(.disabled),
265
+ &.pseudo-hover {
266
+ background-color: transparent; // No background change on hover for selected
267
+ }
268
+
269
+ // When selected tab is pressed
270
+ &:active:not(.disabled),
271
+ &.pseudo-active {
272
+ background-color: transparent; // No background change on press for selected
273
+ }
274
+ }
275
+
276
+ // Disabled State
277
+ &.disabled,
278
+ &:disabled {
279
+ color: $nav-link-disabled-color; // #9da4ae
280
+ background-color: transparent !important; // Override any hover/pressed backgrounds
281
+ pointer-events: none;
282
+ cursor: not-allowed;
283
+
284
+ // If disabled AND active/selected, show gray indicator instead of green
285
+ &.active::before {
286
+ background-color: $nav-link-disabled-color; // Gray indicator for disabled selected tabs
287
+ }
288
+
289
+ // If disabled but NOT selected, hide indicator (transparent)
290
+ &:not(.active)::before {
291
+ background-color: transparent;
292
+ }
293
+ }
294
+ }
295
+
296
+ // Size Variants - matches samples for large/medium/small
297
+ &.nav-lg {
298
+ .nav-link {
299
+ min-height: $tab-v-height-lg; // 40px
300
+ padding: map-get($spacers, 2) map-get($spacers, 2); // 8px vertical, 8px horizontal (reduced gap from indicator)
301
+ font-size: $font-size-base; // 16px
302
+
303
+ &.active {
304
+ font-weight: $font-weight-semibold; // 600
305
+ }
306
+ }
307
+ }
308
+
309
+ &.nav-md {
310
+ .nav-link {
311
+ min-height: $tab-v-height-md; // 32px
312
+ padding: map-get($spacing-tokens, 'spacing-sm') map-get($spacers, 2); // 6px vertical, 8px horizontal (reduced gap from indicator)
313
+ font-size: $font-size-sm; // 14px
314
+
315
+ &.active {
316
+ font-weight: $font-weight-semibold; // 600 for selected medium tabs
317
+ }
318
+ }
319
+ }
320
+
321
+ &.nav-sm {
322
+ .nav-link {
323
+ min-height: $tab-v-height-sm; // 24px
324
+ padding: map-get($spacing-tokens, 'spacing-xxs') map-get($spacing-tokens, 'spacing-sm'); // 2px vertical, 6px horizontal
325
+ font-size: $font-size-sm; // 14px
326
+
327
+ &.active {
328
+ font-weight: $font-weight-medium; // 500 for small tabs (from sample analysis)
329
+ }
330
+ }
331
+ }
332
+
333
+ // RTL Support
334
+ [dir="rtl"] & {
335
+ .nav-link {
336
+ &.active {
337
+ &::before {
338
+ left: auto;
339
+ right: 0;
340
+ }
341
+ }
342
+ }
343
+ }
344
+ }
package/theme/dga-ui.scss CHANGED
@@ -28,6 +28,8 @@
28
28
  @import './customizations/tables';
29
29
  @import './customizations/footer';
30
30
  @import './customizations/navbar';
31
+ @import './customizations/navs';
32
+ @import './customizations/tabs';
31
33
  @import './customizations/progress-indicator';
32
34
  @import './customizations/breadcrumb';
33
35
  @import './customizations/custom-styles';