@redocly/theme 0.69.0-next.1 → 0.69.0-next.10

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 (264) hide show
  1. package/lib/components/Accordion/Accordion.js +5 -1
  2. package/lib/components/Accordion/variables.js +1 -1
  3. package/lib/components/Admonition/Admonition.d.ts +1 -1
  4. package/lib/components/Admonition/Admonition.js +1 -1
  5. package/lib/components/Admonition/variables.dark.js +2 -2
  6. package/lib/components/Admonition/variables.js +10 -10
  7. package/lib/components/Badge/Badge.d.ts +3 -1
  8. package/lib/components/Badge/Badge.js +7 -2
  9. package/lib/components/Banner/variables.dark.js +2 -0
  10. package/lib/components/Banner/variables.js +3 -1
  11. package/lib/components/Breadcrumbs/Breadcrumb.js +1 -1
  12. package/lib/components/Breadcrumbs/variables.js +1 -1
  13. package/lib/components/Button/ButtonGroup.d.ts +3 -5
  14. package/lib/components/Button/ButtonGroup.js +25 -5
  15. package/lib/components/Button/variables.js +27 -4
  16. package/lib/components/Buttons/ConnectMCPButton.js +39 -123
  17. package/lib/components/Buttons/CopyButton.js +12 -1
  18. package/lib/components/Buttons/variables.d.ts +0 -1
  19. package/lib/components/Buttons/variables.js +3 -44
  20. package/lib/components/Catalog/CatalogEntities.js +1 -0
  21. package/lib/components/Catalog/CatalogEntity/CatalogEntityLinks.js +1 -1
  22. package/lib/components/Catalog/CatalogEntity/CatalogEntityMetadata.js +1 -1
  23. package/lib/components/Catalog/CatalogEntity/CatalogEntityMethodAndPath.js +1 -1
  24. package/lib/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelations.js +5 -3
  25. package/lib/components/Catalog/CatalogEntity/CatalogEntitySchema.js +1 -1
  26. package/lib/components/Catalog/CatalogFilter/CatalogFilterSelect.js +1 -0
  27. package/lib/components/Catalog/CatalogViewModeToggle.d.ts +1 -1
  28. package/lib/components/Catalog/CatalogViewModeToggle.js +2 -43
  29. package/lib/components/Catalog/variables.js +5 -5
  30. package/lib/components/CatalogClassic/variables.js +2 -2
  31. package/lib/components/CodeBlock/CodeBlock.js +2 -1
  32. package/lib/components/CodeBlock/CodeBlockContainer.js +1 -0
  33. package/lib/components/Dropdown/Dropdown.d.ts +10 -20
  34. package/lib/components/Dropdown/Dropdown.js +13 -2
  35. package/lib/components/Dropdown/DropdownMenuItemContent.d.ts +9 -0
  36. package/lib/components/Dropdown/DropdownMenuItemContent.js +56 -0
  37. package/lib/components/Dropdown/variables.js +19 -2
  38. package/lib/components/Feedback/Mood.js +18 -14
  39. package/lib/components/Feedback/Rating.js +18 -13
  40. package/lib/components/Feedback/Scale.js +27 -22
  41. package/lib/components/Feedback/Sentiment.js +17 -13
  42. package/lib/components/Filter/FilterInput.js +4 -2
  43. package/lib/components/Filter/FilterSelect.js +1 -0
  44. package/lib/components/Filter/variables.js +2 -2
  45. package/lib/components/Image/variables.js +5 -3
  46. package/lib/components/JsonViewer/Helpers.js +12 -42
  47. package/lib/components/LanguagePicker/variables.js +1 -1
  48. package/lib/components/MCP/McpConnectionTabs.d.ts +7 -0
  49. package/lib/components/MCP/McpConnectionTabs.js +151 -0
  50. package/lib/components/Markdown/styles/base-table.js +8 -0
  51. package/lib/components/Markdown/variables.js +1 -1
  52. package/lib/components/Menu/MenuItem.js +1 -1
  53. package/lib/components/Menu/variables.js +1 -1
  54. package/lib/components/Navbar/variables.js +1 -1
  55. package/lib/components/PageActions/PageActions.js +4 -6
  56. package/lib/components/PageActions/PageActionsMenuItem.d.ts +4 -4
  57. package/lib/components/PageActions/PageActionsMenuItem.js +27 -43
  58. package/lib/components/Panel/Panel.js +5 -1
  59. package/lib/components/Panel/variables.js +1 -1
  60. package/lib/components/Product/variables.js +2 -1
  61. package/lib/components/ReplayGate/ReplayGate.d.ts +1 -0
  62. package/lib/components/Search/FilterFields/SearchFilterFieldSelect.js +22 -32
  63. package/lib/components/Search/SearchAiDialog.js +4 -1
  64. package/lib/components/Search/SearchAiMessage.js +1 -1
  65. package/lib/components/Search/SearchAiNegativeFeedbackForm.js +2 -2
  66. package/lib/components/Search/SearchDialog.js +2 -2
  67. package/lib/components/Search/SearchItem.js +6 -3
  68. package/lib/components/Search/SearchRecent.js +1 -0
  69. package/lib/components/Search/SearchSuggestedPages.js +1 -0
  70. package/lib/components/Search/variables.js +9 -5
  71. package/lib/components/Segmented/Segmented.js +3 -3
  72. package/lib/components/Select/Select.js +30 -23
  73. package/lib/components/Select/variables.js +3 -3
  74. package/lib/components/Sidebar/Sidebar.js +2 -38
  75. package/lib/components/SplitButton/SplitButton.d.ts +21 -0
  76. package/lib/components/SplitButton/SplitButton.js +37 -0
  77. package/lib/components/Switch/variables.dark.js +2 -2
  78. package/lib/components/Switch/variables.js +2 -2
  79. package/lib/components/Tag/variables.js +2 -2
  80. package/lib/components/Tags/variables.js +1 -1
  81. package/lib/components/Toast/variables.js +1 -1
  82. package/lib/components/Tooltip/AnchorTooltip.js +2 -2
  83. package/lib/components/Tooltip/JsTooltip.js +2 -2
  84. package/lib/components/UserMenu/variables.js +1 -1
  85. package/lib/core/constants/mcp.d.ts +4 -0
  86. package/lib/core/constants/mcp.js +10 -1
  87. package/lib/core/constants/search.js +2 -2
  88. package/lib/core/contexts/PageActionsContext.d.ts +5 -0
  89. package/lib/core/contexts/PageActionsContext.js +10 -0
  90. package/lib/core/contexts/index.d.ts +1 -0
  91. package/lib/core/contexts/index.js +1 -0
  92. package/lib/core/hooks/code-walkthrough/use-code-walkthrough-controls.js +5 -17
  93. package/lib/core/hooks/code-walkthrough/use-code-walkthrough-steps.js +1 -0
  94. package/lib/core/hooks/menu/use-menu-item-expanded.js +1 -0
  95. package/lib/core/hooks/use-active-heading.js +59 -15
  96. package/lib/core/hooks/use-active-section-id.js +3 -1
  97. package/lib/core/hooks/use-connect-mcp-button.d.ts +1 -1
  98. package/lib/core/hooks/use-connect-mcp-button.js +16 -13
  99. package/lib/core/hooks/use-control.js +3 -0
  100. package/lib/core/hooks/use-local-state.js +1 -0
  101. package/lib/core/hooks/use-mcp-config.d.ts +2 -0
  102. package/lib/core/hooks/use-mcp-config.js +14 -4
  103. package/lib/core/hooks/use-mobile-menu.js +10 -2
  104. package/lib/core/styles/global.js +16 -11
  105. package/lib/core/styles/palette.js +2 -0
  106. package/lib/core/types/button-group.d.ts +2 -0
  107. package/lib/core/types/button-group.js +3 -0
  108. package/lib/core/types/catalog.d.ts +2 -4
  109. package/lib/core/types/common.d.ts +2 -0
  110. package/lib/core/types/hooks.d.ts +1 -0
  111. package/lib/core/types/index.d.ts +1 -0
  112. package/lib/core/types/l10n.d.ts +1 -1
  113. package/lib/core/types/mcp.d.ts +1 -1
  114. package/lib/core/utils/RenderWithLink.d.ts +2 -0
  115. package/lib/core/utils/RenderWithLink.js +20 -0
  116. package/lib/core/utils/index.d.ts +1 -0
  117. package/lib/core/utils/index.js +1 -0
  118. package/lib/core/utils/mcp.d.ts +5 -0
  119. package/lib/core/utils/mcp.js +35 -0
  120. package/lib/icons/CodexIcon/CodexIcon.d.ts +25 -0
  121. package/lib/icons/CodexIcon/CodexIcon.js +22 -0
  122. package/lib/icons/LinkIcon/LinkIcon.js +1 -1
  123. package/lib/index.d.ts +2 -0
  124. package/lib/index.js +2 -0
  125. package/lib/layouts/McpNotAllowed.js +10 -10
  126. package/lib/markdoc/components/Cards/Card.d.ts +8 -1
  127. package/lib/markdoc/components/Cards/Card.js +55 -16
  128. package/lib/markdoc/components/Cards/CardBadge.d.ts +9 -0
  129. package/lib/markdoc/components/Cards/CardBadge.js +30 -0
  130. package/lib/markdoc/components/Cards/CardIcon.d.ts +5 -4
  131. package/lib/markdoc/components/Cards/CardIcon.js +6 -3
  132. package/lib/markdoc/components/Cards/variables.dark.js +32 -0
  133. package/lib/markdoc/components/Cards/variables.js +81 -7
  134. package/lib/markdoc/components/CodeWalkthrough/CodePanel.js +1 -0
  135. package/lib/markdoc/components/CodeWalkthrough/CodeStep.js +1 -1
  136. package/lib/markdoc/components/CodeWalkthrough/variables.js +2 -1
  137. package/lib/markdoc/components/Heading/Heading.js +5 -2
  138. package/lib/markdoc/components/Tabs/TabList.js +6 -2
  139. package/lib/markdoc/components/Tabs/Tabs.js +4 -2
  140. package/lib/markdoc/components/Tabs/variables.js +4 -4
  141. package/lib/markdoc/tags/admonition.js +1 -1
  142. package/lib/markdoc/tags/card.js +14 -0
  143. package/lib/markdoc/tags/connect-mcp.js +2 -1
  144. package/package.json +19 -10
  145. package/src/components/Accordion/Accordion.tsx +7 -3
  146. package/src/components/Accordion/variables.ts +1 -1
  147. package/src/components/Admonition/Admonition.tsx +2 -2
  148. package/src/components/Admonition/variables.dark.ts +2 -2
  149. package/src/components/Admonition/variables.ts +10 -10
  150. package/src/components/Badge/Badge.tsx +16 -2
  151. package/src/components/Banner/variables.dark.ts +2 -0
  152. package/src/components/Banner/variables.ts +3 -1
  153. package/src/components/Breadcrumbs/Breadcrumb.tsx +1 -1
  154. package/src/components/Breadcrumbs/variables.ts +1 -1
  155. package/src/components/Button/ButtonGroup.tsx +28 -10
  156. package/src/components/Button/variables.ts +27 -4
  157. package/src/components/Buttons/ConnectMCPButton.tsx +88 -145
  158. package/src/components/Buttons/CopyButton.tsx +14 -2
  159. package/src/components/Buttons/variables.ts +2 -44
  160. package/src/components/Catalog/CatalogEntities.tsx +1 -0
  161. package/src/components/Catalog/CatalogEntity/CatalogEntityLinks.tsx +1 -1
  162. package/src/components/Catalog/CatalogEntity/CatalogEntityMetadata.tsx +1 -1
  163. package/src/components/Catalog/CatalogEntity/CatalogEntityMethodAndPath.tsx +1 -1
  164. package/src/components/Catalog/CatalogEntity/CatalogEntityRelations/CatalogEntityRelations.tsx +6 -4
  165. package/src/components/Catalog/CatalogEntity/CatalogEntitySchema.tsx +1 -1
  166. package/src/components/Catalog/CatalogFilter/CatalogFilterSelect.tsx +1 -0
  167. package/src/components/Catalog/CatalogViewModeToggle.tsx +2 -17
  168. package/src/components/Catalog/variables.ts +5 -5
  169. package/src/components/CatalogClassic/variables.ts +2 -2
  170. package/src/components/CodeBlock/CodeBlock.tsx +2 -1
  171. package/src/components/CodeBlock/CodeBlockContainer.tsx +1 -0
  172. package/src/components/Dropdown/Dropdown.tsx +25 -4
  173. package/src/components/Dropdown/DropdownMenuItemContent.tsx +72 -0
  174. package/src/components/Dropdown/variables.ts +19 -2
  175. package/src/components/Feedback/Mood.tsx +22 -15
  176. package/src/components/Feedback/Rating.tsx +22 -14
  177. package/src/components/Feedback/Scale.tsx +40 -32
  178. package/src/components/Feedback/Sentiment.tsx +21 -14
  179. package/src/components/Filter/FilterInput.tsx +5 -3
  180. package/src/components/Filter/FilterSelect.tsx +1 -0
  181. package/src/components/Filter/variables.ts +2 -2
  182. package/src/components/Image/variables.ts +5 -3
  183. package/src/components/JsonViewer/Helpers.tsx +13 -9
  184. package/src/components/LanguagePicker/variables.ts +1 -1
  185. package/src/components/MCP/McpConnectionTabs.tsx +263 -0
  186. package/src/components/Markdown/styles/base-table.ts +8 -0
  187. package/src/components/Markdown/variables.ts +1 -1
  188. package/src/components/Menu/MenuItem.tsx +2 -2
  189. package/src/components/Menu/variables.ts +1 -1
  190. package/src/components/Navbar/variables.ts +1 -1
  191. package/src/components/PageActions/PageActions.tsx +22 -23
  192. package/src/components/PageActions/PageActionsMenuItem.tsx +41 -55
  193. package/src/components/Panel/Panel.tsx +7 -3
  194. package/src/components/Panel/variables.ts +1 -1
  195. package/src/components/Product/variables.ts +2 -1
  196. package/src/components/ReplayGate/ReplayGate.tsx +3 -0
  197. package/src/components/Search/FilterFields/SearchFilterFieldSelect.tsx +32 -40
  198. package/src/components/Search/SearchAiDialog.tsx +4 -1
  199. package/src/components/Search/SearchAiMessage.tsx +1 -1
  200. package/src/components/Search/SearchAiNegativeFeedbackForm.tsx +2 -2
  201. package/src/components/Search/SearchDialog.tsx +2 -2
  202. package/src/components/Search/SearchItem.tsx +7 -1
  203. package/src/components/Search/SearchRecent.tsx +1 -0
  204. package/src/components/Search/SearchSuggestedPages.tsx +1 -0
  205. package/src/components/Search/variables.ts +9 -5
  206. package/src/components/Segmented/Segmented.tsx +6 -3
  207. package/src/components/Select/Select.tsx +36 -22
  208. package/src/components/Select/variables.ts +3 -3
  209. package/src/components/Sidebar/Sidebar.tsx +2 -6
  210. package/src/components/SplitButton/SplitButton.tsx +95 -0
  211. package/src/components/Switch/variables.dark.ts +2 -2
  212. package/src/components/Switch/variables.ts +2 -2
  213. package/src/components/Tag/variables.ts +2 -2
  214. package/src/components/Tags/variables.ts +1 -1
  215. package/src/components/Toast/variables.ts +1 -1
  216. package/src/components/Tooltip/AnchorTooltip.tsx +2 -2
  217. package/src/components/Tooltip/JsTooltip.tsx +2 -2
  218. package/src/components/UserMenu/variables.ts +1 -1
  219. package/src/core/constants/mcp.ts +14 -0
  220. package/src/core/constants/search.ts +2 -2
  221. package/src/core/contexts/PageActionsContext.tsx +7 -0
  222. package/src/core/contexts/index.ts +1 -0
  223. package/src/core/hooks/code-walkthrough/use-code-walkthrough-controls.ts +6 -20
  224. package/src/core/hooks/code-walkthrough/use-code-walkthrough-steps.ts +1 -0
  225. package/src/core/hooks/menu/use-menu-item-expanded.ts +1 -0
  226. package/src/core/hooks/use-active-heading.ts +79 -15
  227. package/src/core/hooks/use-active-section-id.ts +3 -1
  228. package/src/core/hooks/use-connect-mcp-button.ts +23 -15
  229. package/src/core/hooks/use-control.ts +5 -1
  230. package/src/core/hooks/use-local-state.ts +1 -0
  231. package/src/core/hooks/use-mcp-config.ts +15 -4
  232. package/src/core/hooks/use-mobile-menu.ts +11 -3
  233. package/src/core/openapi/index.ts +1 -1
  234. package/src/core/styles/global.ts +17 -12
  235. package/src/core/styles/palette.ts +2 -0
  236. package/src/core/types/button-group.ts +2 -0
  237. package/src/core/types/catalog.ts +2 -4
  238. package/src/core/types/common.ts +3 -0
  239. package/src/core/types/hooks.ts +1 -0
  240. package/src/core/types/index.ts +1 -0
  241. package/src/core/types/l10n.ts +29 -1
  242. package/src/core/types/mcp.ts +1 -1
  243. package/src/core/utils/RenderWithLink.tsx +19 -0
  244. package/src/core/utils/index.ts +1 -0
  245. package/src/core/utils/mcp.ts +39 -0
  246. package/src/icons/CodexIcon/CodexIcon.tsx +23 -0
  247. package/src/icons/LinkIcon/LinkIcon.tsx +1 -1
  248. package/src/index.ts +2 -0
  249. package/src/layouts/McpNotAllowed.tsx +37 -11
  250. package/src/markdoc/components/Cards/Card.tsx +79 -14
  251. package/src/markdoc/components/Cards/CardBadge.tsx +39 -0
  252. package/src/markdoc/components/Cards/CardIcon.tsx +16 -5
  253. package/src/markdoc/components/Cards/variables.dark.ts +32 -0
  254. package/src/markdoc/components/Cards/variables.ts +81 -7
  255. package/src/markdoc/components/CodeWalkthrough/CodePanel.tsx +1 -0
  256. package/src/markdoc/components/CodeWalkthrough/CodeStep.tsx +1 -1
  257. package/src/markdoc/components/CodeWalkthrough/variables.ts +2 -1
  258. package/src/markdoc/components/Heading/Heading.tsx +7 -4
  259. package/src/markdoc/components/Tabs/TabList.tsx +6 -2
  260. package/src/markdoc/components/Tabs/Tabs.tsx +4 -2
  261. package/src/markdoc/components/Tabs/variables.ts +4 -4
  262. package/src/markdoc/tags/admonition.ts +1 -1
  263. package/src/markdoc/tags/card.ts +14 -0
  264. package/src/markdoc/tags/connect-mcp.ts +3 -1
@@ -2,13 +2,11 @@ import React from 'react';
2
2
  import styled from 'styled-components';
3
3
 
4
4
  import type { JSX } from 'react';
5
- import type { ButtonSize } from '@redocly/theme/components/Button/Button';
5
+ import type { ButtonGroupSize, ButtonGroupVariant } from '@redocly/theme/core/types';
6
6
 
7
- type ButtonGroupVariant = 'outlined';
8
-
9
- type ButtonGroupProps = {
7
+ export type ButtonGroupProps = {
10
8
  variant?: ButtonGroupVariant;
11
- size?: ButtonSize;
9
+ size?: ButtonGroupSize;
12
10
  children: React.ReactNode;
13
11
  className?: string;
14
12
  };
@@ -30,24 +28,44 @@ const ButtonGroupWrapper = styled.div`
30
28
  display: flex;
31
29
  line-height: var(--button-line-height);
32
30
 
33
- .button {
31
+ & > .button,
32
+ & > * > .button {
34
33
  border-radius: 0;
35
34
  }
36
35
 
37
36
  & > .button:first-child,
38
- *:first-child > .button {
37
+ & > *:first-child > .button {
39
38
  border-top-left-radius: var(--button-border-radius);
40
39
  border-bottom-left-radius: var(--button-border-radius);
41
40
  }
42
41
 
43
42
  & > .button:last-child,
44
- *:last-child > .button {
43
+ & > *:last-child > .button {
45
44
  border-top-right-radius: var(--button-border-radius);
46
45
  border-bottom-right-radius: var(--button-border-radius);
47
46
  }
48
47
 
48
+ /* Adjacent segments share a single divider line: the leading segment drops its
49
+ own right border and the trailing one draws the divider as its left border. */
50
+ & > .button:not(:last-child),
51
+ & > *:not(:last-child) > .button {
52
+ border-right-style: none;
53
+ border-right-width: 0;
54
+ }
55
+
49
56
  & > .button:not(:first-child),
50
- *:not(:first-child) > .button {
51
- border-left: none;
57
+ & > *:not(:first-child) > .button {
58
+ border-left-width: 1px;
59
+ border-left-style: solid;
60
+ border-left-color: color-mix(
61
+ in srgb,
62
+ var(--button-group-divider-color) calc(var(--button-group-divider-opacity) * 100%),
63
+ transparent
64
+ );
65
+ }
66
+
67
+ & > .button:not(:first-child):disabled,
68
+ & > *:not(:first-child) > .button:disabled {
69
+ border-left-color: var(--button-group-divider-color-disabled);
52
70
  }
53
71
  `;
@@ -68,7 +68,7 @@ export const button = css`
68
68
  --button-font-weight: var(--font-weight-regular);
69
69
  --button-font-size: var(--font-size-base);
70
70
  --button-line-height: var(--line-height-base);
71
- --button-border-radius: var(--border-radius-md);
71
+ --button-border-radius: var(--border-radius-lg);
72
72
  --button-padding: 5px var(--spacing-sm);
73
73
  --button-text-wrap: nowrap;
74
74
  --button-gap: var(--spacing-xs);
@@ -94,7 +94,7 @@ export const button = css`
94
94
  .button-size-small,
95
95
  .button-group-size-small .button {
96
96
  --button-font-size: var(--font-size-base);
97
- --button-border-radius: var(--border-radius);
97
+ --button-border-radius: var(--border-radius-md);
98
98
  --button-padding: 1px var(--spacing-sm);
99
99
  --button-line-height: var(--line-height-base);
100
100
 
@@ -107,7 +107,7 @@ export const button = css`
107
107
  .button-size-medium,
108
108
  .button-group-size-medium .button {
109
109
  --button-font-size: var(--font-size-base);
110
- --button-border-radius: var(--border-radius-md);
110
+ --button-border-radius: var(--border-radius-lg);
111
111
  --button-padding: 5px var(--spacing-sm);
112
112
  --button-line-height: var(--line-height-base);
113
113
 
@@ -120,7 +120,7 @@ export const button = css`
120
120
  .button-size-large,
121
121
  .button-group-size-large .button {
122
122
  --button-font-size: var(--font-size-lg); // @presenter FontSize
123
- --button-border-radius: var(--border-radius-md);
123
+ --button-border-radius: var(--border-radius-xl);
124
124
  --button-padding: var(--spacing-xs) var(--spacing-md);
125
125
  --button-line-height: var(--line-height-lg); // @presenter LineHeight
126
126
 
@@ -241,5 +241,28 @@ export const button = css`
241
241
  --button-icon-right-padding: 0;
242
242
  }
243
243
 
244
+ /**
245
+ * @tokens Button group divider
246
+ */
247
+
248
+ --button-group-divider-color: transparent;
249
+ --button-group-divider-opacity: 1;
250
+ --button-group-divider-color-disabled: var(--color-warm-grey-2); // @presenter Color
251
+
252
+ .button-group-primary {
253
+ --button-group-divider-color: var(--button-content-color-inverse); // @presenter Color
254
+ --button-group-divider-opacity: 0.32;
255
+ }
256
+
257
+ .button-group-secondary {
258
+ --button-group-divider-color: var(--button-content-color); // @presenter Color
259
+ --button-group-divider-opacity: 0.12;
260
+ }
261
+
262
+ .button-group-outlined {
263
+ --button-group-divider-color: var(--button-border-color); // @presenter Color
264
+ --button-group-divider-opacity: 1;
265
+ }
266
+
244
267
  // @tokens End
245
268
  `;
@@ -1,4 +1,4 @@
1
- import React, { useState, useRef } from 'react';
1
+ import React from 'react';
2
2
  import styled from 'styled-components';
3
3
 
4
4
  import type { JSX } from 'react';
@@ -6,14 +6,17 @@ import type { MCPOption } from '@redocly/theme/core/types';
6
6
 
7
7
  import { DropdownMenu } from '@redocly/theme/components/Dropdown/DropdownMenu';
8
8
  import { DropdownMenuItem } from '@redocly/theme/components/Dropdown/DropdownMenuItem';
9
+ import { DropdownMenuItemContent } from '@redocly/theme/components/Dropdown/DropdownMenuItemContent';
9
10
  import { Button } from '@redocly/theme/components/Button/Button';
11
+ import { SplitButton } from '@redocly/theme/components/SplitButton/SplitButton';
10
12
  import { CursorIcon } from '@redocly/theme/icons/CursorIcon/CursorIcon';
11
13
  import { VSCodeIcon } from '@redocly/theme/icons/VSCodeIcon/VSCodeIcon';
14
+ import { ClaudeIcon } from '@redocly/theme/icons/ClaudeIcon/ClaudeIcon';
15
+ import { CodexIcon } from '@redocly/theme/icons/CodexIcon/CodexIcon';
12
16
  import { CopyIcon } from '@redocly/theme/icons/CopyIcon/CopyIcon';
13
17
  import { CheckmarkFilledIcon } from '@redocly/theme/icons/CheckmarkFilledIcon/CheckmarkFilledIcon';
14
- import { ChevronDownIcon } from '@redocly/theme/icons/ChevronDownIcon/ChevronDownIcon';
15
- import { ChevronUpIcon } from '@redocly/theme/icons/ChevronUpIcon/ChevronUpIcon';
16
- import { useConnectMCPButton, useOutsideClick, useThemeHooks } from '@redocly/theme/core/hooks';
18
+ import { useConnectMCPButton, useThemeHooks } from '@redocly/theme/core/hooks';
19
+ import { DEFAULT_MCP_OPTIONS } from '@redocly/theme/core/constants';
17
20
 
18
21
  type MenuOption = {
19
22
  key: MCPOption;
@@ -41,6 +44,22 @@ const MENU_OPTIONS: MenuOption[] = [
41
44
  descriptionTranslationKey: 'page.actions.connectMcp.vscodeDescription',
42
45
  descriptionDefault: 'Install MCP server on VS Code',
43
46
  },
47
+ {
48
+ key: 'claude-code',
49
+ icon: ClaudeIcon,
50
+ titleTranslationKey: 'page.actions.connectMcp.claudeCode',
51
+ titleDefault: 'Connect to Claude Code',
52
+ descriptionTranslationKey: 'page.actions.connectMcp.claudeCodeDescription',
53
+ descriptionDefault: 'Copy the Claude Code CLI command',
54
+ },
55
+ {
56
+ key: 'codex',
57
+ icon: CodexIcon,
58
+ titleTranslationKey: 'page.actions.connectMcp.codex',
59
+ titleDefault: 'Connect to Codex CLI',
60
+ descriptionTranslationKey: 'page.actions.connectMcp.codexDescription',
61
+ descriptionDefault: 'Copy the Codex CLI command',
62
+ },
44
63
  {
45
64
  key: 'copy',
46
65
  icon: CopyIcon,
@@ -51,6 +70,9 @@ const MENU_OPTIONS: MenuOption[] = [
51
70
  },
52
71
  ];
53
72
 
73
+ // Copy actions keep the dropdown open so the copied checkmark is visible.
74
+ const COPY_OPTIONS: MCPOption[] = ['claude-code', 'codex', 'copy'];
75
+
54
76
  export type ConnectMCPButtonProps = {
55
77
  placement?: 'top' | 'bottom';
56
78
  alignment?: 'start' | 'end';
@@ -60,16 +82,12 @@ export type ConnectMCPButtonProps = {
60
82
  export function ConnectMCPButton({
61
83
  placement = 'bottom',
62
84
  alignment = 'end',
63
- options = ['cursor', 'vscode', 'copy'],
85
+ options = DEFAULT_MCP_OPTIONS,
64
86
  }: ConnectMCPButtonProps): JSX.Element | null {
65
87
  const { useTranslate } = useThemeHooks();
66
88
  const { translate } = useTranslate();
67
- const [isOpen, setIsOpen] = useState(false);
68
- const wrapperRef = useRef<HTMLDivElement>(null);
69
-
70
- const { isCopied, visibleOptions, handleAction } = useConnectMCPButton({ options });
71
89
 
72
- useOutsideClick(wrapperRef, () => setIsOpen(false));
90
+ const { copiedOption, visibleOptions, handleAction } = useConnectMCPButton({ options });
73
91
 
74
92
  const menuOptions = MENU_OPTIONS.filter((option) => visibleOptions.includes(option.key));
75
93
  const primaryOption = menuOptions[0];
@@ -78,76 +96,70 @@ export function ConnectMCPButton({
78
96
  if (!primaryOption) return null;
79
97
 
80
98
  const PrimaryIcon = primaryOption.icon;
81
- // When copy is the primary action there is no dropdown item to show the copied state, so the
82
- // primary button itself must reflect it.
83
- const showPrimaryCopied = primaryOption.key === 'copy' && isCopied;
84
-
85
- const handleMenuAction = (key: MCPOption) => {
86
- handleAction(key);
87
- setIsOpen(false);
88
- };
99
+ const showPrimaryCopied = copiedOption === primaryOption.key;
89
100
 
90
101
  return (
91
- <ConnectMCPButtonWrapper ref={wrapperRef} data-component-name="Buttons/ConnectMCPButton">
92
- <SplitButtonGroup>
93
- <PrimaryButton
94
- variant="secondary"
95
- icon={
96
- showPrimaryCopied ? (
97
- <CheckmarkFilledIcon color="var(--color-success-base)" />
98
- ) : (
99
- <PrimaryIcon />
100
- )
101
- }
102
- onClick={() => handleAction(primaryOption.key)}
103
- >
104
- {translate(primaryOption.titleTranslationKey, primaryOption.titleDefault)}
105
- </PrimaryButton>
106
- {dropdownOptions.length > 0 && (
107
- <ChevronButton
102
+ <ConnectMCPButtonWrapper data-component-name="Buttons/ConnectMCPButton">
103
+ <SplitButton
104
+ variant="secondary"
105
+ placement={placement}
106
+ alignment={alignment}
107
+ closeOnSelect={false}
108
+ toggleAriaLabel={translate('page.actions.connectMcp.moreOptions', 'More options')}
109
+ button={
110
+ <Button
108
111
  variant="secondary"
109
- aria-label={translate('page.actions.connectMcp.moreOptions', 'More options')}
110
- aria-expanded={isOpen}
111
- aria-haspopup="menu"
112
- onClick={() => setIsOpen((prev) => !prev)}
112
+ icon={
113
+ showPrimaryCopied ? (
114
+ <CheckmarkFilledIcon color="var(--color-success-base)" />
115
+ ) : (
116
+ <PrimaryIcon />
117
+ )
118
+ }
119
+ onClick={() => handleAction(primaryOption.key)}
113
120
  >
114
- {isOpen ? <ChevronUpIcon /> : <ChevronDownIcon />}
115
- </ChevronButton>
116
- )}
117
- </SplitButtonGroup>
118
-
119
- {isOpen && dropdownOptions.length > 0 && (
120
- <DropdownWrapper $placement={placement} $alignment={alignment}>
121
- <DropdownMenu>
122
- {dropdownOptions.map((option) => {
123
- const Icon = option.icon;
124
- const showCheckmark = option.key === 'copy' && isCopied;
125
-
126
- return (
127
- <DropdownMenuItem key={option.key} onAction={() => handleMenuAction(option.key)}>
128
- <MenuItemContent>
129
- <MenuItemIcon>
130
- {showCheckmark ? (
131
- <CheckmarkFilledIcon color="var(--color-success-base)" />
132
- ) : (
133
- <Icon />
134
- )}
135
- </MenuItemIcon>
136
- <MenuItemText>
137
- <MenuItemTitle>
138
- {translate(option.titleTranslationKey, option.titleDefault)}
139
- </MenuItemTitle>
140
- <MenuItemDescription>
141
- {translate(option.descriptionTranslationKey, option.descriptionDefault)}
142
- </MenuItemDescription>
143
- </MenuItemText>
144
- </MenuItemContent>
145
- </DropdownMenuItem>
146
- );
147
- })}
148
- </DropdownMenu>
149
- </DropdownWrapper>
150
- )}
121
+ {translate(primaryOption.titleTranslationKey, primaryOption.titleDefault)}
122
+ </Button>
123
+ }
124
+ >
125
+ {dropdownOptions.length > 0
126
+ ? ({ close }: { close: () => void }) => (
127
+ <DropdownMenu>
128
+ {dropdownOptions.map((option) => {
129
+ const Icon = option.icon;
130
+ const showCheckmark = copiedOption === option.key;
131
+
132
+ return (
133
+ <DropdownMenuItem
134
+ key={option.key}
135
+ onAction={() => {
136
+ handleAction(option.key);
137
+ if (!COPY_OPTIONS.includes(option.key)) {
138
+ close();
139
+ }
140
+ }}
141
+ >
142
+ <DropdownMenuItemContent
143
+ icon={
144
+ showCheckmark ? (
145
+ <CheckmarkFilledIcon color="var(--color-success-base)" />
146
+ ) : (
147
+ <Icon />
148
+ )
149
+ }
150
+ title={translate(option.titleTranslationKey, option.titleDefault)}
151
+ description={translate(
152
+ option.descriptionTranslationKey,
153
+ option.descriptionDefault,
154
+ )}
155
+ />
156
+ </DropdownMenuItem>
157
+ );
158
+ })}
159
+ </DropdownMenu>
160
+ )
161
+ : null}
162
+ </SplitButton>
151
163
  </ConnectMCPButtonWrapper>
152
164
  );
153
165
  }
@@ -156,72 +168,3 @@ const ConnectMCPButtonWrapper = styled.div`
156
168
  display: inline-block;
157
169
  position: relative;
158
170
  `;
159
-
160
- const SplitButtonGroup = styled.div`
161
- display: inline-flex;
162
- align-items: stretch;
163
- `;
164
-
165
- const PrimaryButton = styled(Button)`
166
- --button-gap: var(--connect-mcp-button-gap);
167
- border-top-right-radius: 0;
168
- border-bottom-right-radius: 0;
169
- `;
170
-
171
- const ChevronButton = styled(Button)`
172
- border-top-left-radius: 0;
173
- border-bottom-left-radius: 0;
174
- border-left: none;
175
- padding-inline: var(--connect-mcp-button-chevron-padding-inline);
176
- `;
177
-
178
- const DropdownWrapper = styled.div<{ $placement?: string; $alignment?: string }>`
179
- position: absolute;
180
- top: ${({ $placement }) => ($placement === 'top' ? 'auto' : '100%')};
181
- bottom: ${({ $placement }) => ($placement === 'top' ? '100%' : 'auto')};
182
- left: ${({ $alignment }) => ($alignment === 'start' ? '0' : 'auto')};
183
- right: ${({ $alignment }) => ($alignment === 'end' ? '0' : 'auto')};
184
- padding-top: var(--dropdown-menu-padding-top);
185
- z-index: var(--dropdown-menu-z-index);
186
- `;
187
-
188
- const MenuItemContent = styled.div`
189
- display: flex;
190
- align-items: center;
191
- gap: var(--connect-mcp-button-menu-item-gap);
192
- padding: var(--connect-mcp-button-menu-item-padding-block)
193
- var(--connect-mcp-button-menu-item-padding-inline);
194
- `;
195
-
196
- const MenuItemIcon = styled.div`
197
- display: flex;
198
- align-items: center;
199
- justify-content: center;
200
- width: var(--connect-mcp-button-menu-item-icon-size);
201
- height: var(--connect-mcp-button-menu-item-icon-size);
202
- flex-shrink: 0;
203
- border: var(--connect-mcp-button-menu-item-icon-border);
204
- border-radius: var(--connect-mcp-button-menu-item-icon-border-radius);
205
- color: var(--connect-mcp-button-menu-item-icon-color);
206
- `;
207
-
208
- const MenuItemText = styled.div`
209
- display: flex;
210
- flex-direction: column;
211
- gap: var(--connect-mcp-button-menu-item-text-gap);
212
- flex: 1;
213
- `;
214
-
215
- const MenuItemTitle = styled.div`
216
- font-size: var(--connect-mcp-button-menu-item-title-font-size);
217
- font-weight: var(--connect-mcp-button-menu-item-title-font-weight);
218
- line-height: var(--connect-mcp-button-menu-item-title-line-height);
219
- color: var(--connect-mcp-button-menu-item-title-color);
220
- `;
221
-
222
- const MenuItemDescription = styled.div`
223
- font-size: var(--connect-mcp-button-menu-item-description-font-size);
224
- font-weight: var(--connect-mcp-button-menu-item-description-font-weight);
225
- line-height: var(--connect-mcp-button-menu-item-description-line-height);
226
- color: var(--connect-mcp-button-menu-item-description-color);
227
- `;
@@ -1,4 +1,4 @@
1
- import React, { memo } from 'react';
1
+ import React, { memo, useEffect, useRef } from 'react';
2
2
 
3
3
  import type { JSX } from 'react';
4
4
  import type { TooltipProps } from '@redocly/theme/core/types';
@@ -52,11 +52,23 @@ function CopyButtonComponent({
52
52
  const { useTranslate } = useThemeHooks();
53
53
  const tooltip = useControl();
54
54
  const { translate } = useTranslate();
55
+ const closeTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
56
+
57
+ useEffect(() => {
58
+ return () => {
59
+ if (closeTimerRef.current) {
60
+ clearTimeout(closeTimerRef.current);
61
+ }
62
+ };
63
+ }, []);
55
64
 
56
65
  const showTooltip = (duration: number = 1500): void => {
57
66
  tooltip.handleOpen();
58
67
 
59
- setTimeout(() => {
68
+ if (closeTimerRef.current) {
69
+ clearTimeout(closeTimerRef.current);
70
+ }
71
+ closeTimerRef.current = setTimeout(() => {
60
72
  tooltip.handleClose();
61
73
  }, duration);
62
74
  };
@@ -46,49 +46,7 @@ export const aiAssistantButton = css`
46
46
 
47
47
  /* Transition */
48
48
  --ai-assistant-button-transition: box-shadow 0.3s ease, transform 0.2s ease;
49
- `;
50
- /* eslint-enable theme/no-raw-colors-in-styles */
51
-
52
- export const connectMCPButton = css`
53
- /**
54
- * @tokens Connect MCP Button
55
- * @presenter Color
56
- */
57
-
58
- /* Button gap */
59
- --connect-mcp-button-gap: var(--spacing-xs);
60
49
 
61
- /* Chevron button */
62
- --connect-mcp-button-chevron-padding-inline: var(--spacing-xs);
63
-
64
- /* Menu item layout */
65
- --connect-mcp-button-menu-item-gap: var(--spacing-sm);
66
- --connect-mcp-button-menu-item-padding-block: var(--spacing-xxs);
67
- --connect-mcp-button-menu-item-padding-inline: 0;
68
-
69
- /* Menu item icon */
70
- --connect-mcp-button-menu-item-icon-size: 32px;
71
- --connect-mcp-button-menu-item-icon-border-color: var(--border-color-secondary);
72
- --connect-mcp-button-menu-item-icon-border-style: solid;
73
- --connect-mcp-button-menu-item-icon-border-width: 1px;
74
- --connect-mcp-button-menu-item-icon-border: var(--connect-mcp-button-menu-item-icon-border-width)
75
- var(--connect-mcp-button-menu-item-icon-border-style)
76
- var(--connect-mcp-button-menu-item-icon-border-color);
77
- --connect-mcp-button-menu-item-icon-border-radius: var(--border-radius);
78
- --connect-mcp-button-menu-item-icon-color: var(--icon-color-secondary);
79
-
80
- /* Menu item text */
81
- --connect-mcp-button-menu-item-text-gap: var(--spacing-xxs);
82
-
83
- /* Menu item title */
84
- --connect-mcp-button-menu-item-title-font-size: var(--font-size-base);
85
- --connect-mcp-button-menu-item-title-font-weight: var(--font-weight-regular);
86
- --connect-mcp-button-menu-item-title-line-height: var(--line-height-base);
87
- --connect-mcp-button-menu-item-title-color: var(--text-color-secondary);
88
-
89
- /* Menu item description */
90
- --connect-mcp-button-menu-item-description-font-size: var(--font-size-sm);
91
- --connect-mcp-button-menu-item-description-font-weight: var(--font-weight-regular);
92
- --connect-mcp-button-menu-item-description-line-height: var(--line-height-sm);
93
- --connect-mcp-button-menu-item-description-color: var(--text-color-description);
50
+ // @tokens End
94
51
  `;
52
+ /* eslint-enable theme/no-raw-colors-in-styles */
@@ -88,6 +88,7 @@ export function CatalogEntities(props: CatalogEntitiesProps): JSX.Element {
88
88
  (query.isPlaceholderData && entities && entities.length >= LOAD_MORE_THRESHOLD);
89
89
 
90
90
  useEffect(() => {
91
+ // oxlint-disable-next-line react-you-might-not-need-an-effect/no-pass-data-to-parent -- the entities query lives in this ejectable component; the fetched total is mirrored up so the portal page header can show the count
91
92
  setEntitiesCounter(total || 0);
92
93
  }, [total, setEntitiesCounter]);
93
94
 
@@ -45,7 +45,7 @@ export function CatalogEntityLinks({ entity }: CatalogEntityLinksProps) {
45
45
  const LinksWrapper = styled.div`
46
46
  display: flex;
47
47
  flex-direction: column;
48
- border-radius: var(--border-radius);
48
+ border-radius: var(--border-radius-xl);
49
49
  background-color: var(--catalog-metadata-bg-color);
50
50
  transition: all 0.2s ease-in-out;
51
51
  margin: var(--spacing-lg) 0;
@@ -82,7 +82,7 @@ const JsonViewerWrapper = styled(JsonViewer)`
82
82
  const MetadataWrapper = styled.div`
83
83
  display: flex;
84
84
  flex-direction: column;
85
- border-radius: var(--border-radius);
85
+ border-radius: var(--border-radius-xl);
86
86
  background-color: var(--catalog-metadata-bg-color);
87
87
  transition: all 0.2s ease-in-out;
88
88
  margin-bottom: var(--spacing-base);
@@ -49,7 +49,7 @@ const PathLabel = styled.label`
49
49
  const LinksWrapper = styled.div`
50
50
  display: flex;
51
51
  flex-direction: column;
52
- border-radius: var(--border-radius);
52
+ border-radius: var(--border-radius-xl);
53
53
  background-color: var(--catalog-metadata-bg-color);
54
54
  transition: all 0.2s ease-in-out;
55
55
  margin: 0 0 var(--spacing-base) 0;
@@ -1,4 +1,4 @@
1
- import React, { JSX, useState, useEffect, useMemo } from 'react';
1
+ import React, { JSX, useState, useMemo } from 'react';
2
2
 
3
3
  import type { CatalogEntityConfig, EntitiesCatalogConfig } from '@redocly/config';
4
4
  import type { BffCatalogEntity, BffCatalogRelatedEntityList } from '@redocly/theme/core/types';
@@ -35,10 +35,12 @@ export function CatalogEntityRelations({
35
35
  const { sortOption, setSortOption, handleSortClick, isColumnSorted } = useCatalogSort();
36
36
 
37
37
  const [filter, setFilter] = useState<string | undefined>(ENTITY_DEFAULT_FILTERS[entity.type]);
38
+ const [prevEntityKey, setPrevEntityKey] = useState(entity.key);
38
39
 
39
- useEffect(() => {
40
- setFilter(ENTITY_DEFAULT_FILTERS[entity.key]);
41
- }, [entity.key]);
40
+ if (prevEntityKey !== entity.key) {
41
+ setPrevEntityKey(entity.key);
42
+ setFilter(ENTITY_DEFAULT_FILTERS[entity.type]);
43
+ }
42
44
 
43
45
  const combinedFilter = useMemo(() => {
44
46
  const baseFilter = filter ?? ENTITY_DEFAULT_FILTERS[entity.type];
@@ -85,7 +85,7 @@ export function CatalogEntitySchema({
85
85
  const MetadataWrapper = styled.div`
86
86
  display: flex;
87
87
  flex-direction: column;
88
- border-radius: var(--border-radius);
88
+ border-radius: var(--border-radius-xl);
89
89
  background-color: var(--catalog-metadata-bg-color);
90
90
  margin-bottom: var(--spacing-lg);
91
91
  `;
@@ -127,6 +127,7 @@ const StyledSelect = styled(Select)<SelectProps>`
127
127
  --select-text-color: var(--filter-select-color);
128
128
  border: 1px solid var(--filter-select-border-color);
129
129
  --select-border-radius: var(--filter-select-border-radius);
130
+ --select-input-border-radius: var(--filter-select-border-radius);
130
131
  padding: var(--filter-select-padding);
131
132
 
132
133
  &:hover {
@@ -1,31 +1,16 @@
1
- import React, { useEffect, useState } from 'react';
1
+ import React from 'react';
2
2
  import styled from 'styled-components';
3
3
 
4
4
  import { TableIcon } from '@redocly/theme/icons/TableIcon/TableIcon';
5
5
  import { CardsIcon } from '@redocly/theme/icons/CardsIcon/CardsIcon';
6
6
  import { CatalogViewMode } from '@redocly/theme/core/types';
7
7
 
8
- function useViewMode(initialViewMode: CatalogViewMode) {
9
- const [viewMode, setViewMode] = useState<CatalogViewMode | null>(null);
10
-
11
- useEffect(() => {
12
- setViewMode(initialViewMode);
13
- }, [initialViewMode]);
14
-
15
- return viewMode;
16
- }
17
-
18
8
  export type CatalogViewModeToggleProps = {
19
9
  viewMode: CatalogViewMode;
20
10
  onViewModeChange: (mode: CatalogViewMode) => void;
21
11
  };
22
12
 
23
- export function CatalogViewModeToggle({
24
- viewMode: initialViewMode,
25
- onViewModeChange,
26
- }: CatalogViewModeToggleProps) {
27
- const viewMode = useViewMode(initialViewMode);
28
-
13
+ export function CatalogViewModeToggle({ viewMode, onViewModeChange }: CatalogViewModeToggleProps) {
29
14
  return (
30
15
  <ViewModeToggleWrapper data-component-name="Catalog/CatalogViewModeToggle">
31
16
  <ViewModeButton
@@ -190,7 +190,7 @@ export const catalog = css`
190
190
  */
191
191
  --catalog-sort-trigger-gap: var(--spacing-xs);
192
192
  --catalog-sort-trigger-padding: 6px 8px;
193
- --catalog-sort-trigger-border-radius: var(--border-radius-md);
193
+ --catalog-sort-trigger-border-radius: var(--border-radius-lg);
194
194
  --catalog-sort-trigger-hover-bg-color: var(--button-bg-color-secondary-hover);
195
195
  --catalog-sort-icon-color: var(--text-color-secondary);
196
196
  --catalog-sort-text-font-size: var(--font-size-sm);
@@ -220,7 +220,7 @@ export const catalog = css`
220
220
  --catalog-card-border-width: var(--border-width);
221
221
  --catalog-card-border-style: var(--border-style);
222
222
  --catalog-card-border-color-hover: var(--border-color-primary);
223
- --catalog-card-border-radius: var(--border-radius-lg);
223
+ --catalog-card-border-radius: var(--border-radius-xl);
224
224
  --catalog-cards-group-margin: 0 0 var(--spacing-base) 0;
225
225
  --catalog-cards-group-gap: var(--spacing-lg);
226
226
 
@@ -229,7 +229,7 @@ export const catalog = css`
229
229
  */
230
230
  --catalog-card-icon-width: 30px;
231
231
  --catalog-card-icon-height: 30px;
232
- --catalog-card-icon-border-radius: 4px;
232
+ --catalog-card-icon-border-radius: var(--border-radius);
233
233
  --catalog-card-icon-bg-color: var(--bg-color);
234
234
  --catalog-card-icon-border-color: var(--border-color-secondary);
235
235
  --catalog-card-icon-border-width: 1px;
@@ -307,7 +307,7 @@ export const catalog = css`
307
307
  --catalog-actions-min-height: 40px;
308
308
  --catalog-actions-bg-color: var(--bg-color-tonal);
309
309
 
310
- --catalog-page-badge-border-radius: var(--border-radius);
310
+ --catalog-page-badge-border-radius: var(--badge-border-radius);
311
311
  --catalog-page-badge-padding: 0 var(--spacing-xs);
312
312
  --catalog-page-badge-font-size: var(--font-size-base);
313
313
  --catalog-page-badge-line-height: var(--line-height-base);
@@ -343,7 +343,7 @@ export const catalog = css`
343
343
  */
344
344
  --catalog-table-icon-width: 32px;
345
345
  --catalog-table-icon-height: 32px;
346
- --catalog-table-icon-border-radius: 4px;
346
+ --catalog-table-icon-border-radius: var(--border-radius);
347
347
  --catalog-table-icon-bg-color: var(--bg-color-tonal);
348
348
  --catalog-table-icon-border-color: var(--border-color-secondary);
349
349
  --catalog-table-icon-border-width: 1px;