@netlify/spark-ui 1.5.0-alpha.9 → 1.6.0

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.
Files changed (99) hide show
  1. package/dist/assets/SearchHeading.css +1 -1
  2. package/dist/assets/SearchLink.css +1 -1
  3. package/dist/assets/SearchModal.css +1 -1
  4. package/dist/chunks/compat.module.DJD78v1z.js +175 -0
  5. package/dist/chunks/hooks.module.D9IrxdEh.js +138 -0
  6. package/dist/chunks/{useTimeout.Cq4aqnDe.js → useTimeout.YR4eKwj7.js} +1 -1
  7. package/dist/components/index.d.ts +0 -1
  8. package/dist/components/preact/Icon/index.d.ts +2 -2
  9. package/dist/components/preact/Icon/index.js +75 -87
  10. package/dist/components/preact/Modal/Modal.js +1 -1
  11. package/dist/components/preact/SearchModal/components/SearchInput.d.ts +0 -2
  12. package/dist/components/preact/SearchModal/components/SearchInput.js +2 -2
  13. package/dist/components/preact/SearchModal/components/SearchLink/SearchLink.d.ts +1 -1
  14. package/dist/components/preact/SearchModal/components/SearchLink/SearchLink.js +17 -35
  15. package/dist/components/preact/SearchModal/components/SearchModal/SearchModal.js +49 -72
  16. package/dist/components/preact/SearchModal/components/SearchToggle/SearchToggle.js +1 -1
  17. package/dist/components/preact/SearchModal/components/SearchWindow.d.ts +1 -1
  18. package/dist/components/preact/SearchModal/components/SearchWindow.js +30 -49
  19. package/dist/components/preact/SearchModal/hooks/useKeyboardNav.js +6 -6
  20. package/dist/components/preact/SearchModal/hooks/useSearch.js +2 -2
  21. package/dist/components/preact/SearchModal/hooks/useSearchHotkeys.js +1 -1
  22. package/dist/components/preact/SearchModal/hooks/useSearchLogger.js +1 -1
  23. package/dist/components/preact/SearchModal/hooks/useSearchParams.js +1 -1
  24. package/dist/components/preact/SearchModal/hooks/useSearchToggles.d.ts +1 -3
  25. package/dist/components/preact/SearchModal/hooks/useSearchToggles.js +10 -13
  26. package/dist/components/preact/SearchModal/types/search.types.d.ts +1 -6
  27. package/dist/components/preact/index.d.ts +0 -1
  28. package/dist/components/preact/index.js +5 -7
  29. package/package.json +3 -5
  30. package/packages/assets/icons/ai.svg +22 -0
  31. package/packages/assets/icons/dev.svg +8 -0
  32. package/packages/assets/icons/ecommerce.svg +16 -0
  33. package/packages/assets/icons/marketing.svg +20 -0
  34. package/packages/components/CodeBlock.astro +4 -1
  35. package/packages/components/SectionTabbedContent.astro +185 -0
  36. package/packages/components/Switchback.astro +129 -0
  37. package/packages/components/Tab.astro +12 -0
  38. package/packages/components/TabList.astro +7 -0
  39. package/packages/components/TabPanel.astro +13 -0
  40. package/packages/components/TabPanelGroup.astro +45 -0
  41. package/packages/components/TabbedContent.astro +72 -0
  42. package/packages/components/Tabs.astro +0 -2
  43. package/packages/components/Testimonial.astro +0 -0
  44. package/packages/components/index.ts +0 -1
  45. package/packages/components/preact/Icon/index.tsx +55 -56
  46. package/packages/components/preact/SearchModal/components/SearchHeading/SearchHeading.css +4 -5
  47. package/packages/components/preact/SearchModal/components/SearchInput.tsx +7 -9
  48. package/packages/components/preact/SearchModal/components/SearchLink/SearchLink.css +9 -14
  49. package/packages/components/preact/SearchModal/components/SearchLink/SearchLink.tsx +7 -27
  50. package/packages/components/preact/SearchModal/components/SearchModal/SearchModal.css +29 -67
  51. package/packages/components/preact/SearchModal/components/SearchModal/SearchModal.tsx +30 -60
  52. package/packages/components/preact/SearchModal/components/SearchWindow.tsx +18 -32
  53. package/packages/components/preact/SearchModal/hooks/useKeyboardNav.ts +2 -2
  54. package/packages/components/preact/SearchModal/hooks/useSearchToggles.ts +3 -11
  55. package/packages/components/preact/SearchModal/types/search.types.tsx +2 -5
  56. package/packages/components/preact/index.ts +0 -1
  57. package/packages/styles/code-block.css +22 -23
  58. package/packages/styles/fonts.css +31 -2
  59. package/packages/styles/layout.css +33 -0
  60. package/packages/styles/tokens.css +22 -36
  61. package/packages/themes/poimandres.json +6 -19
  62. package/dist/assets/AskNetlify.css +0 -1
  63. package/dist/assets/Orb.css +0 -1
  64. package/dist/chunks/compat.module.BNbXPLVY.js +0 -298
  65. package/dist/chunks/hooks.module.DGkdD5n9.js +0 -177
  66. package/dist/components/preact/AskNetlify/AskNetlify.d.ts +0 -7
  67. package/dist/components/preact/AskNetlify/AskNetlify.js +0 -5774
  68. package/dist/components/preact/Orb/Orb.d.ts +0 -2
  69. package/dist/components/preact/Orb/Orb.js +0 -5
  70. package/dist/components/preact/SpriteIcon/index.d.ts +0 -7
  71. package/dist/components/preact/SpriteIcon/index.js +0 -7
  72. package/dist/components/preact/icons/AskNetlify.d.ts +0 -5
  73. package/dist/components/preact/icons/AskNetlify.js +0 -69
  74. package/dist/components/preact/icons/Book.d.ts +0 -5
  75. package/dist/components/preact/icons/Book.js +0 -23
  76. package/dist/components/preact/icons/CircleQuestion.d.ts +0 -5
  77. package/dist/components/preact/icons/CircleQuestion.js +0 -25
  78. package/dist/components/preact/icons/Comment.d.ts +0 -5
  79. package/dist/components/preact/icons/Comment.js +0 -23
  80. package/dist/components/preact/icons/Lightbulb.d.ts +0 -5
  81. package/dist/components/preact/icons/Lightbulb.js +0 -34
  82. package/dist/components/preact/icons/MagnifyingGlass.d.ts +0 -5
  83. package/dist/components/preact/icons/MagnifyingGlass.js +0 -23
  84. package/dist/utils/theme.d.ts +0 -3
  85. package/packages/assets/icons/AskNetlify.svg +0 -23
  86. package/packages/assets/icons/icons.svg +0 -10
  87. package/packages/assets/icons/lightbulb.svg +0 -4
  88. package/packages/components/preact/AskNetlify/AskNetlify.css +0 -224
  89. package/packages/components/preact/AskNetlify/AskNetlify.tsx +0 -156
  90. package/packages/components/preact/Orb/Orb.css +0 -94
  91. package/packages/components/preact/Orb/Orb.tsx +0 -7
  92. package/packages/components/preact/SpriteIcon/index.tsx +0 -13
  93. package/packages/components/preact/icons/AskNetlify.tsx +0 -46
  94. package/packages/components/preact/icons/Book.tsx +0 -20
  95. package/packages/components/preact/icons/CircleQuestion.tsx +0 -22
  96. package/packages/components/preact/icons/Comment.tsx +0 -20
  97. package/packages/components/preact/icons/Lightbulb.tsx +0 -26
  98. package/packages/components/preact/icons/MagnifyingGlass.tsx +0 -20
  99. package/packages/utils/theme.ts +0 -12
@@ -1,6 +1,6 @@
1
1
  .n-search-link {
2
- --n-search-icon-size: 1.25em;
3
- box-sizing: border-box;
2
+ --n-search-icon-size: 1em;
3
+ all: unset;
4
4
  display: flex;
5
5
  justify-content: space-between;
6
6
  flex-wrap: wrap;
@@ -11,11 +11,6 @@
11
11
  font-weight: var(--font-weight-regular);
12
12
  text-decoration: none;
13
13
  cursor: pointer;
14
- width: 100%;
15
- border: none;
16
- text-align: left;
17
- outline: none;
18
- border-radius: var(--radius-l);
19
14
  }
20
15
 
21
16
  .n-search-link-body {
@@ -25,17 +20,17 @@
25
20
  text-wrap: pretty;
26
21
  }
27
22
 
28
- .n-search-link:is(:hover, :focus-visible) {
23
+ .n-search-link:is(:hover, :focus-within) {
29
24
  background: var(--n-search-color-bg-2);
30
25
 
31
26
  & .n-search-link-icon [data-icon='caretRight'] {
32
- opacity: 1;
27
+ display: block;
33
28
  }
34
29
  }
35
30
 
36
31
  .n-search-link-title {
37
32
  font-weight: var(--font-weight-medium);
38
- color: var(--color-text-1);
33
+ color: var(--color-text);
39
34
  line-height: 1.5;
40
35
  }
41
36
 
@@ -54,8 +49,7 @@
54
49
  background-color: var(--mark-bg, var(--color-highlight));
55
50
  }
56
51
 
57
- .n-search-link-icon,
58
- .n-search-link-icon svg {
52
+ .n-search-link-icon {
59
53
  display: flex;
60
54
  width: var(--n-search-icon-size);
61
55
  height: var(--n-search-icon-size);
@@ -63,8 +57,9 @@
63
57
  }
64
58
 
65
59
  .n-search-link-icon [data-icon='caretRight'] {
66
- width: 1em;
67
- opacity: 0;
60
+ display: none;
61
+ width: 0.8em;
62
+ opacity: 0.3;
68
63
  }
69
64
 
70
65
  .n-search-link-label {
@@ -4,40 +4,20 @@ import './SearchLink.css';
4
4
 
5
5
  import Icon from '../../../Icon';
6
6
 
7
- const SearchLink = ({
8
- as: Component = 'a',
9
- icon,
10
- label,
11
- url,
12
- excerpt,
13
- resource,
14
- onClick,
15
- }: SearchLinkProps) => {
16
- const { handleClick: log } = useSearchLogger();
17
-
7
+ const SearchLink = ({ icon, label, url, excerpt, resource }: SearchLinkProps) => {
8
+ const { handleClick } = useSearchLogger()
9
+
18
10
  return (
19
- <Component
20
- className="n-search-link"
21
- href={url}
22
- onClick={(e: Event) => {
23
- onClick && onClick();
24
- log(e);
25
- }}
26
- >
11
+ <a className="n-search-link" href={url} onClick={handleClick}>
27
12
  {icon && (
28
13
  <span className="n-search-link-icon">
29
14
  <Icon name={icon} />
30
15
  </span>
31
16
  )}
32
17
  <div className="n-search-link-body">
18
+
33
19
  <p className="n-search-link-title">
34
- <span className="n-search-link-label">{label}</span>{' '}
35
- {resource && (
36
- <span className="n-search-link-badge" data-resource={resource}>
37
- {resource}
38
- </span>
39
- )}
40
- </p>
20
+ <span className="n-search-link-label">{label}</span> {resource && <span className="n-search-link-badge" data-resource={resource}>{resource}</span>}</p>
41
21
  {excerpt && (
42
22
  <p className="n-search-link-excerpt" dangerouslySetInnerHTML={{ __html: excerpt }} />
43
23
  )}
@@ -45,7 +25,7 @@ const SearchLink = ({
45
25
  <div className="n-search-link-icon">
46
26
  <Icon name="caretRight" />
47
27
  </div>
48
- </Component>
28
+ </a>
49
29
  );
50
30
  };
51
31
 
@@ -4,18 +4,15 @@
4
4
 
5
5
  /* Root Variables */
6
6
  .n-search-modal {
7
- --n-search-padding-inline: var(--space-s);
8
- --n-search-color-text: var(--color-text-1, currentColor);
9
- --n-search-color-text-secondary: var(--color-text-weaker, currentColor);
7
+ --n-search-padding-inline: 0.5em;
8
+ --n-search-color-text: var(--color-text, currentColor);
9
+ --n-search-color-text-secondary: var(--color-text-weak, currentColor);
10
10
  --n-search-color-bg: var(--search-bg-color);
11
- --n-search-color-bg-2: var(--color-bg-3);
11
+ --n-search-color-bg-2: var(--color-bg-2);
12
12
  --n-search-color-border: var(--color-bg-3);
13
- --n-search-border-radius: 1.3rem;
13
+ --n-search-border-radius: 8px;
14
14
  --n-search-max-w: 600px;
15
15
  --n-search-text-highlight: var(--search-highlight-color);
16
- --n-search-input-height: 50px;
17
- --n-search-footer-height: 40px;
18
- --n-search-container-height: 400px;
19
16
  }
20
17
 
21
18
  .n-search-modal {
@@ -24,17 +21,13 @@
24
21
  border-radius: var(--n-search-border-radius);
25
22
  width: min(var(--n-search-max-w), 100%);
26
23
  margin: auto;
27
- background: var(--n-search-color-bg);
28
- }
29
-
30
- .n-search-modal-ask {
31
- --n-search-max-w: 800px;
32
24
  }
33
25
 
34
26
  .n-search-container {
35
27
  --mark-bg: var(--n-search-text-highlight);
36
28
  display: grid;
37
29
  width: min(var(--n-search-max-w), 100%);
30
+ min-height: 470px;
38
31
  background-color: var(--n-search-color-bg);
39
32
  border-radius: var(--n-search-border-radius);
40
33
  overflow: hidden;
@@ -50,14 +43,13 @@
50
43
  }
51
44
 
52
45
  .n-search-input-wrapper {
53
- position: relative;
46
+ all: unset;
54
47
  display: flex;
55
48
  width: 100%;
56
- height: var(--n-search-input-height);
49
+ border-bottom: 1px solid var(--n-search-color-border);
57
50
  }
58
51
 
59
52
  .n-search-input {
60
- position: relative;
61
53
  display: inline-flex;
62
54
  box-sizing: border-box;
63
55
  background: var(--n-search-color-bg);
@@ -68,32 +60,16 @@
68
60
  border: none;
69
61
  outline: none;
70
62
  font-size: 1rem;
71
- color: var(--color-text-1);
72
- }
73
-
74
- .n-search-input-wrapper::after,
75
- .n-search-footer::after {
76
- content: '';
77
- display: block;
78
- width: 200%;
79
- height: 1px;
80
- background: var(--n-search-color-border);
81
- position: absolute;
82
- bottom: 0;
83
- left: 0;
63
+ color: var(--color-text);
84
64
  }
85
65
 
86
66
  .n-search-input::placeholder {
87
- color: var(--n-search-color-text-secondary);
88
- }
89
-
90
- .n-search-links {
91
- padding: var(--space-2xs);
67
+ color: var(--n-search-color-text);
92
68
  }
93
69
 
94
70
  .n-search-label {
95
71
  display: flex;
96
- padding-inline-start: var(--n-search-padding-inline);
72
+ padding-inline: var(--n-search-padding-inline);
97
73
  align-items: center;
98
74
  }
99
75
 
@@ -104,8 +80,8 @@
104
80
 
105
81
  .n-search-icon {
106
82
  display: flex;
107
- width: var(--n-search-icon-size, 1em);
108
- height: var(--n-search-icon-size, 1em);
83
+ width: var(--n-search-icon-size, 0.8em);
84
+ height: var(--n-search-icon-size, 0.8em);
109
85
  color: var(--n-search-color-text-secondary);
110
86
  }
111
87
 
@@ -116,26 +92,28 @@
116
92
 
117
93
  /* Search Results */
118
94
  .n-search-window {
119
- height: var(--n-search-container-height);
95
+ height: 400px;
120
96
  overflow-x: hidden;
121
97
  overflow-y: auto;
122
98
  overscroll-behavior: contain;
123
- scroll-padding-block: var(--space-s);
124
99
  margin-block: 0;
125
100
  background: var(--n-search-color-bg);
126
101
  }
127
102
 
103
+ .n-results-list-item {
104
+ border-bottom: 1px solid var(--color-bg-3);
105
+ }
106
+ .n-results-list-item:first-of-type {
107
+ border-top: 1px solid var(--color-bg-3);
108
+ }
109
+
128
110
  /* Footer */
129
111
  .n-search-footer {
130
- position: relative;
112
+ border-top: 1px solid var(--n-search-color-border);
113
+ padding: var(--space-2xs) var(--space-s);
114
+ background: var(--color-bg-2);
131
115
  display: flex;
132
116
  gap: var(--space-m);
133
- padding: var(--space-2xs) var(--space-s);
134
- height: var(--n-search-footer-height);
135
- }
136
-
137
- .n-search-footer::after {
138
- top: 0;
139
117
  }
140
118
 
141
119
  .n-search-footer-tip {
@@ -150,8 +128,7 @@
150
128
  .n-search-modal {
151
129
  transition:
152
130
  display 0.2s allow-discrete,
153
- overlay 0.2s allow-discrete,
154
- width 0.15s ease-in-out;
131
+ overlay 0.2s allow-discrete;
155
132
  animation: closeSearch 0.2s forwards;
156
133
  }
157
134
 
@@ -159,43 +136,28 @@
159
136
  animation: openSearch 0.2s forwards;
160
137
  }
161
138
 
162
- .n-search-modal[data-state='search'] > * {
163
- opacity: 0;
164
- animation: appearContainer 120ms ease-in-out forwards;
165
- animation-delay: 140ms;
166
- }
167
-
168
- @keyframes appearContainer {
169
- 0% {
170
- opacity: 0;
171
- }
172
- 100% {
173
- opacity: 1;
174
- }
175
- }
176
-
177
139
  @keyframes openSearch {
178
140
  from {
179
141
  opacity: 0;
180
- transform: scale(0.9);
142
+ transform: translateY(20px) scale(0.9);
181
143
  }
182
144
  to {
183
145
  opacity: 1;
184
- transform: scale(1);
146
+ transform: translateY(0px) scale(1);
185
147
  }
186
148
  }
187
149
 
188
150
  @keyframes closeSearch {
189
151
  from {
190
152
  opacity: 1;
191
- transform: scale(1);
153
+ transform: translateY(0px) scale(1);
192
154
  }
193
155
  50% {
194
156
  opacity: 0.3;
195
157
  }
196
158
  to {
197
159
  opacity: 0;
198
- transform: scale(0.9);
160
+ transform: translateY(20px) scale(0.9);
199
161
  }
200
162
  }
201
163
 
@@ -15,24 +15,20 @@ import {
15
15
  useSearchLogger,
16
16
  } from '../../hooks';
17
17
 
18
- import AskNetlify from '../../../../preact/AskNetlify/AskNetlify';
19
-
20
18
  import './SearchModal.css';
21
19
 
22
20
  interface Props {
23
21
  children: ComponentChildren;
24
22
  className?: string;
25
- debug?: boolean;
23
+ debug?: boolean
26
24
  }
27
25
 
28
- function SearchModal(props: Props = { className: '', children: null, debug: false }) {
26
+ function SearchModal(props: Props = {className: '', children: null, debug: false }) {
29
27
  const [isPagefindLoaded, setIsPagefindLoaded] = useState(false);
30
- const [modalState, setModalState] = useState({ current: 'search' });
31
- const [askNetlifyQuery, setAskNetlifyQuery] = useState('');
32
28
 
33
29
  // Poll for the existence of window.pagefind.
34
30
  useEffect(() => {
35
- let intervalId: number;
31
+ let intervalId:number;
36
32
 
37
33
  const checkForPagefind = () => {
38
34
  if (window.pagefind) {
@@ -49,18 +45,19 @@ function SearchModal(props: Props = { className: '', children: null, debug: fals
49
45
  return () => clearInterval(intervalId);
50
46
  }, []);
51
47
 
48
+
52
49
  const { children, className, debug, ...rest } = props;
53
50
  const { state, actions } = useSearch();
54
-
55
51
  const [searchOpen, setSearchOpen] = useState(false);
52
+
56
53
  const openSearch = () => setSearchOpen(true);
57
54
  const closeSearch = () => setSearchOpen(false);
58
55
 
59
56
  const modalRef = useRef<HTMLDialogElement>(null);
60
57
  const containerRef = useClickOutside<HTMLDivElement>(closeSearch);
61
58
 
62
- useSearchLogger(state, debug);
63
- useSearchToggles(isPagefindLoaded, openSearch, setModalState);
59
+ useSearchLogger(state, debug)
60
+ useSearchToggles(isPagefindLoaded, openSearch);
64
61
  useSearchParams(isPagefindLoaded, actions.setSearchTerm, openSearch);
65
62
  useSearchHotkeys(isPagefindLoaded, searchOpen, openSearch, closeSearch);
66
63
  useKeyboardNav(isPagefindLoaded, modalRef, searchOpen, closeSearch);
@@ -70,58 +67,31 @@ function SearchModal(props: Props = { className: '', children: null, debug: fals
70
67
  searchOpen ? modalRef.current.showModal() : modalRef.current.close();
71
68
  }, [searchOpen]);
72
69
 
73
- useEffect(() => {
74
- const input = modalRef.current?.querySelector('input');
75
-
76
- if (input) input.focus();
77
-
78
- if (modalState.current === 'ask') {
79
- setTimeout(() => {
80
- modalRef.current.classList.add('n-search-modal-ask');
81
- }, 150);
82
- } else if (modalState.current === 'search') {
83
- setTimeout(() => {
84
- modalRef.current.classList.remove('n-search-modal-ask');
85
- }, 150);
86
- }
87
- }, [modalState.current]);
88
-
89
70
  return (
90
- <Modal
91
- ref={modalRef}
92
- className={`n-search-modal ${className ? className : ''}`}
93
- data-state={modalState.current}
94
- {...rest}
95
- >
71
+ <Modal ref={modalRef} className={`n-search-modal ${className ? className : ''}`} {...rest}>
96
72
  <div ref={containerRef} className="n-search-container">
97
- {modalState.current === 'ask' && <AskNetlify setModalState={setModalState} />}
98
- {modalState.current === 'search' && (
99
- <>
100
- <SearchInput setSearchTerm={actions.setSearchTerm} initialValue={state.searchTerm} />
101
-
102
- <SearchWindow
103
- setModalState={setModalState}
104
- searchLoading={state.isLoading}
105
- searchTerm={state.searchTerm}
106
- results={state.results}
107
- >
108
- {children}
109
- </SearchWindow>
110
-
111
- <div className="n-search-footer">
112
- <p className="n-search-footer-tip">
113
- <KeyboardKey keyNames={['Esc']} />
114
- to close
115
- </p>
116
- <p className="n-search-footer-tip">
117
- <KeyboardKey keyNames={['Tab']} />
118
- <span>or</span>
119
- <KeyboardKey keyNames={['↑', '↓']} />
120
- to navigate
121
- </p>
122
- </div>
123
- </>
124
- )}
73
+ <SearchInput setSearchTerm={actions.setSearchTerm} initialValue={state.searchTerm} />
74
+
75
+ <SearchWindow
76
+ searchLoading={state.isLoading}
77
+ searchTerm={state.searchTerm}
78
+ results={state.results}
79
+ >
80
+ {children}
81
+ </SearchWindow>
82
+
83
+ <div className="n-search-footer">
84
+ <p className="n-search-footer-tip">
85
+ <KeyboardKey keyNames={['Esc']} />
86
+ to close
87
+ </p>
88
+ <p className="n-search-footer-tip">
89
+ <KeyboardKey keyNames={['Tab']} />
90
+ <span>or</span>
91
+ <KeyboardKey keyNames={['↑', '↓']} />
92
+ to navigate
93
+ </p>
94
+ </div>
125
95
  </div>
126
96
  </Modal>
127
97
  );
@@ -1,11 +1,9 @@
1
1
  import type { FunctionComponent } from 'preact';
2
- import type { SearchResultsProps, SearchWindowProps } from '../types/search.types';
2
+ import type { SearchLinkProps, SearchResultsProps, SearchWindowProps } from '../types/search.types';
3
3
  import { useMemo } from 'preact/hooks';
4
4
  import SearchHeading from './SearchHeading/SearchHeading';
5
5
  import SearchLink from './SearchLink/SearchLink';
6
6
 
7
- import { handleThemeChange, ThemeMap, Theme } from '../../../../utils/theme';
8
-
9
7
  /* --- Search Results Window (for active searches) --- */
10
8
  const SearchResults: FunctionComponent<SearchResultsProps> = ({
11
9
  searchLoading,
@@ -22,9 +20,9 @@ const SearchResults: FunctionComponent<SearchResultsProps> = ({
22
20
 
23
21
  if (!results || results.length === 0) {
24
22
  return (
25
- <SearchHeading>
26
- 0 results for <span className="n-search-term">{searchTerm}</span>
27
- </SearchHeading>
23
+ <SearchHeading>
24
+ 0 results for <span className="n-search-term">{searchTerm}</span>
25
+ </SearchHeading>
28
26
  );
29
27
  }
30
28
 
@@ -45,41 +43,29 @@ const SearchResults: FunctionComponent<SearchResultsProps> = ({
45
43
 
46
44
  /* --- Main Search Results Component --- */
47
45
  export default function SearchWindow({
48
- setModalState,
49
46
  searchLoading,
50
47
  searchTerm,
51
48
  results,
52
49
  children: DefaultWindow,
53
50
  }: SearchWindowProps) {
51
+ const askNetlify: SearchLinkProps = {
52
+ icon: 'sparkles',
53
+ label: 'Ask Netlify AI',
54
+ url: 'https://docs.netlify.com/ask-netlify/',
55
+ };
56
+
54
57
  return (
55
58
  <div className="n-search-window">
56
- <div className="n-search-links">
59
+ <div className="search-links">
60
+ <SearchLink {...askNetlify} />
57
61
  {searchTerm && searchTerm.length > 1 ? (
58
- <SearchResults searchLoading={searchLoading} searchTerm={searchTerm} results={results} />
62
+ <SearchResults
63
+ searchLoading={searchLoading}
64
+ searchTerm={searchTerm}
65
+ results={results}
66
+ />
59
67
  ) : DefaultWindow ? (
60
- <>
61
- <SearchLink
62
- as="button"
63
- icon="askNetlify"
64
- label="Ask Netlify AI"
65
- onClick={() => {
66
- setModalState({ current: 'ask' });
67
- }}
68
- />
69
-
70
- {DefaultWindow}
71
-
72
- <SearchHeading>Actions</SearchHeading>
73
- <SearchLink
74
- as="button"
75
- icon="lightbulb"
76
- label="Toggle theme"
77
- onClick={() => {
78
- const theme = document.documentElement.getAttribute('data-theme') as Theme;
79
- theme && handleThemeChange(ThemeMap[theme]);
80
- }}
81
- />
82
- </>
68
+ DefaultWindow
83
69
  ) : null}
84
70
  </div>
85
71
  </div>
@@ -21,7 +21,7 @@ export function useKeyboardNav(
21
21
  onClose: () => void
22
22
  ) {
23
23
  useEffect(() => {
24
- if (!isPagefindLoaded) return;
24
+ if (!isPagefindLoaded) return
25
25
  const handleKeydown = (e: KeyboardEvent) => {
26
26
  if (!isOpen) return;
27
27
 
@@ -35,7 +35,7 @@ export function useKeyboardNav(
35
35
  const container = containerRef.current;
36
36
  if (!container) return;
37
37
 
38
- const links = Array.from(container.querySelectorAll('.n-search-link'));
38
+ const links = Array.from(container.querySelectorAll('a'));
39
39
  const currentIndex = links.findIndex(link => link === document.activeElement);
40
40
  const nextIndex =
41
41
  e.key === 'ArrowDown'
@@ -12,24 +12,16 @@ import { useEffect } from 'preact/hooks';
12
12
  * @param onOpen - A function to be called when a toggle element is clicked.
13
13
  */
14
14
 
15
- export function useSearchToggles(
16
- isPagefindLoaded: boolean,
17
- onOpen: () => void,
18
- setState: (state: { current: string }) => void
19
- ) {
15
+ export function useSearchToggles(isPagefindLoaded: boolean, onOpen: () => void) {
20
16
  useEffect(() => {
21
- if (!isPagefindLoaded) return;
17
+ if (!isPagefindLoaded) return
22
18
  const toggles = document.querySelectorAll('[data-ntl-search-toggle]');
23
19
 
24
20
  if (!toggles.length) return;
25
21
 
26
22
  toggles.forEach(t => {
27
- const current = t.dataset.ntlSearchToggle ? t.dataset.ntlSearchToggle : 'search';
28
23
  t.removeAttribute('disabled');
29
- t.addEventListener('click', () => {
30
- onOpen();
31
- setState({ current });
32
- });
24
+ t.addEventListener('click', onOpen);
33
25
  });
34
26
 
35
27
  return () => {
@@ -2,17 +2,14 @@ import type { ComponentChildren } from 'preact';
2
2
  import type { IconName } from '../../Icon';
3
3
 
4
4
  export interface SearchLinkProps {
5
- as?: any;
6
5
  icon: IconName;
7
6
  label: string;
8
7
  resource?: 'blog' | 'changelog' | 'docs' | 'guide';
9
- url?: string;
8
+ url: string;
10
9
  excerpt?: string;
11
- onClick?: () => void;
12
10
  }
13
11
 
14
12
  export interface SearchWindowProps {
15
- setModalState: (e: { current: string }) => void;
16
13
  searchLoading: boolean;
17
14
  searchTerm?: string;
18
15
  results?: SearchLinkProps[];
@@ -36,4 +33,4 @@ export interface SearchGTMObjectProps {
36
33
  resultUrl?: string;
37
34
  query?: string;
38
35
  debug_mode?: boolean;
39
- }
36
+ }
@@ -4,7 +4,6 @@ export { default as Icon } from './Icon';
4
4
  export { default as SearchLink } from './SearchModal/components/SearchLink/SearchLink';
5
5
  export { default as SearchHeading } from './SearchModal/components/SearchHeading/SearchHeading';
6
6
  export { default as SearchToggle } from './SearchModal/components/SearchToggle/SearchToggle';
7
- export { default as AskNetlify } from "./AskNetlify/AskNetlify"
8
7
  export { SearchModal } from './SearchModal';
9
8
 
10
9
  export { type IconName } from './Icon';