@gsa-tts/graymatter-ui 0.4.7 → 0.4.8

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": "@gsa-tts/graymatter-ui",
3
- "version": "0.4.7",
3
+ "version": "0.4.8",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -62,8 +62,8 @@
62
62
  "vite": "^6.3.5",
63
63
  "vitest": "^3.0.7",
64
64
  "@gsa-tts/graymatter-typescript-config": "0.0.2",
65
- "@gsa-tts/graymatter-eslint": "0.0.2",
66
- "@gsa-tts/graymatter-vitest-config": "0.0.1"
65
+ "@gsa-tts/graymatter-vitest-config": "0.0.1",
66
+ "@gsa-tts/graymatter-eslint": "0.0.2"
67
67
  },
68
68
  "dependencies": {
69
69
  "@fontsource-variable/archivo": "^5.2.6",
@@ -11,15 +11,17 @@
11
11
  selectedItem,
12
12
  isMenuButtonDisabled,
13
13
  navigationStore,
14
+ selectedSubNavItemId,
14
15
  type NavigationItem,
15
16
  } from '../stores/navigationStore.js';
17
+ import { get } from 'svelte/store';
16
18
  import DiscoverIcon from './icons/DiscoverIcon.svelte';
17
19
  import ChatIcon from './icons/ChatIcon.svelte';
18
20
  import ConsoleIcon from './icons/ConsoleIcon.svelte';
19
21
  import ApiIcon from './icons/ApiIcon.svelte';
20
22
  import MenuIcon from './icons/MenuIcon.svelte';
21
23
  import ProfileMenu from './ProfileMenu.svelte';
22
- // import HelpIcon from './icons/HelpIcon.svelte';
24
+ import HelpIcon from './icons/HelpIcon.svelte';
23
25
 
24
26
  const {
25
27
  ssrSelectedItem = undefined,
@@ -32,6 +34,7 @@
32
34
  chatUrl,
33
35
  consoleUrl,
34
36
  discoverUrl,
37
+ supplementalMenuData,
35
38
  } = $props();
36
39
 
37
40
  let hydrated = false;
@@ -39,7 +42,6 @@
39
42
  let hoveredItem = $state<string | null>(null);
40
43
  let menuButtonHovered = $state(false);
41
44
  let canHover = $state(false);
42
- // let helpIconHovered = $state(false);
43
45
  let discoverNavRef = $state<HTMLAnchorElement | null>(null);
44
46
  let chatNavRef = $state<HTMLAnchorElement | null>(null);
45
47
  let consoleNavRef = $state<HTMLAnchorElement | null>(null);
@@ -92,6 +94,7 @@
92
94
  if (navContainer) {
93
95
  navContainer.classList.add('hydrated');
94
96
  }
97
+
95
98
  // Detect if device supports hover (desktop only)
96
99
  if (typeof window !== 'undefined') {
97
100
  const mq = window.matchMedia('(hover: hover)');
@@ -425,23 +428,24 @@
425
428
 
426
429
  {#if profileMenuData}
427
430
  <div class="nav-footer" part="nav-footer">
428
- <!-- TODO: Add help icon back in when we have decided on full functionality-->
429
- <!-- <div class="nav-footer-icon-container">
430
- <button
431
- type="button"
432
- class="nav-footer-icon-inner"
433
- tabindex="0"
434
- aria-label="Help"
435
- onmouseenter={() => (helpIconHovered = true)}
436
- onmouseleave={() => (helpIconHovered = false)}
437
- onfocus={() => (helpIconHovered = true)}
438
- onblur={() => (helpIconHovered = false)}
439
- >
440
- <div class="nav-footer-icon-svg-wrapper">
441
- <HelpIcon isHovered={helpIconHovered} />
431
+ {#if supplementalMenuData?.help?.url}
432
+ <div
433
+ class="nav-footer-icon-container"
434
+ part="nav-footer-icon-container"
435
+ >
436
+ <a
437
+ class="help-link"
438
+ class:selected={get(selectedSubNavItemId) === 'help'}
439
+ aria-current={get(selectedSubNavItemId) === 'help'}
440
+ href={supplementalMenuData.help.url}
441
+ part="help-link"
442
+ title="Help"
443
+ aria-label="Help"
444
+ >
445
+ <HelpIcon />
446
+ </a>
442
447
  </div>
443
- </button>
444
- </div> -->
448
+ {/if}
445
449
  <div class="nav-footer-profile-container">
446
450
  <ProfileMenu
447
451
  userMeta={profileMenuData?.userMeta}
@@ -742,15 +746,13 @@
742
746
  color: var(--ai-color-neutral-700);
743
747
  }
744
748
 
745
- /* .nav-footer-icon-container {
749
+ .nav-footer-icon-container {
750
+ align-items: center;
746
751
  display: flex;
747
- padding: 0 var(--ai-size-4);
748
752
  flex-direction: column;
749
753
  justify-content: center;
750
- align-items: center;
751
- gap: var(--ai-size-4);
752
- align-self: stretch;
753
- } */
754
+ margin-block-end: var(--ai-size-4);
755
+ }
754
756
 
755
757
  .nav-footer-profile-container {
756
758
  display: flex;
@@ -761,38 +763,22 @@
761
763
  gap: var(--ai-size-4);
762
764
  align-self: stretch;
763
765
  }
764
- /* .nav-footer-icon-inner {
765
- display: flex;
766
- width: var(--ai-size-40);
767
- height: var(--ai-size-40);
768
- padding: var(--ai-size-8);
769
- justify-content: center;
770
- align-items: center;
771
- border-radius: var(--ai-size-4);
772
- background: none;
773
- border: none;
774
- cursor: pointer;
775
- transition: background-color var(--ai-transition-ease-medium), border-radius var(--ai-transition-ease-medium);
776
- } */
777
- /* .nav-footer-icon-inner:hover,
778
- .nav-footer-icon-inner:focus {
779
- background-color: var(--ai-color-steel-300);
766
+
767
+ .help-link {
780
768
  border-radius: var(--ai-size-4);
769
+ padding: var(--ai-size-4);
770
+ transition: background-color var(--ai-transition-ease-medium);
781
771
  }
782
- .nav-footer-icon-inner:focus {
783
- outline: none;
772
+
773
+ .help-link :global(svg) {
774
+ display: block;
784
775
  }
785
- .nav-footer-icon-inner:focus-visible {
786
- outline: var(--ai-size-2) solid var(--ai-color-blue-600);
787
- outline-offset: var(--ai-size-2);
788
- border-radius: var(--ai-size-4);
776
+
777
+ .help-link:hover {
778
+ background: var(--ai-color-steel-300);
779
+ }
780
+
781
+ .help-link:is(.selected) {
782
+ background-color: var(--ai-color-steel-300);
789
783
  }
790
- .nav-footer-icon-svg-wrapper {
791
- width: var(--ai-size-24);
792
- height: var(--ai-size-24);
793
- flex-shrink: 0;
794
- display: flex;
795
- align-items: center;
796
- justify-content: center;
797
- } */
798
784
  </style>
@@ -19,6 +19,7 @@
19
19
  chatUrl,
20
20
  consoleUrl,
21
21
  discoverUrl,
22
+ supplementalMenuData,
22
23
  } = $props();
23
24
  </script>
24
25
 
@@ -33,6 +34,7 @@
33
34
  {chatUrl}
34
35
  {consoleUrl}
35
36
  {discoverUrl}
37
+ {supplementalMenuData}
36
38
  >
37
39
  <slot />
38
40
  </DesktopSideNav>
@@ -16,12 +16,14 @@ const {
16
16
  gtmID,
17
17
  showAppIcons = true,
18
18
  profileMenuData = undefined,
19
+ supplementalMenuData = undefined,
19
20
  logoLinkUrl,
20
21
  logoLinkLabel,
21
22
  title: pageTitle,
22
23
  description,
23
24
  openGraphImage,
24
25
  hideDiscover = true,
26
+ className = '',
25
27
  } = Astro.props;
26
28
 
27
29
  // Use getSecret directly for better environment variable handling
@@ -33,13 +35,13 @@ const discoverUrl =
33
35
  getSecret('DISCOVER_URL') || getSecret('PUBLIC_DISCOVER_URL');
34
36
 
35
37
  const chat = chatUrl || '#';
36
- const console = consoleUrl || '#';
38
+ const consoleApp = consoleUrl || '#';
37
39
  const api = apiDocsUrl || '#';
38
40
  const discover = discoverUrl || '#';
39
41
  ---
40
42
 
41
43
  <BaseLayout title={pageTitle} {gtmID} {description} {openGraphImage}>
42
- <div class="app">
44
+ <div class={`app ${className}`}>
43
45
  <!-- Desktop Navigation -->
44
46
  <div class="layout-container">
45
47
  <nav aria-label="Main navigation">
@@ -51,8 +53,9 @@ const discover = discoverUrl || '#';
51
53
  profileMenuData={profileMenuData}
52
54
  apiUrl={api}
53
55
  chatUrl={chat}
54
- consoleUrl={console}
56
+ consoleUrl={consoleApp}
55
57
  discoverUrl={discover}
58
+ {supplementalMenuData}
56
59
  >
57
60
  <slot name="sub-nav" />
58
61
  </DesktopSideNav>
@@ -6,6 +6,7 @@ export function setupCommonMocks() {
6
6
  vi.mock('../stores/navigationStore.js', () => {
7
7
  const isExpanded = writable(true);
8
8
  const selectedItem = writable('console');
9
+ const selectedSubNavItemId = writable('');
9
10
  const selectedSubNavItemTitle = writable('');
10
11
 
11
12
  const isMenuButtonDisabled = derived(
@@ -17,6 +18,7 @@ export function setupCommonMocks() {
17
18
  isExpanded,
18
19
  selectedItem,
19
20
  isMenuButtonDisabled,
21
+ selectedSubNavItemId,
20
22
  selectedSubNavItemTitle,
21
23
  navigationStore: {
22
24
  setSelectedItem: vi.fn(),