Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions packages/@react-spectrum/ai/src/PromptField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,25 +37,24 @@ import {
useRef,
useState
} from 'react';
import {
Direction,
Position,
TokenFieldSegment,
TokenFieldValue,
TokenSegment
} from 'react-stately/useTokenFieldState';
import {DOMRef} from '@react-types/shared';
import {IconContext} from '@react-spectrum/s2';
import {Image, Text} from '@react-spectrum/s2/Card';
// @ts-ignore
import intlMessages from '../intl/*.json';
// @ts-ignore
import {isFileDropItem, useDrop} from 'react-aria-components/useDrop';
import {Link} from '@react-spectrum/s2/Link';
import {Menu, MenuItem, MenuItemProps, MenuTrigger} from '@react-spectrum/s2/Menu';
import Microphone from '@react-spectrum/s2/icons/Microphone';
import {PixelLoader} from './loader/react';
import Plus from '@react-spectrum/s2/icons/Add';
import {Popover, PopoverProps} from '@react-spectrum/s2/Popover';
import {
Position,
TokenFieldSegment,
TokenFieldValue,
TokenSegment
} from 'react-stately/useTokenFieldState';
import {PromptFieldContainer} from './PromptFieldContainer';
import {PromptFocusContext} from './Chat';
import Send from '@react-spectrum/s2/icons/ArrowUpSend';
Expand Down Expand Up @@ -373,7 +372,7 @@ export function PromptTokenField(props: PromptTokenFieldProps) {
if (completionTrigger) {
let filterAnchor = prompt.findText(
prompt.caretPosition,
Direction.Backward,
TokenFieldValue.Direction.Backward,
completionTrigger
);
if (filterAnchor != null) {
Expand Down
57 changes: 39 additions & 18 deletions packages/@react-spectrum/ai/src/ResponseStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,11 @@ const buttonStyles = style({
}
},
display: 'flex',
flexGrow: 1,
flexGrow: 0,
alignItems: 'center',
paddingX: 'calc(self(minHeight) * 3/8 - 1px)',
gap: 'calc(self(minHeight) * 3/8 - 1px)',
minHeight: 32,
width: 'full',
backgroundColor: 'transparent',
transition: 'default',
borderWidth: 0,
Expand Down Expand Up @@ -282,15 +281,15 @@ export interface ResponseStatusPanelProps
styles?: StyleString;
}

const panelStyles = style({
const panelStyle = {
font: 'body',
height: '--disclosure-panel-height',
overflow: 'clip',
transition: {
default: '[height]',
'@media (prefers-reduced-motion: reduce)': 'none'
}
});
} as const;

const panelInner = style({
paddingTop: 8,
Expand All @@ -317,7 +316,10 @@ export const ResponseStatusPanel = forwardRef(function ResponseStatusPanel(
}, [registerPanel]);

return (
<RACDisclosurePanel {...domProps} ref={panelRef} className={mergeStyles(panelStyles, styles)}>
<RACDisclosurePanel
{...domProps}
ref={panelRef}
className={mergeStyles(style(panelStyle), styles)}>
<div className={panelInner}>{props.children}</div>
</RACDisclosurePanel>
);
Expand Down Expand Up @@ -429,6 +431,20 @@ const executionTraceItemStyles = style({
default: 'block',
':last-child': 'none'
}
},
'--execution-trace-item-padding-bottom-disclosure': {
type: 'paddingBottom',
value: {
default: 12,
':last-child': 0
}
},
'--execution-trace-item-padding-bottom-no-disclosure': {
type: 'paddingBottom',
value: {
default: 16,
':last-child': 0
}
}
});

Expand All @@ -447,20 +463,23 @@ const executionTraceItemDividerStyles = style({
display: 'var(--divider-display, flex)'
});

const executionTraceItemBaseStyles = {
paddingBottom: 12,
const executionTraceDisclosurePanelStyles = style({
...panelStyle,
paddingStart: 8
} as const;
});

const executionTraceDisclosureContainerStyles = style({
paddingBottom: 'var(--execution-trace-item-padding-bottom-disclosure)',
marginTop: -4
});

const executionTraceWithoutDisclosureStyles = style({
...executionTraceItemBaseStyles,
paddingStart: 8,
display: 'flex',
flexDirection: 'column',
minHeight: 24
paddingBottom: 'var(--execution-trace-item-padding-bottom-no-disclosure)'
});

const executionTraceDetailPanelStyles = style(executionTraceItemBaseStyles);

/**
* An ExecutionTraceItem represents a single step within an ExecutionTrace, such as
* a tool call or search. When a `detail` is provided, the row can be expanded to reveal it.
Expand Down Expand Up @@ -490,12 +509,14 @@ export const ExecutionTraceItem = forwardRef(function ExecutionTraceItem(
<div role="presentation" className={executionTraceItemDividerStyles} />
</div>
{hasDetail && !isAlwaysOpen ? (
<RACDisclosure>
<DetailTrigger>{children}</DetailTrigger>
<RACDisclosurePanel className={mergeStyles(panelStyles, executionTraceDetailPanelStyles)}>
{detail}
</RACDisclosurePanel>
</RACDisclosure>
<div className={executionTraceDisclosureContainerStyles}>
<RACDisclosure>
<DetailTrigger>{children}</DetailTrigger>
<RACDisclosurePanel className={executionTraceDisclosurePanelStyles}>
{detail}
</RACDisclosurePanel>
</RACDisclosure>
</div>
) : (
<div className={executionTraceWithoutDisclosureStyles}>
<span>{children}</span>
Expand Down
1 change: 1 addition & 0 deletions packages/@react-spectrum/s2/src/Popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export interface PopoverProps
| 'isKeyboardDismissDisabled'
| 'shouldCloseOnInteractOutside'
| 'shouldUpdatePosition'
| 'shouldSkipAnimation'
| 'style'
| 'className'
| 'render'
Expand Down
3 changes: 2 additions & 1 deletion packages/@react-spectrum/s2/src/SideNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,8 @@ const treeRow = style<TreeItemRenderProps & {isLink?: boolean}>({
'--centerPadding': {
type: 'paddingTop',
value: centerPadding()
}
},
transition: 'default'
});

const treeCellGrid = style({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import React from 'react';
import {render} from './utils/render';

describe('ButtonGroup', () => {
it('stacks vertically when the container shrinks below the width of buttons with no-space labels', async () => {
it.skip('stacks vertically when the container shrinks below the width of buttons with no-space labels', async () => {
let {container} = await render(
<div style={{width: '500px'}} data-testid="wrapper">
<ButtonGroup data-testid="button-group">
Expand Down
69 changes: 0 additions & 69 deletions packages/dev/s2-docs/pages/react-aria/DatePicker/useDatePicker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,75 +30,6 @@ import {DatePicker} from 'hooks-starter/DatePicker';
<DatePicker label="Event date" />
```

<details>
<summary>View implementation</summary>

```tsx
"use client";
import React from 'react';
import {useDatePicker, type AriaDatePickerProps} from 'react-aria/useDatePicker';
import {useDatePickerState} from 'react-stately/useDatePickerState';
import type {DateValue} from '@internationalized/date';
import {Provider} from 'react-aria-components/slots';
import {Group, GroupContext} from 'react-aria-components/Group';
import {DateFieldContext} from 'react-aria-components/DateField';
import {ButtonContext} from 'react-aria-components/Button';
import {LabelContext} from 'react-aria-components/Label';
import {CalendarContext} from 'react-aria-components/Calendar';
import {DialogContext, OverlayTriggerStateContext} from 'react-aria-components/Dialog';
import {PopoverContext} from 'react-aria-components/Popover';
import {DateInput, DateSegment} from 'vanilla-starter/DateField';
import {Label, FieldButton} from 'vanilla-starter/Form';
import {Calendar} from 'vanilla-starter/Calendar';
import {Popover} from 'vanilla-starter/Popover';
import {ChevronDown} from 'lucide-react';
import 'vanilla-starter/DatePicker.css';

function DatePicker(props: AriaDatePickerProps<DateValue>) {
// Create state based on the incoming props.
let state = useDatePickerState(props);

// Get props for the child elements from useDatePicker.
let groupRef = React.useRef<HTMLDivElement>(null);
let {groupProps, labelProps, fieldProps, buttonProps, dialogProps, calendarProps} =
useDatePicker(props, state, groupRef);

// Provide the values returned by the hook to the reused components via context.
return (
<Provider
values={[
[GroupContext, {...groupProps, ref: groupRef}],
[DateFieldContext, fieldProps],
[ButtonContext, {...buttonProps, isPressed: state.isOpen}],
[LabelContext, {...labelProps, elementType: 'span'}],
[CalendarContext, calendarProps as any],
[DialogContext, dialogProps],
[OverlayTriggerStateContext, state],
[PopoverContext, {trigger: 'DatePicker', triggerRef: groupRef, placement: 'bottom start'}]
]}>
<div className="react-aria-DatePicker">
<Label>{props.label}</Label>
<Group>
{/* The DateInput builds its own field state from fieldProps, provided via DateFieldContext. */}
<DateInput>{segment => <DateSegment segment={segment} />}</DateInput>
<FieldButton>
<ChevronDown />
</FieldButton>
</Group>
<Popover hideArrow>
{/* Rendered from calendarProps, provided via CalendarContext. */}
<Calendar />
</Popover>
</div>
</Provider>
);
}

<DatePicker label="Event date" />
```

</details>

## API

<Anatomy />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,86 +30,6 @@ import {DateRangePicker} from 'hooks-starter/DateRangePicker';
<DateRangePicker label="Trip dates" />
```

<details>
<summary>View implementation</summary>

```tsx
"use client";
import React from 'react';
import {useDateRangePicker, type AriaDateRangePickerProps} from 'react-aria/useDateRangePicker';
import {useDateRangePickerState} from 'react-stately/useDateRangePickerState';
import type {DateValue} from '@internationalized/date';
import {Provider} from 'react-aria-components/slots';
import {Group, GroupContext} from 'react-aria-components/Group';
import {DateFieldContext} from 'react-aria-components/DateField';
import {ButtonContext} from 'react-aria-components/Button';
import {LabelContext} from 'react-aria-components/Label';
import {RangeCalendarContext} from 'react-aria-components/RangeCalendar';
import {DialogContext, OverlayTriggerStateContext} from 'react-aria-components/Dialog';
import {PopoverContext} from 'react-aria-components/Popover';
import {DateInput, DateSegment} from 'vanilla-starter/DateField';
import {Label, FieldButton} from 'vanilla-starter/Form';
import {RangeCalendar} from 'vanilla-starter/RangeCalendar';
import {Popover} from 'vanilla-starter/Popover';
import {ChevronDown} from 'lucide-react';
import 'vanilla-starter/DateRangePicker.css';

function DateRangePicker(props: AriaDateRangePickerProps<DateValue>) {
// Create state based on the incoming props.
let state = useDateRangePickerState(props);

// Get props for the child elements from useDateRangePicker.
let groupRef = React.useRef<HTMLDivElement>(null);
let {
groupProps,
labelProps,
startFieldProps,
endFieldProps,
buttonProps,
dialogProps,
calendarProps
} = useDateRangePicker(props, state, groupRef);

// Provide the values returned by the hook to the reused components via context.
return (
<Provider
values={[
[GroupContext, {...groupProps, ref: groupRef}],
[ButtonContext, {...buttonProps, isPressed: state.isOpen}],
[LabelContext, {...labelProps, elementType: 'span'}],
[RangeCalendarContext, calendarProps],
[DialogContext, dialogProps],
[OverlayTriggerStateContext, state],
[PopoverContext, {trigger: 'DateRangePicker', triggerRef: groupRef, placement: 'bottom start'}],
// Each DateInput builds its own field state from the start/end slots.
[DateFieldContext, {slots: {start: startFieldProps, end: endFieldProps}}]
]}>
<div className="react-aria-DateRangePicker">
<Label>{props.label}</Label>
<Group className="react-aria-Group inset">
<div className="date-fields">
<DateInput slot="start">{segment => <DateSegment segment={segment} />}</DateInput>
<span aria-hidden="true">–</span>
<DateInput slot="end">{segment => <DateSegment segment={segment} />}</DateInput>
</div>
<FieldButton>
<ChevronDown />
</FieldButton>
</Group>
<Popover hideArrow>
{/* Rendered from calendarProps, provided via RangeCalendarContext. */}
<RangeCalendar />
</Popover>
</div>
</Provider>
);
}

<DateRangePicker label="Trip dates" />
```

</details>

## API

<Anatomy />
Expand Down
4 changes: 2 additions & 2 deletions packages/dev/s2-docs/pages/react-aria/TokenField.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ import {Autocomplete} from 'react-aria-components/Autocomplete';
import {Text} from 'react-aria-components/Text';
import {Token, TokenField} from 'vanilla-starter/TokenField';
import {tokenFieldPositionToDOMRange} from 'react-aria/useTokenField';
import {Direction, TokenFieldValue} from 'react-aria-components/TokenField';
import {TokenFieldValue} from 'react-aria-components/TokenField';
import {Menu, MenuItem} from 'vanilla-starter/Menu';
import {Popover} from 'vanilla-starter/Popover';
import {useMemo, useRef, useState} from 'react';
Expand Down Expand Up @@ -166,7 +166,7 @@ function Example() {
);

let [filterAnchor, filterValue] = useMemo(() => {
let filterAnchor = value.findText(value.caretPosition, Direction.Backward, /(?<=^|\s)[@/]/);
let filterAnchor = value.findText(value.caretPosition, TokenFieldValue.Direction.Backward, /(?<=^|\s)[@/]/);
if (filterAnchor != null) {
let filterValue = value.slice(filterAnchor, value.caretPosition).toString();
return [filterAnchor, filterValue];
Expand Down
Loading
Loading