@stackql/docusaurus-plugin-aeo 0.3.0 → 0.4.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.1
4
+
5
+ Cosmetic patch. No API, option-shape, behavior, or placement changes.
6
+
7
+ ### Changed
8
+
9
+ - Provider icons swapped from [simple-icons](https://simpleicons.org) (monochrome) to [@lobehub/icons](https://github.com/lobehub/lobe-icons) (colored brand variants). Resolves the ChatGPT-fallback-glyph issue from v0.3.0-v0.4.0: Claude, Perplexity, and Gemini now render in their brand colors via lobehub's `.Color` variants, and ChatGPT renders the OpenAI mark tinted with ChatGPT green (lobehub does not ship a `.Color` variant for OpenAI as of 5.10.0, so the monochrome mark is tinted inline).
10
+ - `ListItemIcon` now uses `sx={{ minWidth: 32, color: 'inherit' }}` so MUI's default tint does not override the brand colors.
11
+
12
+ ### Removed
13
+
14
+ - `simple-icons` dependency.
15
+
16
+ ### Added
17
+
18
+ - `@lobehub/icons` (`^5.10.0`, MIT) as a runtime dependency.
19
+
20
+ ## 0.4.0
21
+
22
+ Visual refresh of the Ask AI button (feature 3) to match the look-and-feel of MUI-based dropdown components used elsewhere on consumer sites. No changes to features 1, 2, or 4.
23
+
24
+ ### Changed (breaking)
25
+
26
+ - `@mui/material`, `@mui/icons-material`, `@emotion/react`, `@emotion/styled` are now required peer dependencies when `askAi.enabled` is `true`. Consumers that already use MUI (common in Docusaurus sites) get a single deduped copy at install time; consumers without MUI will get a clean npm peer-dependency install error pointing at exactly what to install. Consumers who disable the button (`askAi.enabled: false`) can skip these - the theme components are not registered and MUI is never imported.
27
+
28
+ ### Changed
29
+
30
+ - Ask AI button reimplemented with MUI primitives: outlined `Button` (small, with `KeyboardArrowDownIcon` caret) for the trigger; `Menu` with `MenuItem`s containing `ListItemIcon` (the simple-icons brand SVGs from v0.3.0) and `ListItemText`. Menu is anchored bottom-right of the trigger and opens with transform-origin top-right.
31
+ - Button is hidden on viewports under 997px (matches the Docusaurus mobile breakpoint).
32
+
33
+ ### Removed
34
+
35
+ - Custom click-outside and Esc-to-close handlers. MUI `Menu` provides both natively. Net reduction in `src/theme/AskAiButton/index.jsx`: ~25 lines.
36
+ - All custom trigger / menu CSS classes. The CSS module is now a 2-rule wrapper that controls only the responsive show/hide; all other styling lives on the MUI `sx` prop.
37
+
3
38
  ## 0.3.0
4
39
 
5
40
  Focused UX upgrade to the Ask AI button (feature 3). No changes to features 1, 2, or 4.
package/README.md CHANGED
@@ -170,7 +170,7 @@ Behavior:
170
170
 
171
171
  ## Feature 3: "Ask AI" button
172
172
 
173
- A solid pill dropdown reading "Ask AI about this page" is injected at the top of every doc and blog-post content area, right-aligned in the breadcrumb row. Each item in the dropdown opens the corresponding AI surface in a new tab with a prefilled prompt that references the current page's `.md` companion.
173
+ An outlined pill button with a caret reading "Ask AI about this page" is injected at the top of every doc and blog-post content area, right-aligned in the breadcrumb row. Each item in the dropdown opens the corresponding AI surface in a new tab with a prefilled prompt that references the current page's `.md` companion. The button is hidden on viewports under 997px to keep the breadcrumb row uncluttered on mobile.
174
174
 
175
175
  Placement specifics:
176
176
 
@@ -194,9 +194,9 @@ Read https://your-site.example/path/to/page.md and help me with the following qu
194
194
 
195
195
  The trailing space is intentional - the cursor lands ready for the user to type.
196
196
 
197
- Provider icons are real brand SVGs sourced from [simple-icons](https://simpleicons.org). Three of four (Claude, Perplexity, Gemini) come from the upstream catalog directly. OpenAI / ChatGPT was removed from simple-icons in 2024 following a takedown, so the ChatGPT row shows a neutral chat-bubble glyph as a placeholder.
197
+ Provider icons are real brand SVGs in each provider's brand color, sourced from [@lobehub/icons](https://github.com/lobehub/lobe-icons). Claude, Perplexity, and Gemini render via their `.Color` variants directly; OpenAI ships only a monochrome mark, so the ChatGPT row uses that mark tinted with the ChatGPT brand green so it visually pairs with the colored icons.
198
198
 
199
- **Trademark note.** Brand logos are trademarks of their respective owners; their inclusion via simple-icons does not imply endorsement. Consumers using the Ask AI button in commercial contexts should review each provider's brand-usage policy.
199
+ **Trademark note.** Brand logos are trademarks of their respective owners; their inclusion via @lobehub/icons does not imply endorsement. Consumers using the Ask AI button in commercial contexts should review each provider's brand-usage policy.
200
200
 
201
201
  Options:
202
202
 
@@ -207,7 +207,22 @@ Options:
207
207
  | `askAi.promptTemplate` | `'Read {pageUrl}.md and help me with the following question about it: '` | Prompt sent to each provider. `{pageUrl}` is the page's canonical URL (no trailing slash). If feature 1 is disabled, the consumer should remove the `.md` from the template. |
208
208
  | `askAi.placement` | `'breadcrumb-row'` | `'breadcrumb-row'` puts the button at the top of every doc/blog page (docs breadcrumb row, or above the blog title). `'none'` does not register any theme components - swizzle the button into your preferred location manually. |
209
209
 
210
- Styling uses CSS modules and reads from Docusaurus's theme tokens (`--ifm-color-primary`, `--ifm-color-primary-darker`, `--ifm-color-emphasis-300`, etc.) so dark/light mode work automatically without extra rules.
210
+ The button is built from [MUI](https://mui.com) primitives - outlined `Button` with a `KeyboardArrowDownIcon` caret as the trigger, and a `Menu` of `MenuItem` rows for the providers. Theming reads `--ifm-color-primary` and `--ifm-font-family-base` via MUI's `sx` prop, so dark/light mode work automatically. The MUI `Menu` handles click-outside-to-close and Esc-to-close natively.
211
+
212
+ ### Peer dependencies
213
+
214
+ When `askAi.enabled` is `true` (the default), the following peer dependencies must be installed by the consumer site:
215
+
216
+ | Package | Range |
217
+ | --- | --- |
218
+ | `@mui/material` | `^5.0.0 \|\| ^6.0.0 \|\| ^7.0.0` |
219
+ | `@mui/icons-material` | `^5.0.0 \|\| ^6.0.0 \|\| ^7.0.0` |
220
+ | `@emotion/react` | `^11.0.0` |
221
+ | `@emotion/styled` | `^11.0.0` |
222
+
223
+ These are declared as peer dependencies (not direct dependencies) so consumers that already use MUI - common in Docusaurus sites - get a single deduped copy at install time. Consumers without MUI will get a clean npm peer-dependency error pointing at exactly what to install.
224
+
225
+ Consumers who disable the Ask AI button (`askAi.enabled: false`) can ignore these peers; the theme components are not registered in that case and MUI is never imported.
211
226
 
212
227
  ### Customizing placement
213
228
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackql/docusaurus-plugin-aeo",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "AEO (Answer Engine Optimization) helpers for Docusaurus: .md companion files, llms.txt / llms-full.txt, an Ask AI dropdown, and /ai/* route conventions.",
5
5
  "main": "src/index.js",
6
6
  "exports": {
@@ -21,12 +21,30 @@
21
21
  },
22
22
  "peerDependencies": {
23
23
  "@docusaurus/core": "^3.0.0",
24
+ "@emotion/react": "^11.0.0",
25
+ "@emotion/styled": "^11.0.0",
26
+ "@mui/icons-material": "^5.0.0 || ^6.0.0 || ^7.0.0",
27
+ "@mui/material": "^5.0.0 || ^6.0.0 || ^7.0.0",
24
28
  "react": "^18.0.0 || ^19.0.0",
25
29
  "react-dom": "^18.0.0 || ^19.0.0"
26
30
  },
31
+ "peerDependenciesMeta": {
32
+ "@mui/material": {
33
+ "optional": false
34
+ },
35
+ "@mui/icons-material": {
36
+ "optional": false
37
+ },
38
+ "@emotion/react": {
39
+ "optional": false
40
+ },
41
+ "@emotion/styled": {
42
+ "optional": false
43
+ }
44
+ },
27
45
  "dependencies": {
28
- "gray-matter": "^4.0.3",
29
- "simple-icons": "^16.22.0"
46
+ "@lobehub/icons": "^5.10.0",
47
+ "gray-matter": "^4.0.3"
30
48
  },
31
49
  "overrides": {
32
50
  "serialize-javascript": "^7.0.5",
@@ -1,72 +1,45 @@
1
- // Brand icons for the four supported AI providers.
1
+ // Brand icons for the four supported AI providers, sourced from
2
+ // @lobehub/icons. Each provider's package exports a default Mono
3
+ // component with .Color, .Text, .Combine, .Avatar attached as
4
+ // properties. We prefer .Color (multi-color brand variant) when the
5
+ // provider ships one; OpenAI does not, so we fall back to Mono and
6
+ // tint it with the ChatGPT brand green via inline style.
2
7
  //
3
- // Three of four come from simple-icons (siClaude, siPerplexity,
4
- // siGooglegemini). OpenAI / ChatGPT was removed from simple-icons in
5
- // 2024 following a takedown, so for that one we ship a neutral inline
6
- // chat-bubble glyph. The same fallback path is reused for any future
7
- // icon that disappears from upstream.
8
- //
9
- // All icons render as a 24x24 viewBox SVG with `fill="currentColor"`,
10
- // so the menu CSS can size them via font-size or width/height and tint
11
- // them via the surrounding text color. ESM `import` is used so webpack
12
- // can tree-shake unused simple-icons exports out of the bundle.
8
+ // Deep import paths (@lobehub/icons/es/<Provider>) are used because
9
+ // the package does not declare a subpath exports map; the deep path
10
+ // is stable across the 5.x line and tree-shakes cleanly because each
11
+ // per-provider module's dependency footprint is just React.
13
12
 
14
13
  import React from 'react';
15
- import { siClaude, siPerplexity, siGooglegemini } from 'simple-icons';
14
+ import ClaudeIcons from '@lobehub/icons/es/Claude';
15
+ import OpenAIIcons from '@lobehub/icons/es/OpenAI';
16
+ import PerplexityIcons from '@lobehub/icons/es/Perplexity';
17
+ import GeminiIcons from '@lobehub/icons/es/Gemini';
16
18
 
17
- function svg(children) {
18
- return React.createElement(
19
- 'svg',
20
- {
21
- xmlns: 'http://www.w3.org/2000/svg',
22
- width: '1em',
23
- height: '1em',
24
- viewBox: '0 0 24 24',
25
- fill: 'currentColor',
26
- role: 'img',
27
- 'aria-hidden': 'true',
28
- },
29
- children,
30
- );
31
- }
19
+ const ICON_SIZE = 18;
32
20
 
33
- function fromSimpleIcons(si) {
34
- if (!si || typeof si.path !== 'string') {
35
- return GenericAiIcon;
36
- }
37
- return function BrandIcon() {
38
- return svg(React.createElement('path', { d: si.path }));
39
- };
40
- }
21
+ // OpenAI ships only the monochrome mark (Color variant absent from
22
+ // @lobehub/icons as of 5.10.0). Use the known ChatGPT brand green so
23
+ // the row visually matches the other three colored marks.
24
+ const CHATGPT_GREEN = '#10A37F';
41
25
 
42
- // Neutral chat-bubble glyph - used when a brand icon isn't available
43
- // upstream. Not a brand mark, no trademark concerns.
44
- function GenericAiIcon() {
45
- return svg(
46
- React.createElement('path', {
47
- d: 'M4 4h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-8l-5 4v-4H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Zm3 6h2v2H7v-2Zm4 0h2v2h-2v-2Zm4 0h2v2h-2v-2Z',
48
- }),
49
- );
26
+ function makeColorIcon(IconNamespace, fallbackColor) {
27
+ const Component = IconNamespace.Color || IconNamespace;
28
+ const usingFallback = !IconNamespace.Color;
29
+ return function Icon() {
30
+ const props = { size: ICON_SIZE };
31
+ if (usingFallback && fallbackColor) {
32
+ props.style = { color: fallbackColor };
33
+ }
34
+ return React.createElement(Component, props);
35
+ };
50
36
  }
51
37
 
52
38
  const icons = {
53
- claude: fromSimpleIcons(siClaude),
54
- // simple-icons dropped OpenAI/ChatGPT in 2024; fall back to a neutral
55
- // chat-bubble glyph rather than failing the build or shipping a guess
56
- // at the wordmark.
57
- chatgpt: GenericAiIcon,
58
- perplexity: fromSimpleIcons(siPerplexity),
59
- gemini: fromSimpleIcons(siGooglegemini),
39
+ claude: makeColorIcon(ClaudeIcons),
40
+ chatgpt: makeColorIcon(OpenAIIcons, CHATGPT_GREEN),
41
+ perplexity: makeColorIcon(PerplexityIcons),
42
+ gemini: makeColorIcon(GeminiIcons),
60
43
  };
61
44
 
62
- if (typeof console !== 'undefined') {
63
- for (const [name, icon] of Object.entries(icons)) {
64
- if (icon === GenericAiIcon && name !== 'chatgpt') {
65
- console.warn(
66
- `[plugin-aeo] AskAiButton: brand icon for "${name}" missing from simple-icons; using generic AI glyph`,
67
- );
68
- }
69
- }
70
- }
71
-
72
45
  export default icons;
@@ -1,4 +1,10 @@
1
- import React, { useCallback, useEffect, useRef, useState } from 'react';
1
+ import React, { useState } from 'react';
2
+ import Button from '@mui/material/Button';
3
+ import Menu from '@mui/material/Menu';
4
+ import MenuItem from '@mui/material/MenuItem';
5
+ import ListItemIcon from '@mui/material/ListItemIcon';
6
+ import ListItemText from '@mui/material/ListItemText';
7
+ import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
2
8
  import { useLocation } from '@docusaurus/router';
3
9
  import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
4
10
  import { usePluginData } from '@docusaurus/useGlobalData';
@@ -19,51 +25,24 @@ const PROVIDER_URLS = {
19
25
  gemini: 'https://gemini.google.com/app?q=',
20
26
  };
21
27
 
22
- function buildPrompt(template, pageUrl) {
23
- return template.replace('{pageUrl}', pageUrl);
24
- }
28
+ const DEFAULT_PROMPT_TEMPLATE =
29
+ 'Read {pageUrl}.md and help me with the following question about it: ';
25
30
 
26
- export default function AskAiButton(props) {
31
+ export default function AskAiButton() {
27
32
  const { siteConfig } = useDocusaurusContext();
28
33
  const data = usePluginData('@stackql/docusaurus-plugin-aeo') || {};
29
34
  const cfg = data.askAi || {};
30
35
  const location = useLocation();
31
36
 
32
- const [open, setOpen] = useState(false);
33
- const wrapperRef = useRef(null);
34
-
35
- useEffect(() => {
36
- function onDocClick(e) {
37
- if (wrapperRef.current && !wrapperRef.current.contains(e.target)) {
38
- setOpen(false);
39
- }
40
- }
41
- function onEsc(e) {
42
- if (e.key === 'Escape') setOpen(false);
43
- }
44
- if (open) {
45
- document.addEventListener('mousedown', onDocClick);
46
- document.addEventListener('keydown', onEsc);
47
- }
48
- return () => {
49
- document.removeEventListener('mousedown', onDocClick);
50
- document.removeEventListener('keydown', onEsc);
51
- };
52
- }, [open]);
53
-
54
- const toggle = useCallback(() => setOpen((v) => !v), []);
37
+ const [anchorEl, setAnchorEl] = useState(null);
38
+ const open = Boolean(anchorEl);
55
39
 
56
40
  if (cfg.enabled === false) return null;
57
41
 
58
42
  const baseUrl = (siteConfig.url || '').replace(/\/$/, '');
59
43
  const pageUrl = `${baseUrl}${location.pathname.replace(/\/$/, '') || ''}`;
60
- const promptTemplate =
61
- cfg.promptTemplate ||
62
- 'Read {pageUrl}.md and help me with the following question about it: ';
63
- const targetUrl = cfg.companionsEnabled === false
64
- ? pageUrl
65
- : pageUrl; // template controls .md suffix; pageUrl is the HTML route
66
- const prompt = buildPrompt(promptTemplate, targetUrl);
44
+ const promptTemplate = cfg.promptTemplate || DEFAULT_PROMPT_TEMPLATE;
45
+ const prompt = promptTemplate.replace('{pageUrl}', pageUrl);
67
46
  const encoded = encodeURIComponent(prompt);
68
47
 
69
48
  const order =
@@ -71,60 +50,76 @@ export default function AskAiButton(props) {
71
50
  ? cfg.providerOrder
72
51
  : ['claude', 'chatgpt', 'perplexity', 'gemini'];
73
52
 
53
+ const handleOpen = (e) => setAnchorEl(e.currentTarget);
54
+ const handleClose = () => setAnchorEl(null);
55
+
74
56
  return (
75
- <div className={styles.wrapper} ref={wrapperRef}>
76
- <button
77
- type="button"
78
- className={styles.trigger}
57
+ <div className={styles.dropdownWrapper}>
58
+ <Button
59
+ variant="outlined"
60
+ size="small"
61
+ endIcon={<KeyboardArrowDownIcon />}
62
+ onClick={handleOpen}
79
63
  aria-haspopup="menu"
80
64
  aria-expanded={open}
81
- onClick={toggle}
65
+ sx={{
66
+ textTransform: 'none',
67
+ fontFamily: 'var(--ifm-font-family-base)',
68
+ fontWeight: 600,
69
+ fontSize: '0.75rem',
70
+ borderColor: 'var(--ifm-color-primary)',
71
+ color: 'var(--ifm-color-primary)',
72
+ '&:hover': {
73
+ borderColor: 'var(--ifm-color-primary)',
74
+ backgroundColor: 'rgba(0, 65, 101, 0.04)',
75
+ },
76
+ }}
77
+ >
78
+ Ask AI about this page
79
+ </Button>
80
+ <Menu
81
+ anchorEl={anchorEl}
82
+ open={open}
83
+ onClose={handleClose}
84
+ anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
85
+ transformOrigin={{ vertical: 'top', horizontal: 'right' }}
86
+ sx={{
87
+ '& .MuiPaper-root': {
88
+ fontFamily: 'var(--ifm-font-family-base)',
89
+ minWidth: 200,
90
+ },
91
+ }}
82
92
  >
83
- <span>Ask AI about this page</span>
84
- <span
85
- className={`${styles.caret}${open ? ` ${styles.caretOpen}` : ''}`}
86
- aria-hidden="true"
87
- >
88
- {/* Inline chevron-down so we don't depend on a font glyph. */}
89
- <svg
90
- xmlns="http://www.w3.org/2000/svg"
91
- width="0.75em"
92
- height="0.75em"
93
- viewBox="0 0 24 24"
94
- fill="currentColor"
95
- >
96
- <path d="M6 9l6 6 6-6H6z" />
97
- </svg>
98
- </span>
99
- </button>
100
- {open && (
101
- <ul className={styles.menu} role="menu">
102
- {order.map((key) => {
103
- const Icon = icons[key];
104
- const label = PROVIDER_LABELS[key] || key;
105
- const base = PROVIDER_URLS[key];
106
- if (!base || !Icon) return null;
107
- const href = `${base}${encoded}`;
108
- return (
109
- <li key={key} className={styles.item} role="none">
110
- <a
111
- role="menuitem"
112
- className={styles.itemLink}
113
- href={href}
114
- target="_blank"
115
- rel="noopener noreferrer"
116
- onClick={() => setOpen(false)}
117
- >
118
- <span className={styles.icon}>
119
- <Icon />
120
- </span>
121
- <span>{label}</span>
122
- </a>
123
- </li>
124
- );
125
- })}
126
- </ul>
127
- )}
93
+ {order.map((key) => {
94
+ const Icon = icons[key];
95
+ const label = PROVIDER_LABELS[key];
96
+ const base = PROVIDER_URLS[key];
97
+ if (!base || !Icon) return null;
98
+ const href = `${base}${encoded}`;
99
+ return (
100
+ <MenuItem
101
+ key={key}
102
+ component="a"
103
+ href={href}
104
+ target="_blank"
105
+ rel="noopener noreferrer"
106
+ onClick={handleClose}
107
+ >
108
+ <ListItemIcon sx={{ minWidth: 32, color: 'inherit' }}>
109
+ <Icon />
110
+ </ListItemIcon>
111
+ <ListItemText
112
+ primaryTypographyProps={{
113
+ fontSize: '0.85rem',
114
+ fontFamily: 'var(--ifm-font-family-base)',
115
+ }}
116
+ >
117
+ {label}
118
+ </ListItemText>
119
+ </MenuItem>
120
+ );
121
+ })}
122
+ </Menu>
128
123
  </div>
129
124
  );
130
125
  }
@@ -1,87 +1,11 @@
1
- .wrapper {
2
- position: relative;
3
- display: inline-block;
1
+ .dropdownWrapper {
2
+ display: none;
3
+ flex-shrink: 0;
4
4
  }
5
5
 
6
- .trigger {
7
- display: inline-flex;
8
- align-items: center;
9
- gap: 0.5rem;
10
- padding: 0.4rem 0.9rem;
11
- background: var(--ifm-color-primary);
12
- color: var(--ifm-color-primary-contrast-foreground, #fff);
13
- border: none;
14
- border-radius: 999px;
15
- font-size: 0.875rem;
16
- font-weight: 500;
17
- line-height: 1.2;
18
- cursor: pointer;
19
- white-space: nowrap;
20
- transition: background-color 0.15s ease;
21
- }
22
-
23
- .trigger:hover {
24
- background: var(--ifm-color-primary-darker, var(--ifm-color-primary-dark));
25
- }
26
-
27
- .trigger:focus-visible {
28
- outline: 2px solid var(--ifm-color-primary-light, currentColor);
29
- outline-offset: 2px;
30
- }
31
-
32
- .caret {
33
- display: inline-block;
34
- font-size: 0.7em;
35
- opacity: 0.9;
36
- transition: transform 0.15s ease;
37
- }
38
-
39
- .caretOpen {
40
- transform: rotate(180deg);
41
- }
42
-
43
- .menu {
44
- position: absolute;
45
- top: calc(100% + 0.4rem);
46
- right: 0;
47
- z-index: 100;
48
- min-width: 200px;
49
- margin: 0;
50
- padding: 0.25rem 0;
51
- list-style: none;
52
- background: var(--ifm-background-surface-color, var(--ifm-background-color));
53
- border: 1px solid var(--ifm-color-emphasis-300);
54
- border-radius: 0.5rem;
55
- box-shadow: 0 6px 24px -8px rgba(0, 0, 0, 0.18);
56
- }
57
-
58
- .item {
59
- margin: 0;
60
- }
61
-
62
- .itemLink {
63
- display: flex;
64
- align-items: center;
65
- gap: 0.65rem;
66
- padding: 0.5rem 0.85rem;
67
- color: var(--ifm-color-content, var(--ifm-font-color-base));
68
- text-decoration: none;
69
- font-size: 0.875rem;
70
- }
71
-
72
- .itemLink:hover {
73
- background: var(--ifm-color-emphasis-100);
74
- color: var(--ifm-color-content, var(--ifm-font-color-base));
75
- text-decoration: none;
76
- }
77
-
78
- .icon {
79
- display: inline-flex;
80
- align-items: center;
81
- justify-content: center;
82
- width: 18px;
83
- height: 18px;
84
- font-size: 18px;
85
- color: var(--ifm-color-content, var(--ifm-font-color-base));
86
- flex: 0 0 auto;
6
+ @media screen and (min-width: 997px) {
7
+ .dropdownWrapper {
8
+ display: flex;
9
+ align-items: center;
10
+ }
87
11
  }