@graphprotocol/gds-react 0.1.0 → 0.1.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.
Files changed (107) hide show
  1. package/README.md +10 -11
  2. package/dist/GDSProvider.d.ts +6 -3
  3. package/dist/GDSProvider.d.ts.map +1 -1
  4. package/dist/GDSProvider.js +14 -6
  5. package/dist/GDSProvider.js.map +1 -1
  6. package/dist/components/Address.d.ts.map +1 -1
  7. package/dist/components/Address.js +8 -6
  8. package/dist/components/Address.js.map +1 -1
  9. package/dist/components/Avatar.d.ts +4 -2
  10. package/dist/components/Avatar.d.ts.map +1 -1
  11. package/dist/components/Avatar.js +8 -5
  12. package/dist/components/Avatar.js.map +1 -1
  13. package/dist/components/Breadcrumbs.parts.d.ts.map +1 -1
  14. package/dist/components/Breadcrumbs.parts.js +2 -2
  15. package/dist/components/Breadcrumbs.parts.js.map +1 -1
  16. package/dist/components/Button.js +3 -3
  17. package/dist/components/Button.js.map +1 -1
  18. package/dist/components/Card.js +2 -2
  19. package/dist/components/Card.js.map +1 -1
  20. package/dist/components/Checkbox.parts.js +1 -1
  21. package/dist/components/Checkbox.parts.js.map +1 -1
  22. package/dist/components/CodeBlock.parts.js +1 -1
  23. package/dist/components/CodeBlock.parts.js.map +1 -1
  24. package/dist/components/CopyButton.js +1 -1
  25. package/dist/components/CopyButton.js.map +1 -1
  26. package/dist/components/Keyboard.js +1 -1
  27. package/dist/components/Label.d.ts.map +1 -1
  28. package/dist/components/Label.js +1 -1
  29. package/dist/components/Label.js.map +1 -1
  30. package/dist/components/Link.d.ts.map +1 -1
  31. package/dist/components/Link.js +1 -1
  32. package/dist/components/Link.js.map +1 -1
  33. package/dist/components/Menu.parts.d.ts.map +1 -1
  34. package/dist/components/Menu.parts.js +15 -10
  35. package/dist/components/Menu.parts.js.map +1 -1
  36. package/dist/components/Modal.parts.js +1 -1
  37. package/dist/components/Modal.parts.js.map +1 -1
  38. package/dist/components/OTCInput.js +1 -1
  39. package/dist/components/OTCInput.js.map +1 -1
  40. package/dist/components/Search.d.ts +16 -0
  41. package/dist/components/Search.d.ts.map +1 -0
  42. package/dist/components/Search.js +129 -0
  43. package/dist/components/Search.js.map +1 -0
  44. package/dist/components/Search.meta.d.ts +15 -0
  45. package/dist/components/Search.meta.d.ts.map +1 -0
  46. package/dist/components/Search.meta.js +24 -0
  47. package/dist/components/Search.meta.js.map +1 -0
  48. package/dist/components/SegmentedControl.parts.d.ts.map +1 -1
  49. package/dist/components/SegmentedControl.parts.js +9 -10
  50. package/dist/components/SegmentedControl.parts.js.map +1 -1
  51. package/dist/components/TabSet.parts.js +2 -2
  52. package/dist/components/TabSet.parts.js.map +1 -1
  53. package/dist/components/Tooltip.parts.d.ts.map +1 -1
  54. package/dist/components/Tooltip.parts.js +10 -6
  55. package/dist/components/Tooltip.parts.js.map +1 -1
  56. package/dist/components/base/ButtonOrLink.parts.d.ts.map +1 -1
  57. package/dist/components/base/ButtonOrLink.parts.js +23 -12
  58. package/dist/components/base/ButtonOrLink.parts.js.map +1 -1
  59. package/dist/components/base/Render.d.ts +1 -1
  60. package/dist/components/base/Render.d.ts.map +1 -1
  61. package/dist/components/base/Render.js +1 -1
  62. package/dist/components/base/Render.js.map +1 -1
  63. package/dist/components/index.d.ts +2 -0
  64. package/dist/components/index.d.ts.map +1 -1
  65. package/dist/components/index.js +2 -0
  66. package/dist/components/index.js.map +1 -1
  67. package/dist/hooks/useCSSProp.js +1 -1
  68. package/dist/hooks/useCSSProp.js.map +1 -1
  69. package/dist/hooks/useEffectWithRefDeps.js +1 -1
  70. package/dist/hooks/useEffectWithRefDeps.js.map +1 -1
  71. package/dist/hooks/useGDS.d.ts +1 -1
  72. package/dist/hooks/useNumberInput.js +1 -1
  73. package/dist/hooks/useNumberInput.js.map +1 -1
  74. package/dist/hooks/useStyleObserver.js +1 -1
  75. package/dist/hooks/useStyleObserver.js.map +1 -1
  76. package/dist/tailwind-plugin.d.ts.map +1 -1
  77. package/dist/tailwind-plugin.js +2 -0
  78. package/dist/tailwind-plugin.js.map +1 -1
  79. package/package.json +19 -18
  80. package/src/GDSProvider.tsx +31 -14
  81. package/src/components/Address.tsx +11 -6
  82. package/src/components/Avatar.tsx +21 -13
  83. package/src/components/Breadcrumbs.parts.tsx +2 -3
  84. package/src/components/Button.tsx +3 -3
  85. package/src/components/Card.tsx +2 -2
  86. package/src/components/Checkbox.parts.tsx +1 -1
  87. package/src/components/CodeBlock.parts.tsx +3 -3
  88. package/src/components/CopyButton.tsx +1 -1
  89. package/src/components/Keyboard.tsx +1 -1
  90. package/src/components/Label.tsx +2 -1
  91. package/src/components/Link.tsx +2 -1
  92. package/src/components/Menu.parts.tsx +20 -24
  93. package/src/components/Modal.parts.tsx +1 -1
  94. package/src/components/OTCInput.tsx +1 -1
  95. package/src/components/Search.meta.ts +24 -0
  96. package/src/components/Search.tsx +238 -0
  97. package/src/components/SegmentedControl.parts.tsx +10 -11
  98. package/src/components/TabSet.parts.tsx +2 -2
  99. package/src/components/Tooltip.parts.tsx +15 -4
  100. package/src/components/base/ButtonOrLink.parts.tsx +27 -13
  101. package/src/components/base/Render.tsx +1 -1
  102. package/src/components/index.ts +2 -0
  103. package/src/hooks/useCSSProp.ts +1 -1
  104. package/src/hooks/useEffectWithRefDeps.ts +1 -1
  105. package/src/hooks/useNumberInput.ts +1 -1
  106. package/src/hooks/useStyleObserver.ts +1 -1
  107. package/src/tailwind-plugin.ts +2 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphprotocol/gds-react",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "React components for The Graph Design System",
5
5
  "author": "Edge & Node and contributors",
6
6
  "license": "MIT",
@@ -43,42 +43,43 @@
43
43
  "tailwindcss": "^4.1.14"
44
44
  },
45
45
  "dependencies": {
46
- "@base-ui-components/react": "1.0.0-rc.0",
47
- "@base-ui-components/utils": "0.2.2",
48
- "@react-aria/utils": "^3.31.0",
46
+ "@base-ui/react": "^1.0.0",
47
+ "@base-ui/utils": "^0.2.3",
48
+ "@react-aria/utils": "^3.32.0",
49
49
  "@react-hookz/web": "^25.2.0",
50
50
  "@ver0/deep-equal": "^1.0.1",
51
51
  "escape-string-regexp": "^5.0.0",
52
52
  "motion": "^12.23.26",
53
- "react-aria": "^3.44.0",
53
+ "react-aria": "^3.45.0",
54
54
  "react-keyed-flatten-children": "^5.1.1",
55
- "shiki": "^3.19.0",
55
+ "shiki": "^3.20.0",
56
56
  "style-observer": "^0.1.2",
57
57
  "ts-extras": "^0.16.0",
58
58
  "type-fest": "^5.3.1",
59
- "@graphprotocol/gds-css": "0.1.0",
60
- "@graphprotocol/gds-icons": "0.1.0",
59
+ "@graphprotocol/gds-css": "0.1.1",
60
+ "@graphprotocol/gds-icons": "0.1.1",
61
61
  "@graphprotocol/gds-utils": "0.1.0"
62
62
  },
63
63
  "devDependencies": {
64
- "@storybook/addon-themes": "^10.1.6",
65
- "@storybook/addon-vitest": "^10.1.6",
66
- "@storybook/react": "^10.1.6",
67
- "@storybook/react-vite": "^10.1.6",
64
+ "@storybook/addon-themes": "^10.1.9",
65
+ "@storybook/addon-vitest": "^10.1.9",
66
+ "@storybook/react": "^10.1.9",
67
+ "@storybook/react-vite": "^10.1.9",
68
68
  "@svgr/core": "^8.1.0",
69
69
  "@svgr/plugin-jsx": "^8.1.0",
70
70
  "@svgr/plugin-svgo": "^8.1.0",
71
- "@tailwindcss/postcss": "^4.1.17",
72
- "@types/node": "^24.10.2",
71
+ "@tailwindcss/postcss": "^4.1.18",
72
+ "@types/node": "^24.10.4",
73
73
  "@types/react": "^19.2.7",
74
74
  "@types/react-dom": "^19.2.3",
75
75
  "@types/react-is": "^19.2.0",
76
+ "@web3icons/react": "^4.1.7",
76
77
  "lightningcss": "^1.30.2",
77
78
  "postcss": "^8.5.6",
78
- "react": "^19.2.1",
79
- "react-dom": "^19.2.1",
80
- "react-is": "^19.2.1",
81
- "storybook": "^10.1.6",
79
+ "react": "^19.2.3",
80
+ "react-dom": "^19.2.3",
81
+ "react-is": "^19.2.3",
82
+ "storybook": "^10.1.9",
82
83
  "storybook-addon-rtl": "^3.0.1"
83
84
  },
84
85
  "scripts": {
@@ -4,13 +4,15 @@ import {
4
4
  createContext,
5
5
  useEffect,
6
6
  useLayoutEffect,
7
+ useMemo,
7
8
  useRef,
8
9
  useState,
9
10
  type ComponentProps,
10
11
  } from 'react'
11
- import { DirectionProvider } from '@base-ui-components/react/direction-provider'
12
- import { Tooltip } from '@base-ui-components/react/tooltip'
12
+ import { DirectionProvider } from '@base-ui/react/direction-provider'
13
+ import { Tooltip } from '@base-ui/react/tooltip'
13
14
 
15
+ import { ButtonOrLink, type ButtonOrLinkConfigProps } from './components/base/ButtonOrLink.tsx'
14
16
  import { cn } from './utils/index.ts'
15
17
 
16
18
  type Theme = 'dark' | 'light' | 'system'
@@ -48,6 +50,7 @@ export interface GDSProviderProps extends Omit<ComponentProps<'div'>, 'dir'> {
48
50
  direction?: ComponentProps<typeof DirectionProvider>['direction'] | undefined
49
51
  /** Defaults to `en` if `direction` is `ltr`, or `ar` if `direction` is `rtl`. */
50
52
  language?: string | undefined
53
+ buttonOrLinkConfig?: Omit<ButtonOrLinkConfigProps, 'children'> | undefined
51
54
  }
52
55
 
53
56
  export interface GDSContextValue {
@@ -67,7 +70,8 @@ export const GDSContext = createContext<GDSContextValue | null>(null)
67
70
  *
68
71
  * Currently implements:
69
72
  *
70
- * - An easy way to configure the root theme (dark/light/system) and text direction.
73
+ * - An easy way to configure the root theme (dark/light/system), text direction, and `ButtonOrLink`
74
+ * config.
71
75
  * - Space key handler for improved `active` state behavior.
72
76
  * - Shared delay for multiple tooltips (once a tooltip is visible, adjacent tooltips show instantly).
73
77
  *
@@ -87,6 +91,7 @@ export function GDSProvider({
87
91
  theme = DEFAULT_THEME,
88
92
  direction = 'ltr',
89
93
  language = direction === 'rtl' ? 'ar' : 'en',
94
+ buttonOrLinkConfig,
90
95
  children,
91
96
  className,
92
97
  ...props
@@ -203,20 +208,32 @@ export function GDSProvider({
203
208
  }
204
209
  }, [])
205
210
 
211
+ const gdsContextValue = useMemo(
212
+ () => ({
213
+ theme,
214
+ activeTheme,
215
+ direction,
216
+ language,
217
+ }),
218
+ [theme, activeTheme, direction, language],
219
+ )
220
+
206
221
  return (
207
- <GDSContext.Provider value={{ theme, activeTheme, direction, language }}>
222
+ <GDSContext.Provider value={gdsContextValue}>
208
223
  <DirectionProvider direction={direction}>
209
224
  <Tooltip.Provider timeout={300}>
210
- {/* Prevent a flash of incorrect theme in server-side rendered apps (e.g. Next.js) */}
211
- <PreHydrationStyle>{THEME_SSR_CSS[theme]}</PreHydrationStyle>
212
- <div
213
- dir={direction}
214
- lang={language}
215
- className={cn('gds-provider isolate', themeClass, className)}
216
- {...props}
217
- >
218
- {children}
219
- </div>
225
+ <ButtonOrLink.Config {...buttonOrLinkConfig}>
226
+ {/* Prevent a flash of incorrect theme in server-side rendered apps (e.g. Next.js) */}
227
+ <PreHydrationStyle>{THEME_SSR_CSS[theme]}</PreHydrationStyle>
228
+ <div
229
+ dir={direction}
230
+ lang={language}
231
+ className={cn('gds-provider isolate', themeClass, className)}
232
+ {...props}
233
+ >
234
+ {children}
235
+ </div>
236
+ </ButtonOrLink.Config>
220
237
  </Tooltip.Provider>
221
238
  </DirectionProvider>
222
239
  </GDSContext.Provider>
@@ -48,6 +48,8 @@ export function Address({
48
48
  }: AddressProps) {
49
49
  useGDS()
50
50
 
51
+ const { rootProps, nestedProps } = splitProps(props)
52
+
51
53
  const [stateRef, state] = useCSSState({
52
54
  pointer: undefined,
53
55
  focus: undefined,
@@ -59,7 +61,6 @@ export function Address({
59
61
  { variant, size, copy },
60
62
  { ref: stateRef },
61
63
  )
62
- const { rootProps, nestedProps } = splitProps(props)
63
64
 
64
65
  const address = passedAddress || ZERO_ADDRESS
65
66
 
@@ -67,7 +68,7 @@ export function Address({
67
68
  <span
68
69
  ref={cssPropsPolyfillStateRef}
69
70
  className={cn(
70
- `gds-address isolate root-grid *:col-span-full *:row-span-full u:h-max u:w-max u:max-w-full
71
+ `gds-address isolate root-grid *:col-span-full *:row-span-full u:size-max u:max-w-full
71
72
  u:state-[show-copy=false]
72
73
  u:hover:state-[show-copy]
73
74
  u:hover:state-hover
@@ -141,10 +142,14 @@ export function Address({
141
142
  {avatar !== null ? (
142
143
  <Avatar
143
144
  shape="circle"
144
- src={[
145
- ...(avatar ? (Array.isArray(avatar) ? avatar : [avatar]) : []),
146
- createIdenticon(address),
147
- ]}
145
+ src={
146
+ avatar && typeof avatar !== 'string' && !Array.isArray(avatar)
147
+ ? avatar
148
+ : [
149
+ ...(avatar ? (Array.isArray(avatar) ? avatar : [avatar]) : []),
150
+ createIdenticon(address),
151
+ ]
152
+ }
148
153
  alt=""
149
154
  className={`
150
155
  @prop-variant-enclosed/address:-ms-px
@@ -1,6 +1,6 @@
1
1
  'use client'
2
2
 
3
- import { useState } from 'react'
3
+ import { useState, type ReactElement } from 'react'
4
4
  import { useDeepCompareEffect } from '@react-hookz/web'
5
5
 
6
6
  import type { GDSComponentProps } from '@graphprotocol/gds-css'
@@ -20,9 +20,10 @@ export declare namespace AvatarProps {
20
20
  interface BaseProps extends GDSComponentProps<typeof AvatarMeta> {
21
21
  /**
22
22
  * Image source URL or array of URLs to try as fallbacks. If an array is provided, each URL will
23
- * be tried in order until one loads successfully.
23
+ * be tried in order until one loads successfully. Alternatively, this can be a React element
24
+ * (e.g. an icon) for custom avatar content.
24
25
  */
25
- src: string | string[] | undefined
26
+ src: string | string[] | ReactElement | undefined
26
27
  /**
27
28
  * Text used as the avatar's accessible name (e.g. the username or address of the represented
28
29
  * user). Necessary if the avatar is clickable, recommended otherwise (unless the same
@@ -101,8 +102,9 @@ export function Avatar({
101
102
  <span className="nested/avatar-paint pointer-events-none shrink-0">
102
103
  <span
103
104
  className={`
104
- block overflow-clip bg-elevated
105
+ block overflow-clip bg-default
105
106
  group-clickable-focus-visible/avatar:outline
107
+ **:icon:default-size-[60%]
106
108
  @prop-size-xsmall/avatar:size-4
107
109
  @prop-size-small/avatar:size-5
108
110
  @prop-size-medium/avatar:size-6
@@ -112,18 +114,24 @@ export function Avatar({
112
114
  @prop-shape-rounded/avatar:rounded-4
113
115
  @prop-shape-rounded/avatar:@prop-size-xsmall/avatar:rounded-2
114
116
  @prop-shape-rounded/avatar:@prop-size-xlarge/avatar:rounded-8
117
+ uu:*:absolute
118
+ uu:*:inset-0
119
+ uu:*:m-auto
120
+ uu:*:size-full
121
+ uu:*:object-cover
115
122
  `}
116
123
  >
117
124
  {src ? (
118
- <img
119
- src={src}
120
- alt=""
121
- onError={() => setCurrentSourceIndex(currentSourceIndex + 1)}
122
- className={`
123
- absolute top-0 left-0 size-full object-cover
124
- [[src^='data:image/bmp']]:[image-rendering:pixelated]
125
- `}
126
- />
125
+ typeof src === 'string' ? (
126
+ <img
127
+ src={src}
128
+ alt=""
129
+ onError={() => setCurrentSourceIndex(currentSourceIndex + 1)}
130
+ className="[[src^='data:image/bmp']]:[image-rendering:pixelated]"
131
+ />
132
+ ) : (
133
+ src
134
+ )
127
135
  ) : null}
128
136
  {alt ? <span className="sr-only">{alt}</span> : null}
129
137
  </span>
@@ -11,9 +11,9 @@ import {
11
11
  import { isEqual } from '@ver0/deep-equal'
12
12
 
13
13
  import type { GDSComponentProps } from '@graphprotocol/gds-css'
14
+ import { ArrowLeftInteractiveIcon, DotsThreeIcon } from '@graphprotocol/gds-react/icons'
14
15
 
15
16
  import { useCSSPropsPolyfill, useCSSState, useGDS } from '../hooks/index.ts'
16
- import { ArrowLeftInteractiveIcon, DotsThreeIcon } from '../icons/index.generated.ts'
17
17
  import { cn, getCSSPropsAttributes, splitProps } from '../utils/index.ts'
18
18
  import { renderAddon, type AddonValue } from './base/Addon.tsx'
19
19
  import { MaybeButtonOrLink, type MaybeButtonOrLinkProps } from './base/MaybeButtonOrLink.tsx'
@@ -258,6 +258,7 @@ export function BreadcrumbsItem({
258
258
  children,
259
259
  ...props
260
260
  }: BreadcrumbsItemProps) {
261
+ const { rootProps, nestedProps } = splitProps(props)
261
262
  const current = passedCurrent ?? props.href === undefined
262
263
 
263
264
  const [stateRef, state] = useCSSState({
@@ -266,8 +267,6 @@ export function BreadcrumbsItem({
266
267
  current,
267
268
  })
268
269
 
269
- const { rootProps, nestedProps } = splitProps(props)
270
-
271
270
  return (
272
271
  <div
273
272
  ref={stateRef}
@@ -3,9 +3,9 @@
3
3
  import type { ComponentProps } from 'react'
4
4
 
5
5
  import type { GDSComponentProps } from '@graphprotocol/gds-css'
6
+ import { LoadingIcon } from '@graphprotocol/gds-react/icons'
6
7
 
7
8
  import { useCSSPropsPolyfill, useCSSState, useGDS } from '../hooks/index.ts'
8
- import { LoadingIcon } from '../icons/index.generated.ts'
9
9
  import { cn, getCSSPropsAttributes, isReactNode } from '../utils/index.ts'
10
10
  import { renderAddon, type AddonValue } from './base/Addon.tsx'
11
11
  import { ButtonOrLink, type ButtonOrLinkProps } from './base/ButtonOrLink.tsx'
@@ -132,10 +132,10 @@ export function Button({
132
132
  >
133
133
  <span
134
134
  className={`
135
- nested/button-paint pointer-events-none flex h-(--height) grow items-center justify-center
135
+ nested/button-paint pointer-events-none flex h-(--height) max-w-full min-w-full grow items-center justify-center
136
136
  rounded-(--gds-button-radius) border-(length:--border-width) border-(--gds-button-border)
137
137
  bg-(--gds-button-bg) text-(--gds-button-fg) transition [--border-width:1px]
138
- @state-[addon-only=auto]/button:min-w-(--height)
138
+ @state-[addon-only=auto]/button:w-(--height)
139
139
  @prop-variant-naked/button:transition-[color]
140
140
  @prop-variant-naked/button:[--border-width:0px]
141
141
  @prop-size-xsmall/button:px-1.25
@@ -3,9 +3,9 @@
3
3
  import { useId, type ReactNode } from 'react'
4
4
 
5
5
  import type { GDSComponentProps } from '@graphprotocol/gds-css'
6
+ import { ArrowUpRightInteractiveIcon } from '@graphprotocol/gds-react/icons'
6
7
 
7
8
  import { useCSSPropsPolyfill, useCSSState, useGDS } from '../hooks/index.ts'
8
- import { ArrowUpRightInteractiveIcon } from '../icons/index.generated.ts'
9
9
  import { cn, getCSSPropsAttributes, splitProps } from '../utils/index.ts'
10
10
  import { MaybeButtonOrLink, type MaybeButtonOrLinkProps } from './base/MaybeButtonOrLink.tsx'
11
11
  import { CardMeta } from './Card.meta.ts'
@@ -66,6 +66,7 @@ export function Card({
66
66
  autoIcon = true,
67
67
  ...remainingProps
68
68
  } = props as CardProps.ButtonProps | CardProps.LinkProps
69
+ const { rootProps, nestedProps } = splitProps(remainingProps)
69
70
 
70
71
  const [statePassedRef, state] = useCSSState(
71
72
  {
@@ -80,7 +81,6 @@ export function Card({
80
81
  { variant },
81
82
  { ref: statePassedRef },
82
83
  )
83
- const { rootProps, nestedProps } = splitProps(remainingProps)
84
84
 
85
85
  const Element = as ?? 'div'
86
86
  const uniqueId = useId()
@@ -3,9 +3,9 @@
3
3
  import type { ComponentProps, ReactNode } from 'react'
4
4
 
5
5
  import type { GDSComponentProps } from '@graphprotocol/gds-css'
6
+ import { CheckIcon, MinusIcon } from '@graphprotocol/gds-react/icons'
6
7
 
7
8
  import { useControlled, useGDS } from '../hooks/index.ts'
8
- import { CheckIcon, MinusIcon } from '../icons/index.generated.ts'
9
9
  import { cn, splitProps } from '../utils/index.ts'
10
10
  import { Checkable, type CheckableLabelProps } from './base/Checkable.tsx'
11
11
  import type { CheckboxMeta } from './Checkbox.meta.ts'
@@ -19,8 +19,6 @@ import {
19
19
  } from 'shiki'
20
20
 
21
21
  import type { GDSComponentProps } from '@graphprotocol/gds-css'
22
-
23
- import { useControlled, useCSSPropsPolyfill, useGDS } from '../hooks/index.ts'
24
22
  import {
25
23
  EyeClosedIcon,
26
24
  EyeIcon,
@@ -37,7 +35,9 @@ import {
37
35
  FileTsxIcon,
38
36
  FileVueIcon,
39
37
  TerminalIcon,
40
- } from '../icons/index.generated.ts'
38
+ } from '@graphprotocol/gds-react/icons'
39
+
40
+ import { useControlled, useCSSPropsPolyfill, useGDS } from '../hooks/index.ts'
41
41
  import { cn, getCSSPropsAttributes, type Stringifiable } from '../utils/index.ts'
42
42
  import { Button } from './Button.tsx'
43
43
  import { CodeBlockMeta } from './CodeBlock.meta.ts'
@@ -3,9 +3,9 @@
3
3
  import { useRef, useState } from 'react'
4
4
 
5
5
  import type { GDSComponentProps } from '@graphprotocol/gds-css'
6
+ import { CopyInteractiveIcon } from '@graphprotocol/gds-react/icons'
6
7
 
7
8
  import { useGDS } from '../hooks/index.ts'
8
- import { CopyInteractiveIcon } from '../icons/index.generated.ts'
9
9
  import { cn, isReactNode } from '../utils/index.ts'
10
10
  import { Button, type ButtonProps } from './Button.tsx'
11
11
  import type { CopyButtonMeta } from './CopyButton.meta.ts'
@@ -72,7 +72,7 @@ export function Keyboard({
72
72
  @prop-size-large/keyboard:text-14
73
73
  @prop-size-large/keyboard:[--height:--spacing(6)]
74
74
  ${/* Prevent incorrect alignment when empty */ ''}
75
- empty:after:content-(--content-nbsp)
75
+ empty:after:content-nbsp
76
76
  `}
77
77
  >
78
78
  {childrenArray.map((child, index) => (
@@ -30,11 +30,12 @@ export function Label({
30
30
  }: LabelProps) {
31
31
  useGDS()
32
32
 
33
+ const { rootProps, nestedProps } = splitProps(props)
34
+
33
35
  const [cssPropsPolyfillRef, cssPropsPolyfillAttributes] = useCSSPropsPolyfill(LabelMeta, {
34
36
  variant,
35
37
  size,
36
38
  })
37
- const { rootProps, nestedProps } = splitProps(props)
38
39
  const NestedElement = (props.htmlFor ? 'label' : 'span') as 'span'
39
40
 
40
41
  const {
@@ -2,8 +2,9 @@
2
2
 
3
3
  import type { ComponentProps, CSSProperties } from 'react'
4
4
 
5
+ import { ArrowUpRightInteractiveIcon } from '@graphprotocol/gds-react/icons'
6
+
5
7
  import { useCSSPropsPolyfill, useCSSState, useGDS } from '../hooks/index.ts'
6
- import { ArrowUpRightInteractiveIcon } from '../icons/index.generated.ts'
7
8
  import { cn, getCSSPropsAttributes, trimReactNode } from '../utils/index.ts'
8
9
  import { renderAddon, type AddonValue } from './base/Addon.tsx'
9
10
  import { ButtonOrLink, type ButtonOrLinkProps } from './base/ButtonOrLink.tsx'
@@ -10,13 +10,11 @@ import {
10
10
  type ReactElement,
11
11
  type ReactNode,
12
12
  } from 'react'
13
- import { Menu } from '@base-ui-components/react/menu'
14
- import { useMergedRefs } from '@base-ui-components/utils/useMergedRefs'
13
+ import { Menu } from '@base-ui/react/menu'
14
+ import { useMergedRefs } from '@base-ui/utils/useMergedRefs'
15
15
  import type { Merge } from 'type-fest'
16
16
 
17
17
  import { twToPx, type GDSComponentProps } from '@graphprotocol/gds-css'
18
-
19
- import { useAutoValue, useControlled, useCSSState, useGDS } from '../hooks/index.ts'
20
18
  import {
21
19
  ArrowRightInteractiveIcon,
22
20
  ArrowUpRightInteractiveIcon,
@@ -25,7 +23,9 @@ import {
25
23
  LoadingIcon,
26
24
  MagnifyingGlassIcon,
27
25
  XIcon,
28
- } from '../icons/index.generated.ts'
26
+ } from '@graphprotocol/gds-react/icons'
27
+
28
+ import { useAutoValue, useControlled, useCSSState, useGDS } from '../hooks/index.ts'
29
29
  import { cn, type OptionValue } from '../utils/index.ts'
30
30
  import { renderAddon, type AddonValue } from './base/Addon.tsx'
31
31
  import { ButtonOrLink, type ButtonOrLinkProps } from './base/ButtonOrLink.tsx'
@@ -209,8 +209,8 @@ export function MenuRoot<T extends OptionValue>({
209
209
  }}
210
210
  modal={!isNested ? position !== false : (undefined as never)}
211
211
  /**
212
- * This seems to be the only way to disable a `Menu.SubmenuTrigger`. See
213
- * https://github.com/mui/base-ui/issues/1976#issuecomment-2914529452.
212
+ * This seems to be the only way to disable a `Menu.SubmenuTrigger` (see
213
+ * https://github.com/mui/base-ui/issues/1976#issuecomment-2914529452).
214
214
  */
215
215
  disabled={triggerIsElement ? Boolean(trigger.props.disabled) : (undefined as never)}
216
216
  closeParentOnEsc
@@ -219,10 +219,7 @@ export function MenuRoot<T extends OptionValue>({
219
219
  <Trigger
220
220
  nativeButton={isNested ? false : triggerIsElement}
221
221
  openOnHover={position && position.openOnHover !== false}
222
- delay={
223
- (position && typeof position.openOnHover === 'number' ? position.openOnHover : 100) ||
224
- 1 /* 0 is buggy: https://github.com/mui/base-ui/issues/3446 */
225
- }
222
+ delay={position && typeof position.openOnHover === 'number' ? position.openOnHover : 100}
226
223
  data-open-on-hover={Boolean(position && position.openOnHover) || undefined}
227
224
  className={`
228
225
  u:i:open:data-open-on-hover:state-hover
@@ -433,27 +430,26 @@ const MaybePortal = ({
433
430
  ...props
434
431
  }: ComponentProps<'div'> & { position: MenuPosition | false }) => {
435
432
  const containerRef = useRef<HTMLDivElement>(null)
436
- const parentPosition = useContext(MenuItemsContext)?.position
437
433
  const { dirProps } = useGDS()
438
434
 
439
435
  return (
440
436
  <>
441
437
  {/**
442
438
  * Ideally, we simply wouldn't render a `Menu.Portal` or `Menu.Positioner` when `position` is
443
- * `false`, but they are required by Base UI (https://github.com/mui/base-ui/pull/1222). So we hack
444
- * our way around them.
439
+ * `false`, but they are required by Base UI, so we hack our way around them.
445
440
  */}
446
441
  {!position ? <div ref={containerRef} className="contents *:contents" /> : null}
447
- {/**
448
- * If there is a parent menu that is not positioned, we need to specify `document.body` as the
449
- * container of this menu's portal to prevent it from being rendered in the same portal container as
450
- * the parent menu and appearing behind other elements as a result (since nested menus are always
451
- * positioned). The reason we don't use `document.body` for all positioned menus regardless of
452
- * whether it's nested or not is that it prevents the focus from returning to the trigger when the
453
- * menu closes (https://github.com/mui/base-ui/issues/1809).
454
- */}
455
442
  <Menu.Portal
456
- container={!position ? containerRef : parentPosition === false ? document?.body : undefined}
443
+ container={
444
+ !position
445
+ ? containerRef
446
+ : /**
447
+ * Specifying `document.body` because while it is the default for top-level menus, a nested menu
448
+ * defaults to using the same portal as its parent, which is not desirable when the parent is not
449
+ * positioned (it can cause the nested menu to appear behind other elements).
450
+ */
451
+ document?.body
452
+ }
457
453
  >
458
454
  <Menu.Positioner
459
455
  align={position ? position.align : 'start'}
@@ -518,7 +514,7 @@ export function MenuGroup<T extends OptionValue>({
518
514
  <Menu.RadioGroup
519
515
  value={value}
520
516
  defaultValue={defaultValue}
521
- {...(onChange !== undefined ? { onValueChange: onChange } : {})}
517
+ {...(onChange !== undefined && { onValueChange: onChange })}
522
518
  />
523
519
  ) : (
524
520
  <div />
@@ -10,7 +10,7 @@ import {
10
10
  type ReactElement,
11
11
  type ReactNode,
12
12
  } from 'react'
13
- import { Dialog } from '@base-ui-components/react/dialog'
13
+ import { Dialog } from '@base-ui/react/dialog'
14
14
 
15
15
  import type { GDSComponentProps } from '@graphprotocol/gds-css'
16
16
  import { ArrowLeftIcon, XIcon } from '@graphprotocol/gds-react/icons'
@@ -1,7 +1,7 @@
1
1
  'use client'
2
2
 
3
3
  import { useEffect, useRef, useState } from 'react'
4
- import { useMergedRefs } from '@base-ui-components/utils/useMergedRefs'
4
+ import { useMergedRefs } from '@base-ui/utils/useMergedRefs'
5
5
 
6
6
  import { useControlled, useGDS } from '../hooks/index.ts'
7
7
  import { cn } from '../utils/index.ts'
@@ -0,0 +1,24 @@
1
+ import { createComponent } from '@graphprotocol/gds-css'
2
+
3
+ export const SearchMeta = createComponent('Search', {
4
+ cssProps: {
5
+ /** @default 'medium' */
6
+ size: {
7
+ type: 'values',
8
+ values: ['small', 'medium'],
9
+ defaultValue: 'medium',
10
+ },
11
+ /** @default 'full' */
12
+ layout: {
13
+ type: 'values',
14
+ values: ['compact', 'full'],
15
+ defaultValue: 'full',
16
+ },
17
+ },
18
+ vars: {
19
+ 'input-width': {
20
+ '@variant @prop-size-small/search': '--spacing(32)',
21
+ '@variant @prop-size-medium/search': '--spacing(40)',
22
+ },
23
+ },
24
+ })