@graphprotocol/gds-react 0.1.0 → 0.1.2
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/README.md +10 -11
- package/dist/GDSProvider.d.ts +6 -3
- package/dist/GDSProvider.d.ts.map +1 -1
- package/dist/GDSProvider.js +14 -6
- package/dist/GDSProvider.js.map +1 -1
- package/dist/components/Address.d.ts.map +1 -1
- package/dist/components/Address.js +8 -6
- package/dist/components/Address.js.map +1 -1
- package/dist/components/Avatar.d.ts +4 -2
- package/dist/components/Avatar.d.ts.map +1 -1
- package/dist/components/Avatar.js +12 -5
- package/dist/components/Avatar.js.map +1 -1
- package/dist/components/Breadcrumbs.parts.d.ts.map +1 -1
- package/dist/components/Breadcrumbs.parts.js +4 -4
- package/dist/components/Breadcrumbs.parts.js.map +1 -1
- package/dist/components/Button.js +11 -7
- package/dist/components/Button.js.map +1 -1
- package/dist/components/Card.js +3 -3
- package/dist/components/Card.js.map +1 -1
- package/dist/components/Checkbox.parts.js +1 -1
- package/dist/components/Checkbox.parts.js.map +1 -1
- package/dist/components/Chip.d.ts +6 -0
- package/dist/components/Chip.d.ts.map +1 -0
- package/dist/components/Chip.js +5 -0
- package/dist/components/Chip.js.map +1 -0
- package/dist/components/Chip.meta.d.ts +17 -0
- package/dist/components/Chip.meta.d.ts.map +1 -0
- package/dist/components/Chip.meta.js +22 -0
- package/dist/components/Chip.meta.js.map +1 -0
- package/dist/components/Chip.parts.d.ts +52 -0
- package/dist/components/Chip.parts.d.ts.map +1 -0
- package/dist/components/Chip.parts.js +122 -0
- package/dist/components/Chip.parts.js.map +1 -0
- package/dist/components/CodeBlock.parts.js +1 -1
- package/dist/components/CodeBlock.parts.js.map +1 -1
- package/dist/components/CopyButton.js +1 -1
- package/dist/components/CopyButton.js.map +1 -1
- package/dist/components/DescriptionList.parts.js +1 -1
- package/dist/components/Keyboard.js +1 -1
- package/dist/components/Label.d.ts.map +1 -1
- package/dist/components/Label.js +1 -1
- package/dist/components/Label.js.map +1 -1
- package/dist/components/Link.d.ts.map +1 -1
- package/dist/components/Link.js +1 -1
- package/dist/components/Link.js.map +1 -1
- package/dist/components/Menu.parts.d.ts.map +1 -1
- package/dist/components/Menu.parts.js +15 -10
- package/dist/components/Menu.parts.js.map +1 -1
- package/dist/components/Modal.parts.js +1 -1
- package/dist/components/Modal.parts.js.map +1 -1
- package/dist/components/OTCInput.js +1 -1
- package/dist/components/OTCInput.js.map +1 -1
- package/dist/components/Search.d.ts +16 -0
- package/dist/components/Search.d.ts.map +1 -0
- package/dist/components/Search.js +129 -0
- package/dist/components/Search.js.map +1 -0
- package/dist/components/Search.meta.d.ts +15 -0
- package/dist/components/Search.meta.d.ts.map +1 -0
- package/dist/components/Search.meta.js +24 -0
- package/dist/components/Search.meta.js.map +1 -0
- package/dist/components/SegmentedControl.parts.d.ts.map +1 -1
- package/dist/components/SegmentedControl.parts.js +16 -28
- package/dist/components/SegmentedControl.parts.js.map +1 -1
- package/dist/components/TabSet.parts.js +3 -3
- package/dist/components/TabSet.parts.js.map +1 -1
- package/dist/components/ToggleButton.d.ts +0 -2
- package/dist/components/ToggleButton.d.ts.map +1 -1
- package/dist/components/ToggleButton.js.map +1 -1
- package/dist/components/Tooltip.parts.d.ts.map +1 -1
- package/dist/components/Tooltip.parts.js +9 -5
- package/dist/components/Tooltip.parts.js.map +1 -1
- package/dist/components/base/ButtonOrLink.parts.d.ts +8 -5
- package/dist/components/base/ButtonOrLink.parts.d.ts.map +1 -1
- package/dist/components/base/ButtonOrLink.parts.js +42 -28
- package/dist/components/base/ButtonOrLink.parts.js.map +1 -1
- package/dist/components/base/Render.d.ts +1 -1
- package/dist/components/base/Render.d.ts.map +1 -1
- package/dist/components/base/Render.js +1 -1
- package/dist/components/base/Render.js.map +1 -1
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +4 -0
- package/dist/components/index.js.map +1 -1
- package/dist/hooks/useCSSProp.js +1 -1
- package/dist/hooks/useCSSProp.js.map +1 -1
- package/dist/hooks/useEffectWithRefDeps.js +1 -1
- package/dist/hooks/useEffectWithRefDeps.js.map +1 -1
- package/dist/hooks/useGDS.d.ts +1 -1
- package/dist/hooks/useNumberInput.js +1 -1
- package/dist/hooks/useNumberInput.js.map +1 -1
- package/dist/hooks/useStyleObserver.js +1 -1
- package/dist/hooks/useStyleObserver.js.map +1 -1
- package/dist/tailwind-plugin.d.ts.map +1 -1
- package/dist/tailwind-plugin.js +5 -0
- package/dist/tailwind-plugin.js.map +1 -1
- package/package.json +19 -18
- package/src/GDSProvider.tsx +31 -14
- package/src/components/Address.tsx +11 -6
- package/src/components/Avatar.tsx +25 -13
- package/src/components/Breadcrumbs.parts.tsx +4 -5
- package/src/components/Button.tsx +16 -6
- package/src/components/Card.tsx +3 -3
- package/src/components/Checkbox.parts.tsx +1 -1
- package/src/components/Chip.meta.ts +23 -0
- package/src/components/Chip.parts.tsx +329 -0
- package/src/components/Chip.tsx +7 -0
- package/src/components/CodeBlock.parts.tsx +3 -3
- package/src/components/CopyButton.tsx +1 -1
- package/src/components/DescriptionList.parts.tsx +1 -1
- package/src/components/Keyboard.tsx +1 -1
- package/src/components/Label.tsx +2 -1
- package/src/components/Link.tsx +2 -1
- package/src/components/Menu.parts.tsx +20 -24
- package/src/components/Modal.parts.tsx +1 -1
- package/src/components/OTCInput.tsx +1 -1
- package/src/components/Search.meta.ts +24 -0
- package/src/components/Search.tsx +238 -0
- package/src/components/SegmentedControl.parts.tsx +38 -40
- package/src/components/TabSet.parts.tsx +3 -3
- package/src/components/ToggleButton.tsx +0 -2
- package/src/components/Tooltip.parts.tsx +14 -4
- package/src/components/base/ButtonOrLink.parts.tsx +65 -34
- package/src/components/base/Render.tsx +1 -1
- package/src/components/index.ts +4 -0
- package/src/hooks/useCSSProp.ts +1 -1
- package/src/hooks/useEffectWithRefDeps.ts +1 -1
- package/src/hooks/useNumberInput.ts +1 -1
- package/src/hooks/useStyleObserver.ts +1 -1
- package/src/tailwind-plugin.ts +5 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { createContext, useContext, type ComponentProps, type ReactNode } from 'react'
|
|
4
|
+
import { Checkbox } from '@base-ui/react/checkbox'
|
|
5
|
+
import { CheckboxGroup } from '@base-ui/react/checkbox-group'
|
|
6
|
+
import { Radio } from '@base-ui/react/radio'
|
|
7
|
+
import { RadioGroup } from '@base-ui/react/radio-group'
|
|
8
|
+
|
|
9
|
+
import type { GDSComponentProps } from '@graphprotocol/gds-css'
|
|
10
|
+
|
|
11
|
+
import { useAutoValue, useCSSPropsPolyfill, useCSSState, useGDS } from '../hooks/index.ts'
|
|
12
|
+
import { cn, getCSSPropsAttributes, splitProps } from '../utils/index.ts'
|
|
13
|
+
import { renderAddon, type AddonValue } from './base/Addon.tsx'
|
|
14
|
+
import { ButtonOrLink, type ButtonOrLinkProps } from './base/ButtonOrLink.tsx'
|
|
15
|
+
import { ChipGroupMeta, ChipMeta } from './Chip.meta.ts'
|
|
16
|
+
|
|
17
|
+
type ExtractFn<T> = T extends (...args: infer A) => infer R ? (...args: A) => R : never
|
|
18
|
+
|
|
19
|
+
export declare namespace ChipProps {
|
|
20
|
+
interface BaseProps extends GDSComponentProps<typeof ChipMeta> {
|
|
21
|
+
/** Name used to submit the chip's value when inside a `<Chip.Group type="checkbox">` in a form. */
|
|
22
|
+
name?: string | undefined
|
|
23
|
+
/** Value used to identify this chip when inside a `<Chip.Group>`. */
|
|
24
|
+
value?: string | undefined
|
|
25
|
+
addonBefore?: AddonValue | undefined
|
|
26
|
+
addonAfter?: AddonValue | undefined
|
|
27
|
+
count?: ReactNode | undefined
|
|
28
|
+
}
|
|
29
|
+
interface ButtonProps
|
|
30
|
+
extends
|
|
31
|
+
BaseProps,
|
|
32
|
+
Omit<ButtonOrLinkProps.ButtonProps, 'value'>,
|
|
33
|
+
ButtonOrLinkProps.DisableableProps {}
|
|
34
|
+
interface LinkProps
|
|
35
|
+
extends BaseProps, ButtonOrLinkProps.LinkProps, ButtonOrLinkProps.DisableableProps {}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type ChipProps = ChipProps.ButtonProps | ChipProps.LinkProps
|
|
39
|
+
|
|
40
|
+
interface ChipGroupContextValue {
|
|
41
|
+
type: 'checkbox' | 'radio'
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const ChipGroupContext = createContext<ChipGroupContextValue | null>(null)
|
|
45
|
+
|
|
46
|
+
export function ChipRoot({
|
|
47
|
+
size,
|
|
48
|
+
name,
|
|
49
|
+
value: passedValue,
|
|
50
|
+
addonBefore,
|
|
51
|
+
addonAfter,
|
|
52
|
+
count,
|
|
53
|
+
disabled = false,
|
|
54
|
+
className,
|
|
55
|
+
style,
|
|
56
|
+
children,
|
|
57
|
+
...props
|
|
58
|
+
}: ChipProps) {
|
|
59
|
+
useGDS()
|
|
60
|
+
|
|
61
|
+
const { rootProps, nestedProps } = splitProps(props)
|
|
62
|
+
|
|
63
|
+
const autoValue = useAutoValue(children)
|
|
64
|
+
const value = passedValue !== undefined ? passedValue : autoValue
|
|
65
|
+
|
|
66
|
+
const groupContext = useContext(ChipGroupContext)
|
|
67
|
+
|
|
68
|
+
const [stateRef, state] = useCSSState({
|
|
69
|
+
pointer: undefined,
|
|
70
|
+
focus: undefined,
|
|
71
|
+
checked: undefined,
|
|
72
|
+
disabled: Boolean(disabled),
|
|
73
|
+
})
|
|
74
|
+
const [cssPropsPolyfillStateRef, cssPropsPolyfillAttributes] = useCSSPropsPolyfill(
|
|
75
|
+
ChipMeta,
|
|
76
|
+
{ size },
|
|
77
|
+
{ ref: stateRef },
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<div
|
|
82
|
+
ref={cssPropsPolyfillStateRef}
|
|
83
|
+
data-type={groupContext?.type ?? 'plain'}
|
|
84
|
+
className={cn(
|
|
85
|
+
`gds-chip root-flex flex-col u:size-max u:max-w-full
|
|
86
|
+
u:has-nested-checked/chip-ref:expose-checked
|
|
87
|
+
u:has-nested-hover/chip-ref:expose-hover
|
|
88
|
+
u:has-nested-focus-visible/chip-ref:expose-focus
|
|
89
|
+
u:has-nested-disabled/chip-ref:expose-disabled
|
|
90
|
+
u:i:has-nested-checked/chip-ref:data-[type=radio]:state-idle`,
|
|
91
|
+
className,
|
|
92
|
+
)}
|
|
93
|
+
{...state.exposedAttributes}
|
|
94
|
+
{...state.polyfillAttributes}
|
|
95
|
+
{...getCSSPropsAttributes(ChipMeta, { size }, style)}
|
|
96
|
+
{...cssPropsPolyfillAttributes}
|
|
97
|
+
{...rootProps}
|
|
98
|
+
>
|
|
99
|
+
{(() => {
|
|
100
|
+
if (!groupContext || props.href !== undefined) {
|
|
101
|
+
return renderButtonOrLink({})
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (groupContext.type === 'checkbox') {
|
|
105
|
+
return (
|
|
106
|
+
<Checkbox.Root
|
|
107
|
+
name={name ?? (undefined as never)}
|
|
108
|
+
value={typeof value === 'string' ? value : (undefined as never)}
|
|
109
|
+
disabled={Boolean(disabled)}
|
|
110
|
+
nativeButton
|
|
111
|
+
render={renderButtonOrLink}
|
|
112
|
+
/>
|
|
113
|
+
)
|
|
114
|
+
} else {
|
|
115
|
+
return (
|
|
116
|
+
<Radio.Root
|
|
117
|
+
value={value}
|
|
118
|
+
disabled={Boolean(disabled)}
|
|
119
|
+
nativeButton
|
|
120
|
+
render={renderButtonOrLink}
|
|
121
|
+
/>
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function renderButtonOrLink({
|
|
126
|
+
tabIndex: _tabIndex,
|
|
127
|
+
defaultChecked: _defaultChecked,
|
|
128
|
+
...renderProps
|
|
129
|
+
}: Parameters<
|
|
130
|
+
ExtractFn<ComponentProps<typeof Checkbox.Root | typeof Radio.Root>['render']>
|
|
131
|
+
>[0]) {
|
|
132
|
+
return (
|
|
133
|
+
<ButtonOrLink
|
|
134
|
+
{...renderProps}
|
|
135
|
+
disabled={disabled}
|
|
136
|
+
className={cn(
|
|
137
|
+
renderProps.className,
|
|
138
|
+
`nested/chip-ref flex grow items-center justify-center
|
|
139
|
+
rounded-full border border-default text-muted transition
|
|
140
|
+
@state-checked/chip:border-brand-muted
|
|
141
|
+
@state-checked/chip:bg-brand-subtlest
|
|
142
|
+
@state-checked/chip:text-default
|
|
143
|
+
@state-hover/chip:border-strong
|
|
144
|
+
@state-hover/chip:text-default
|
|
145
|
+
@state-hover/chip:@state-checked/chip:border-brand-default
|
|
146
|
+
@state-hover/chip:@state-checked/chip:bg-brand-subtler
|
|
147
|
+
@prop-size-small/chip:h-6
|
|
148
|
+
@prop-size-small/chip:px-1
|
|
149
|
+
@prop-size-small/chip:text-12
|
|
150
|
+
@prop-size-medium/chip:h-8
|
|
151
|
+
@prop-size-medium/chip:px-1.5
|
|
152
|
+
@prop-size-medium/chip:text-14
|
|
153
|
+
@prop-size-large/chip:h-10
|
|
154
|
+
@prop-size-large/chip:px-2
|
|
155
|
+
@prop-size-large/chip:text-16
|
|
156
|
+
u:*:transition-opacity
|
|
157
|
+
u:*:@state-disabled/chip:opacity-disabled
|
|
158
|
+
u:*:@state-disabled/chip:grayscale
|
|
159
|
+
u:@prop-size-small/chip:addon-small
|
|
160
|
+
u:@prop-size-medium/chip:addon-medium
|
|
161
|
+
u:@prop-size-large/chip:addon-large
|
|
162
|
+
i:@state-disabled/chip:border-muted
|
|
163
|
+
i:@state-disabled/chip:bg-transparent
|
|
164
|
+
i:@state-disabled/chip:text-muted
|
|
165
|
+
i:@state-disabled/chip:@state-checked/chip:border-transparent
|
|
166
|
+
i:@state-disabled/chip:@state-checked/chip:bg-brand-subtlest`,
|
|
167
|
+
)}
|
|
168
|
+
{...nestedProps}
|
|
169
|
+
>
|
|
170
|
+
{/* Ensure rounded corners are clickable */}
|
|
171
|
+
<span className="absolute inset-0 not-in-clickable:hidden" />
|
|
172
|
+
{addonBefore ? <ChipAddon side="before">{renderAddon(addonBefore)}</ChipAddon> : null}
|
|
173
|
+
<span
|
|
174
|
+
className={`
|
|
175
|
+
flex items-baseline
|
|
176
|
+
@prop-size-small/chip:gap-0.5
|
|
177
|
+
@prop-size-small/chip:px-0.5
|
|
178
|
+
@prop-size-medium/chip:gap-1
|
|
179
|
+
@prop-size-medium/chip:px-1
|
|
180
|
+
@prop-size-large/chip:gap-1
|
|
181
|
+
@prop-size-large/chip:px-1
|
|
182
|
+
`}
|
|
183
|
+
>
|
|
184
|
+
<span className="truncate">{children}</span>
|
|
185
|
+
{count ? (
|
|
186
|
+
<span
|
|
187
|
+
className={`
|
|
188
|
+
max-w-full shrink-0 truncate text-subtle transition
|
|
189
|
+
@state-enabled/chip:@state-checked/chip:text-current
|
|
190
|
+
@state-enabled/chip:@state-hover/chip:text-current
|
|
191
|
+
@prop-size-small/chip:text-10
|
|
192
|
+
@prop-size-medium/chip:text-12
|
|
193
|
+
@prop-size-large/chip:text-14
|
|
194
|
+
`}
|
|
195
|
+
>
|
|
196
|
+
{count}
|
|
197
|
+
</span>
|
|
198
|
+
) : null}
|
|
199
|
+
</span>
|
|
200
|
+
{addonAfter ? <ChipAddon side="after">{renderAddon(addonAfter)}</ChipAddon> : null}
|
|
201
|
+
</ButtonOrLink>
|
|
202
|
+
)
|
|
203
|
+
}
|
|
204
|
+
})()}
|
|
205
|
+
</div>
|
|
206
|
+
)
|
|
207
|
+
}
|
|
208
|
+
ChipRoot.displayName = 'Chip'
|
|
209
|
+
|
|
210
|
+
function ChipAddon({
|
|
211
|
+
side,
|
|
212
|
+
className,
|
|
213
|
+
children,
|
|
214
|
+
...props
|
|
215
|
+
}: ComponentProps<'span'> & { side: 'before' | 'after' }) {
|
|
216
|
+
return (
|
|
217
|
+
<span
|
|
218
|
+
data-side={side}
|
|
219
|
+
className={cn(
|
|
220
|
+
`gds-addon root-flex items-center justify-center u:h-(--gds-addon-size) u:min-w-(--gds-addon-size) u:shrink-0
|
|
221
|
+
u:has-avatar-group:data-[side=after]:ps-0.5
|
|
222
|
+
u:has-tag:data-[side=after]:ps-0.5
|
|
223
|
+
u:has-avatar-group:data-[side=before]:pe-0.5
|
|
224
|
+
u:has-tag:data-[side=before]:pe-0.5`,
|
|
225
|
+
className,
|
|
226
|
+
)}
|
|
227
|
+
{...props}
|
|
228
|
+
>
|
|
229
|
+
{children}
|
|
230
|
+
</span>
|
|
231
|
+
)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export declare namespace ChipGroupProps {
|
|
235
|
+
interface BaseProps
|
|
236
|
+
extends Omit<ComponentProps<'div'>, 'onChange'>, GDSComponentProps<typeof ChipGroupMeta> {}
|
|
237
|
+
interface CheckboxProps extends BaseProps {
|
|
238
|
+
type: 'checkbox'
|
|
239
|
+
name?: undefined
|
|
240
|
+
/** Array of checked/selected chip values. */
|
|
241
|
+
value?: string[] | undefined
|
|
242
|
+
defaultValue?: string[] | undefined
|
|
243
|
+
onChange?: ((value: string[]) => void) | undefined
|
|
244
|
+
}
|
|
245
|
+
interface RadioProps extends BaseProps {
|
|
246
|
+
type: 'radio'
|
|
247
|
+
/** Name used to submit the checked/selected chip value when inside a form. */
|
|
248
|
+
name?: string | undefined
|
|
249
|
+
/** Checked/selected chip value. */
|
|
250
|
+
value?: string | undefined
|
|
251
|
+
defaultValue?: string | undefined
|
|
252
|
+
onChange?: ((value: string) => void) | undefined
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export type ChipGroupProps = ChipGroupProps.CheckboxProps | ChipGroupProps.RadioProps
|
|
257
|
+
|
|
258
|
+
export function ChipGroup({
|
|
259
|
+
ref: passedRef,
|
|
260
|
+
type,
|
|
261
|
+
name,
|
|
262
|
+
value,
|
|
263
|
+
defaultValue,
|
|
264
|
+
onChange,
|
|
265
|
+
size,
|
|
266
|
+
className,
|
|
267
|
+
style,
|
|
268
|
+
children,
|
|
269
|
+
...props
|
|
270
|
+
}: ChipGroupProps) {
|
|
271
|
+
useGDS()
|
|
272
|
+
|
|
273
|
+
if (props['aria-label'] === undefined && props['aria-labelledby'] === undefined) {
|
|
274
|
+
// oxlint-disable-next-line no-console
|
|
275
|
+
console.warn(
|
|
276
|
+
'[Chip.Group] One of `aria-label` or `aria-labelledby` should be set for accessibility',
|
|
277
|
+
)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const [cssPropsPolyfillPassedRef, cssPropsPolyfillAttributes, cssProps] = useCSSPropsPolyfill(
|
|
281
|
+
ChipGroupMeta,
|
|
282
|
+
{ size },
|
|
283
|
+
{ ref: passedRef, returnPropValues: { size } },
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
const sharedProps = {
|
|
287
|
+
ref: cssPropsPolyfillPassedRef,
|
|
288
|
+
'data-size': cssProps.size,
|
|
289
|
+
className: cn(
|
|
290
|
+
`gds-chip-group root-flex u:flex-wrap
|
|
291
|
+
u:data-[size=large]:gap-2
|
|
292
|
+
u:data-[size=medium]:gap-1.5
|
|
293
|
+
u:data-[size=small]:gap-1
|
|
294
|
+
u:**:chip:@prop-size-small/chip-group:prop-size-small
|
|
295
|
+
u:**:chip:@prop-size-medium/chip-group:prop-size-medium
|
|
296
|
+
u:**:chip:@prop-size-large/chip-group:prop-size-large`,
|
|
297
|
+
className,
|
|
298
|
+
),
|
|
299
|
+
...getCSSPropsAttributes(ChipGroupMeta, { size }, style),
|
|
300
|
+
...cssPropsPolyfillAttributes,
|
|
301
|
+
...props,
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return (
|
|
305
|
+
<ChipGroupContext.Provider value={{ type }}>
|
|
306
|
+
{type === 'checkbox' ? (
|
|
307
|
+
<CheckboxGroup
|
|
308
|
+
{...sharedProps}
|
|
309
|
+
{...(value !== undefined && { value })}
|
|
310
|
+
{...(defaultValue !== undefined && { defaultValue })}
|
|
311
|
+
{...(onChange !== undefined && { onValueChange: onChange })}
|
|
312
|
+
>
|
|
313
|
+
{children}
|
|
314
|
+
</CheckboxGroup>
|
|
315
|
+
) : (
|
|
316
|
+
<RadioGroup
|
|
317
|
+
name={name ?? (undefined as never)}
|
|
318
|
+
{...sharedProps}
|
|
319
|
+
{...(value !== undefined && { value })}
|
|
320
|
+
{...(defaultValue !== undefined && { defaultValue })}
|
|
321
|
+
{...(onChange !== undefined && { onValueChange: onChange as (value: unknown) => void })}
|
|
322
|
+
>
|
|
323
|
+
{children}
|
|
324
|
+
</RadioGroup>
|
|
325
|
+
)}
|
|
326
|
+
</ChipGroupContext.Provider>
|
|
327
|
+
)
|
|
328
|
+
}
|
|
329
|
+
ChipGroup.displayName = 'Chip.Group'
|
|
@@ -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 '
|
|
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'
|
|
@@ -189,7 +189,7 @@ export function DescriptionListItem({
|
|
|
189
189
|
<span
|
|
190
190
|
className={`
|
|
191
191
|
absolute inset-y-0 flex items-center justify-center
|
|
192
|
-
not-
|
|
192
|
+
group-not-data-loading/description-list-item:hidden
|
|
193
193
|
@prop-orientation-horizontal/description-list:start-0
|
|
194
194
|
@prop-orientation-vertical/description-list:end-0
|
|
195
195
|
@prop-orientation-vertical/description-list:w-(--gds-addon-size)
|
|
@@ -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-
|
|
75
|
+
empty:after:content-nbsp
|
|
76
76
|
`}
|
|
77
77
|
>
|
|
78
78
|
{childrenArray.map((child, index) => (
|
package/src/components/Label.tsx
CHANGED
|
@@ -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 {
|
package/src/components/Link.tsx
CHANGED
|
@@ -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
|
|
14
|
-
import { useMergedRefs } from '@base-ui
|
|
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 '
|
|
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
|
|
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
|
|
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={
|
|
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
|
|
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
|
|
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
|
|
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
|
+
})
|