@adecore/ui 0.53.2 → 0.54.0
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/dist/Banner.d.ts +1 -1
- package/dist/ButtonGroup.js +1 -1
- package/dist/Checkbox.js +1 -1
- package/dist/ChoiceCards.d.ts +1 -1
- package/dist/ChoiceCards.js +2 -2
- package/dist/CloseButton.js +1 -1
- package/dist/ColorSwatch.d.ts +1 -1
- package/dist/ColorSwatch.js +1 -1
- package/dist/ColorWheelPicker.js +1 -1
- package/dist/CopyButton.js +1 -1
- package/dist/DockShell.js +1 -1
- package/dist/EmptyState.d.ts +1 -1
- package/dist/EmptyState.js +1 -1
- package/dist/ErrorBoundary.js +122 -112
- package/dist/Field.d.ts +1 -1
- package/dist/Field.js +2 -2
- package/dist/FileIcon.js +1 -1
- package/dist/Icon.d.ts +1 -1
- package/dist/IconButton.d.ts +3 -3
- package/dist/IconButton.js +2 -2
- package/dist/IconPicker.js +35 -32
- package/dist/Input.d.ts +1 -1
- package/dist/ListRow.js +1 -1
- package/dist/MiddleTruncate.js +2 -2
- package/dist/PanelEmpty.d.ts +1 -1
- package/dist/PanelHeader.d.ts +1 -1
- package/dist/PanelHeader.js +1 -1
- package/dist/ProjectSwitcher.js +1 -1
- package/dist/PromptDialog.d.ts +1 -1
- package/dist/ScrollArea.d.ts +12 -0
- package/dist/ScrollArea.js +144 -0
- package/dist/SectionLabel.js +1 -1
- package/dist/SegmentBar.js +1 -1
- package/dist/Segmented.d.ts +1 -1
- package/dist/Select.d.ts +1 -1
- package/dist/Select.js +22 -16
- package/dist/SelectSearch.js +49 -33
- package/dist/ShortcutHints.js +1 -1
- package/dist/Slider.js +2 -2
- package/dist/SlidingColumn.js +1 -1
- package/dist/SplitButton.js +1 -1
- package/dist/Surface.js +1 -1
- package/dist/Switch.js +1 -1
- package/dist/TextMenu.js +2 -2
- package/dist/Toasts.js +2 -2
- package/dist/Tooltip.d.ts +1 -1
- package/dist/Tooltip.js +1 -1
- package/dist/UIProvider.d.ts +1 -1
- package/dist/Waveform.js +1 -1
- package/dist/Wipe.js +2 -2
- package/dist/combobox/parts.d.ts +3 -3
- package/dist/combobox/parts.js +53 -32
- package/dist/command-palette/parts.d.ts +1 -1
- package/dist/command-palette/parts.js +22 -7
- package/dist/command-palette/virtual.js +4 -4
- package/dist/dialog/parts.d.ts +1 -1
- package/dist/dialog/parts.js +2 -2
- package/dist/file-tree/parts.d.ts +2 -2
- package/dist/file-tree/parts.js +3 -3
- package/dist/file-tree/use-file-tree-shift.d.ts +1 -1
- package/dist/file-tree/use-file-tree-shift.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/key-value-list/parts.js +1 -1
- package/dist/menu/parts.d.ts +3 -3
- package/dist/menu/parts.js +46 -30
- package/dist/popover/parts.d.ts +3 -3
- package/dist/popover/parts.js +110 -71
- package/dist/project-switcher-row.js +1 -1
- package/dist/scrollbar-geometry.d.ts +15 -0
- package/dist/scrollbar-geometry.js +48 -0
- package/dist/settings/MasterDetail.js +40 -30
- package/dist/settings/SettingsDialog.d.ts +1 -1
- package/dist/settings/SettingsDialog.js +27 -11
- package/dist/settings/SettingsRow.d.ts +1 -1
- package/dist/settings/SettingsRow.js +1 -1
- package/dist/settings/SettingsSection.d.ts +1 -1
- package/dist/tabs/parts.d.ts +1 -1
- package/dist/tabs/parts.js +3 -3
- package/dist/testing/dedupe.js +1 -1
- package/dist/theme.css +91 -1
- package/dist/tree/parts.js +2 -2
- package/dist/useOverlayScrollbars.d.ts +7 -0
- package/dist/useOverlayScrollbars.js +281 -0
- package/dist/workspace/PaneBar.js +2 -2
- package/dist/workspace/SplitView.d.ts +1 -1
- package/dist/workspace/SplitView.js +4 -4
- package/dist/workspace/TabStrip.d.ts +1 -1
- package/dist/workspace/TabStrip.js +2 -2
- package/dist/workspace/Workspace.d.ts +1 -1
- package/dist/workspace/Workspace.js +2 -2
- package/dist/workspace/WorkspaceRail.js +1 -1
- package/dist/workspace/WorkspaceTopRow.js +1 -1
- package/package.json +1 -1
- package/src/AccentSwatches.tsx +1 -1
- package/src/Banner.tsx +1 -1
- package/src/Button.tsx +1 -1
- package/src/ButtonGroup.tsx +1 -1
- package/src/Checkbox.tsx +2 -2
- package/src/ChoiceCards.tsx +3 -3
- package/src/CloseButton.tsx +2 -2
- package/src/ColorSwatch.tsx +2 -2
- package/src/ColorWheelPicker.tsx +1 -1
- package/src/ColumnResizeHandle.tsx +1 -1
- package/src/CopyButton.tsx +1 -1
- package/src/DockShell.tsx +1 -1
- package/src/EmptyState.tsx +2 -2
- package/src/ErrorBoundary.tsx +4 -3
- package/src/Field.tsx +2 -2
- package/src/FileIcon.tsx +1 -1
- package/src/Icon.tsx +2 -2
- package/src/IconButton.tsx +3 -3
- package/src/IconPicker.tsx +7 -6
- package/src/Input.tsx +2 -2
- package/src/Kbd.tsx +1 -1
- package/src/ListRow.tsx +1 -1
- package/src/Meter.tsx +1 -1
- package/src/MiddleTruncate.tsx +2 -2
- package/src/PanelEmpty.tsx +2 -2
- package/src/PanelHeader.tsx +2 -2
- package/src/Pill.tsx +1 -1
- package/src/ProjectSwitcher.tsx +2 -2
- package/src/PromptDialog.tsx +1 -1
- package/src/RelativeTime.tsx +1 -1
- package/src/ScrollArea.tsx +47 -0
- package/src/SectionLabel.tsx +1 -1
- package/src/SegmentBar.tsx +1 -1
- package/src/Segmented.tsx +1 -1
- package/src/Select.tsx +6 -2
- package/src/SelectSearch.tsx +19 -12
- package/src/Separator.tsx +1 -1
- package/src/ShortcutHints.tsx +1 -1
- package/src/Skeleton.tsx +1 -1
- package/src/Slider.tsx +2 -2
- package/src/SlidingColumn.tsx +1 -1
- package/src/Spinner.tsx +1 -1
- package/src/SplitButton.tsx +1 -1
- package/src/Stepper.tsx +1 -1
- package/src/Surface.tsx +1 -1
- package/src/Switch.tsx +2 -2
- package/src/TextMenu.tsx +2 -2
- package/src/Tile.tsx +1 -1
- package/src/Toasts.tsx +2 -2
- package/src/Tooltip.tsx +2 -2
- package/src/UIProvider.tsx +1 -1
- package/src/Waveform.tsx +1 -1
- package/src/Wipe.tsx +2 -2
- package/src/ZoomControls.tsx +1 -1
- package/src/combobox/parts.tsx +9 -4
- package/src/command-palette/parts.tsx +25 -19
- package/src/command-palette/virtual.tsx +4 -4
- package/src/dialog/parts.tsx +2 -2
- package/src/file-tree/parts.tsx +6 -6
- package/src/file-tree/use-empty-lines.ts +1 -1
- package/src/file-tree/use-file-tree-shift.tsx +2 -2
- package/src/file-tree/use-slots.ts +2 -2
- package/src/index.ts +2 -0
- package/src/key-value-list/parts.tsx +1 -1
- package/src/menu/parts.tsx +11 -6
- package/src/popover/parts.tsx +13 -5
- package/src/project-switcher-row.tsx +2 -2
- package/src/scrollbar-geometry.ts +67 -0
- package/src/select-shared.ts +1 -1
- package/src/settings/DetailHeader.tsx +1 -1
- package/src/settings/MasterDetail.tsx +9 -6
- package/src/settings/SettingsDialog.tsx +16 -9
- package/src/settings/SettingsRow.tsx +1 -1
- package/src/settings/SettingsSection.tsx +1 -1
- package/src/tabs/parts.tsx +4 -4
- package/src/testing/dedupe.ts +1 -1
- package/src/theme.css +91 -1
- package/src/tree/parts.tsx +2 -2
- package/src/useOverlayScrollbars.tsx +263 -0
- package/src/workspace/DropPreview.tsx +1 -1
- package/src/workspace/PaneBar.tsx +2 -2
- package/src/workspace/SplitView.tsx +5 -5
- package/src/workspace/TabStrip.tsx +3 -3
- package/src/workspace/Workspace.tsx +2 -2
- package/src/workspace/WorkspaceRail.tsx +1 -1
- package/src/workspace/WorkspaceTopRow.tsx +1 -1
package/src/ErrorBoundary.tsx
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { Component, type ErrorInfo, type ReactNode } from 'react';
|
|
2
1
|
import clsx from 'clsx';
|
|
3
2
|
import { RotateCw, TriangleAlert } from 'lucide-react';
|
|
3
|
+
import { Component, type ErrorInfo, type ReactNode } from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
import { Button } from './Button.tsx';
|
|
6
6
|
import { ButtonGroup } from './ButtonGroup.tsx';
|
|
7
7
|
import { CopyButton } from './CopyButton.tsx';
|
|
8
8
|
import { errorMessageOf, errorReport, shouldReset, type ResetKeys } from './error-boundary.ts';
|
|
9
9
|
import { Icon } from './Icon.tsx';
|
|
10
|
+
import { ScrollArea } from './ScrollArea.tsx';
|
|
10
11
|
|
|
11
12
|
export interface ErrorBoundaryProps {
|
|
12
13
|
/* The first line of the message: "Could not show this view". */
|
|
@@ -49,7 +50,7 @@ function ErrorFallback({ label, error, componentStack, compact, reload, classNam
|
|
|
49
50
|
const { t } = useTranslation('ui');
|
|
50
51
|
|
|
51
52
|
return (
|
|
52
|
-
<
|
|
53
|
+
<ScrollArea role="alert" className={clsx('bg-surface', className)} viewportClassName={clsx('grid place-items-center', compact ? 'p-3' : 'p-6')}>
|
|
53
54
|
<div className={clsx('flex max-w-[360px] flex-col items-center text-center', compact ? 'gap-1' : 'gap-2')}>
|
|
54
55
|
{!compact && <Icon icon={TriangleAlert} size={20} className="text-status-error" />}
|
|
55
56
|
<p className="text-sm font-medium text-text">{label}</p>
|
|
@@ -69,7 +70,7 @@ function ErrorFallback({ label, error, componentStack, compact, reload, classNam
|
|
|
69
70
|
</ButtonGroup>
|
|
70
71
|
</div>
|
|
71
72
|
</div>
|
|
72
|
-
</
|
|
73
|
+
</ScrollArea>
|
|
73
74
|
);
|
|
74
75
|
}
|
|
75
76
|
|
package/src/Field.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useId, type ReactNode, type Ref } from 'react';
|
|
2
|
-
import clsx from 'clsx';
|
|
3
1
|
import { useRender } from '@base-ui/react/use-render';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { useId, type ReactNode, type Ref } from 'react';
|
|
4
4
|
import { FieldContext } from './field-context.ts';
|
|
5
5
|
import { SectionLabel } from './SectionLabel.tsx';
|
|
6
6
|
|
package/src/FileIcon.tsx
CHANGED
package/src/Icon.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Ref } from 'react';
|
|
2
|
-
import type { LucideIcon } from 'lucide-react';
|
|
3
1
|
import clsx from 'clsx';
|
|
2
|
+
import type { LucideIcon } from 'lucide-react';
|
|
3
|
+
import type { Ref } from 'react';
|
|
4
4
|
|
|
5
5
|
// The whole client draws at this weight. 2 is Lucide's default, but at 12 and 14 pixels next to
|
|
6
6
|
// text of the same size a hair thinner keeps the glyph from outweighing the words beside it.
|
package/src/IconButton.tsx
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
3
|
import type { LucideIcon } from 'lucide-react';
|
|
4
|
-
import {
|
|
4
|
+
import type { ComponentProps, ReactElement, ReactNode } from 'react';
|
|
5
|
+
import { ICON_BUTTON_CLASS, ICON_BUTTON_ICON_SIZE, type IconButtonSize } from './icon-button-size.ts';
|
|
5
6
|
import { Icon } from './Icon.tsx';
|
|
6
7
|
import type { Shortcut } from './shortcut.ts';
|
|
7
8
|
import { Spinner } from './Spinner.tsx';
|
|
8
9
|
import { Tooltip, type TooltipSide } from './Tooltip.tsx';
|
|
9
|
-
import { ICON_BUTTON_CLASS, ICON_BUTTON_ICON_SIZE, type IconButtonSize } from './icon-button-size.ts';
|
|
10
10
|
|
|
11
11
|
export type { IconButtonSize };
|
|
12
12
|
|
package/src/IconPicker.tsx
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { useId, useLayoutEffect, useRef, useState, type KeyboardEvent, type Ref } from 'react';
|
|
2
1
|
import clsx from 'clsx';
|
|
3
2
|
import { Ban, ChevronDown, Search, X } from 'lucide-react';
|
|
3
|
+
import { useId, useLayoutEffect, useRef, useState, type KeyboardEvent, type Ref } from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
import { Button } from './Button.tsx';
|
|
6
6
|
import { EmptyState } from './EmptyState.tsx';
|
|
7
7
|
import { formatNumber } from './format/number.ts';
|
|
8
|
+
import { cellForKey, escapeClearsSearch, filterSections, isGrouped, sectionsOf, tabStopOf, type IconPickerIcons, type IconSection } from './icon-picker.ts';
|
|
8
9
|
import { Icon } from './Icon.tsx';
|
|
9
10
|
import { IconButton } from './IconButton.tsx';
|
|
10
|
-
import { cellForKey, escapeClearsSearch, filterSections, isGrouped, sectionsOf, tabStopOf, type IconPickerIcons, type IconSection } from './icon-picker.ts';
|
|
11
11
|
import { PopoverPopup, PopoverRoot, PopoverTrigger } from './popover/parts.tsx';
|
|
12
|
+
import { ScrollArea } from './ScrollArea.tsx';
|
|
12
13
|
import { SectionLabel } from './SectionLabel.tsx';
|
|
13
14
|
import { Tooltip } from './Tooltip.tsx';
|
|
14
15
|
|
|
@@ -277,12 +278,12 @@ function IconPickerPanel({ id, name, sections, headed, value, keywords, searchab
|
|
|
277
278
|
)}
|
|
278
279
|
</div>
|
|
279
280
|
)}
|
|
280
|
-
<
|
|
281
|
-
|
|
281
|
+
<ScrollArea
|
|
282
|
+
viewportRef={area}
|
|
282
283
|
id={`${id}-grid`}
|
|
283
284
|
role="radiogroup"
|
|
284
285
|
aria-label={name}
|
|
285
|
-
|
|
286
|
+
viewportClassName={clsx('relative overscroll-contain', headed ? 'scroll-pt-7' : 'px-1.5 pt-1.5 pb-2')}
|
|
286
287
|
style={rows === undefined ? undefined : { height: rows * ROW_HEIGHT + (headed ? HEADED_EXTRA : BARE_EXTRA) }}
|
|
287
288
|
onScroll={(event) => markStuckHeadings(event.currentTarget)}
|
|
288
289
|
onKeyDown={moveFocus}
|
|
@@ -342,7 +343,7 @@ function IconPickerPanel({ id, name, sections, headed, value, keywords, searchab
|
|
|
342
343
|
);
|
|
343
344
|
})
|
|
344
345
|
)}
|
|
345
|
-
</
|
|
346
|
+
</ScrollArea>
|
|
346
347
|
{onClear && (
|
|
347
348
|
<div className="flex border-t border-border p-1">
|
|
348
349
|
<Button size="sm" disabled={disabled || value === null} onClick={onClear}>
|
package/src/Input.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ComponentProps, ReactNode } from 'react';
|
|
2
|
-
import type { LucideIcon } from 'lucide-react';
|
|
3
1
|
import clsx from 'clsx';
|
|
2
|
+
import type { LucideIcon } from 'lucide-react';
|
|
3
|
+
import type { ComponentProps, ReactNode } from 'react';
|
|
4
4
|
import { fieldControlProps, useFieldControl } from './field-context.ts';
|
|
5
5
|
import { Icon } from './Icon.tsx';
|
|
6
6
|
|
package/src/Kbd.tsx
CHANGED
package/src/ListRow.tsx
CHANGED
package/src/Meter.tsx
CHANGED
package/src/MiddleTruncate.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { useLayoutEffect, useState, type Ref } from 'react';
|
|
2
1
|
import clsx from 'clsx';
|
|
3
|
-
import {
|
|
2
|
+
import { useLayoutEffect, useState, type Ref } from 'react';
|
|
4
3
|
import { mergeRefs } from './merge-refs.ts';
|
|
4
|
+
import { fitMiddle, type MiddleCut } from './middle-truncate.ts';
|
|
5
5
|
import { Tooltip } from './Tooltip.tsx';
|
|
6
6
|
|
|
7
7
|
export interface MiddleTruncateProps {
|
package/src/PanelEmpty.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ReactNode, Ref } from 'react';
|
|
2
|
-
import type { LucideIcon } from 'lucide-react';
|
|
3
1
|
import clsx from 'clsx';
|
|
2
|
+
import type { LucideIcon } from 'lucide-react';
|
|
3
|
+
import type { ReactNode, Ref } from 'react';
|
|
4
4
|
import { EmptyState } from './EmptyState.tsx';
|
|
5
5
|
|
|
6
6
|
export interface PanelEmptyProps {
|
package/src/PanelHeader.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ReactNode } from 'react';
|
|
2
|
-
import clsx from 'clsx';
|
|
3
1
|
import { useRender } from '@base-ui/react/use-render';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import type { ReactNode } from 'react';
|
|
4
4
|
import { SectionLabel } from './SectionLabel.tsx';
|
|
5
5
|
|
|
6
6
|
export type PanelHeaderProps = useRender.ComponentProps<'header'> & {
|
package/src/Pill.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ReactNode, Ref } from 'react';
|
|
2
1
|
import clsx from 'clsx';
|
|
2
|
+
import type { ReactNode, Ref } from 'react';
|
|
3
3
|
|
|
4
4
|
/* Every ground is an alpha over whatever the pill stands on, the way a border is: a solid sunken ground read as a hole on a dark row. */
|
|
5
5
|
const TONES = {
|
package/src/ProjectSwitcher.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { ComponentProps, MouseEvent, ReactNode, Ref } from 'react';
|
|
2
1
|
import clsx from 'clsx';
|
|
3
|
-
import { useTranslation } from 'react-i18next';
|
|
4
2
|
import { ChevronDown, History } from 'lucide-react';
|
|
3
|
+
import type { ComponentProps, MouseEvent, ReactNode, Ref } from 'react';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
5
5
|
import { Icon } from './Icon.tsx';
|
|
6
6
|
import * as Menu from './menu/index.parts.ts';
|
|
7
7
|
import { ProjectSwitcherRow } from './project-switcher-row.tsx';
|
package/src/PromptDialog.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { LucideIcon } from 'lucide-react';
|
|
1
2
|
import { useState, type ReactNode, type Ref } from 'react';
|
|
2
3
|
import { useTranslation } from 'react-i18next';
|
|
3
|
-
import type { LucideIcon } from 'lucide-react';
|
|
4
4
|
import { Button } from './Button.tsx';
|
|
5
5
|
import { DialogDescription, DialogFooter, DialogPopup, DialogRoot, DialogTitle } from './dialog/parts.tsx';
|
|
6
6
|
import { Field, FormError } from './Field.tsx';
|
package/src/RelativeTime.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Ref } from 'react';
|
|
2
1
|
import clsx from 'clsx';
|
|
2
|
+
import type { Ref } from 'react';
|
|
3
3
|
import { formatAge, formatDayClockWithYear, useFormatLocale } from './format/index.ts';
|
|
4
4
|
import { Tooltip, type TooltipSide } from './Tooltip.tsx';
|
|
5
5
|
import { useNow } from './useNow.ts';
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { useState, type CSSProperties, type Ref } from 'react';
|
|
4
|
+
import { mergeRefs } from './merge-refs.ts';
|
|
5
|
+
import { useOverlayScrollbars, type ScrollAreaAxis } from './useOverlayScrollbars.tsx';
|
|
6
|
+
|
|
7
|
+
export type ScrollAreaProps = Omit<useRender.ComponentProps<'div'>, 'className' | 'ref'> & {
|
|
8
|
+
/* The directions the content scrolls in; the other one clips. */
|
|
9
|
+
axis?: ScrollAreaAxis;
|
|
10
|
+
|
|
11
|
+
/* The outer box, which holds the bars and takes the size. */
|
|
12
|
+
className?: string;
|
|
13
|
+
ref?: Ref<HTMLDivElement>;
|
|
14
|
+
|
|
15
|
+
/* The element that scrolls, for a virtualizer or code that sets the scroll position. */
|
|
16
|
+
viewportRef?: Ref<HTMLElement>;
|
|
17
|
+
|
|
18
|
+
/* Padding and layout of the content. `render` and the remaining props land on the viewport too. */
|
|
19
|
+
viewportClassName?: string;
|
|
20
|
+
|
|
21
|
+
/* Pixels of the bottom edge a layer over the area covers, such as a docked input. The bars end above it. */
|
|
22
|
+
coveredBottom?: number;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/* A box that scrolls natively under thin bars that float over its content and show only while it scrolls. */
|
|
26
|
+
export function ScrollArea({ axis = 'y', className, viewportClassName, viewportRef, coveredBottom, ref, render, ...props }: ScrollAreaProps) {
|
|
27
|
+
const [viewport, setViewport] = useState<HTMLElement | null>(null);
|
|
28
|
+
const scrollbars = useOverlayScrollbars(viewport, { axis });
|
|
29
|
+
|
|
30
|
+
const content = useRender<Record<string, never>, HTMLElement>({
|
|
31
|
+
render,
|
|
32
|
+
ref: mergeRefs<HTMLElement>(setViewport, viewportRef),
|
|
33
|
+
defaultTagName: 'div',
|
|
34
|
+
props: { ...props, 'data-axis': axis, className: clsx('ade-scroll-viewport', viewportClassName) }
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<div
|
|
39
|
+
ref={ref}
|
|
40
|
+
className={clsx('ade-scroll-area', className)}
|
|
41
|
+
style={coveredBottom ? ({ '--scrollbar-covered-bottom': `${coveredBottom}px` } as CSSProperties) : undefined}
|
|
42
|
+
>
|
|
43
|
+
{content}
|
|
44
|
+
{scrollbars}
|
|
45
|
+
</div>
|
|
46
|
+
);
|
|
47
|
+
}
|
package/src/SectionLabel.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import clsx from 'clsx';
|
|
2
1
|
import { useRender } from '@base-ui/react/use-render';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
3
|
|
|
4
4
|
/* A label takes the line height of the row it sits in, which is why the size carries `/[inherit]`. */
|
|
5
5
|
const SECTION_LABEL = 'text-xs/[inherit] font-medium text-text-faint';
|
package/src/SegmentBar.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useEffect, useRef, useState, type Ref } from 'react';
|
|
2
1
|
import clsx from 'clsx';
|
|
2
|
+
import { useEffect, useRef, useState, type Ref } from 'react';
|
|
3
3
|
import { mergeRefs } from './merge-refs.ts';
|
|
4
4
|
import { Tooltip } from './Tooltip.tsx';
|
|
5
5
|
import { useMeasuredWidth } from './useMeasuredWidth.ts';
|
package/src/Segmented.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { KeyboardEvent, Ref } from 'react';
|
|
2
1
|
import clsx from 'clsx';
|
|
3
2
|
import type { LucideIcon } from 'lucide-react';
|
|
3
|
+
import type { KeyboardEvent, Ref } from 'react';
|
|
4
4
|
import { Icon } from './Icon.tsx';
|
|
5
5
|
import { segmentedStop, segmentedTarget } from './segmented-keys.ts';
|
|
6
6
|
import { Tooltip } from './Tooltip.tsx';
|
package/src/Select.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { Ref } from 'react';
|
|
2
1
|
import { Select as BaseSelect } from '@base-ui/react/select';
|
|
3
2
|
import clsx from 'clsx';
|
|
4
3
|
import { ChevronDown } from 'lucide-react';
|
|
4
|
+
import { useState, type Ref } from 'react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
6
|
import { Icon } from './Icon.tsx';
|
|
7
7
|
import { MENU_LABEL } from './menu/parts.tsx';
|
|
@@ -9,6 +9,7 @@ import { renderPositioner } from './popup-layer.ts';
|
|
|
9
9
|
import { RowContent } from './select-row.tsx';
|
|
10
10
|
import { isGroup, rowClassName, triggerClassName, type SelectGroup, type SelectItem } from './select-shared.ts';
|
|
11
11
|
import { SelectSearch } from './SelectSearch.tsx';
|
|
12
|
+
import { useOverlayScrollbars } from './useOverlayScrollbars.tsx';
|
|
12
13
|
|
|
13
14
|
export type { SelectGroup, SelectItem };
|
|
14
15
|
|
|
@@ -74,6 +75,8 @@ function PlainSelect<T extends string>({
|
|
|
74
75
|
const groups = items.length > 0 && isGroup(items[0]!) ? (items as SelectGroup<T>[]) : null;
|
|
75
76
|
const flat = groups ? groups.flatMap((group) => group.items) : (items as SelectItem<T>[]);
|
|
76
77
|
const selected = flat.find((item) => item.value === value) ?? null;
|
|
78
|
+
const [list, setList] = useState<HTMLDivElement | null>(null);
|
|
79
|
+
const scrollbars = useOverlayScrollbars(list);
|
|
77
80
|
|
|
78
81
|
return (
|
|
79
82
|
<BaseSelect.Root
|
|
@@ -99,7 +102,7 @@ function PlainSelect<T extends string>({
|
|
|
99
102
|
alignItemWithTrigger={false}
|
|
100
103
|
>
|
|
101
104
|
<BaseSelect.Popup className="menu-popup">
|
|
102
|
-
<BaseSelect.List className="max-h-80 overflow-auto">
|
|
105
|
+
<BaseSelect.List ref={setList} className="max-h-80 overflow-auto">
|
|
103
106
|
{groups
|
|
104
107
|
? groups.map((group) => (
|
|
105
108
|
<BaseSelect.Group key={group.label}>
|
|
@@ -112,6 +115,7 @@ function PlainSelect<T extends string>({
|
|
|
112
115
|
: flat.map((item) => <Row key={item.value} item={item} picked={item.value === value} />)}
|
|
113
116
|
</BaseSelect.List>
|
|
114
117
|
</BaseSelect.Popup>
|
|
118
|
+
{scrollbars}
|
|
115
119
|
</BaseSelect.Positioner>
|
|
116
120
|
</BaseSelect.Portal>
|
|
117
121
|
</BaseSelect.Root>
|
package/src/SelectSearch.tsx
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { useState } from 'react';
|
|
2
1
|
import { Combobox } from '@base-ui/react/combobox';
|
|
3
2
|
import clsx from 'clsx';
|
|
4
3
|
import { ChevronDown, Search } from 'lucide-react';
|
|
4
|
+
import { useState } from 'react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
6
|
import { Icon } from './Icon.tsx';
|
|
7
7
|
import { MENU_LABEL } from './menu/parts.tsx';
|
|
8
8
|
import { renderPositioner } from './popup-layer.ts';
|
|
9
|
-
import type { SelectProps } from './Select.tsx';
|
|
10
9
|
import { RowContent } from './select-row.tsx';
|
|
11
10
|
import { isGroup, rowClassName, triggerClassName, type SelectGroup, type SelectItem } from './select-shared.ts';
|
|
11
|
+
import type { SelectProps } from './Select.tsx';
|
|
12
|
+
import { useOverlayScrollbars } from './useOverlayScrollbars.tsx';
|
|
12
13
|
|
|
13
14
|
/* The `Select` with a search field on top of its options, for lists too long to scan. A combobox of Base UI brings the filtering and the keyboard. */
|
|
14
15
|
export function SelectSearch<T extends string>({
|
|
@@ -38,6 +39,8 @@ export function SelectSearch<T extends string>({
|
|
|
38
39
|
: flat.map((item) => item.value);
|
|
39
40
|
|
|
40
41
|
const searchLabel = searchPlaceholder ?? t('select.search');
|
|
42
|
+
const [list, setList] = useState<HTMLDivElement | null>(null);
|
|
43
|
+
const scrollbars = useOverlayScrollbars(list);
|
|
41
44
|
|
|
42
45
|
const renderRow = (itemValue: T) => {
|
|
43
46
|
const item = byValue.get(itemValue)!;
|
|
@@ -87,16 +90,20 @@ export function SelectSearch<T extends string>({
|
|
|
87
90
|
/>
|
|
88
91
|
</label>
|
|
89
92
|
<Combobox.Empty className="px-3 py-4 text-center text-xs text-text-faint empty:hidden">{t('select.noMatch', { query })}</Combobox.Empty>
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
<Combobox.
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
93
|
+
{/* Out to the popup's edge on the right, so the bar lies where a menu's does. */}
|
|
94
|
+
<div className="relative -mr-1 flex min-h-0 flex-col">
|
|
95
|
+
<Combobox.List ref={setList} className="min-h-0 overflow-auto pr-1">
|
|
96
|
+
{groups
|
|
97
|
+
? (group: { value: string; items: T[] }) => (
|
|
98
|
+
<Combobox.Group key={group.value} items={group.items}>
|
|
99
|
+
<Combobox.GroupLabel className={MENU_LABEL}>{group.value}</Combobox.GroupLabel>
|
|
100
|
+
<Combobox.Collection>{renderRow}</Combobox.Collection>
|
|
101
|
+
</Combobox.Group>
|
|
102
|
+
)
|
|
103
|
+
: renderRow}
|
|
104
|
+
</Combobox.List>
|
|
105
|
+
{scrollbars}
|
|
106
|
+
</div>
|
|
100
107
|
</Combobox.Popup>
|
|
101
108
|
</Combobox.Positioner>
|
|
102
109
|
</Combobox.Portal>
|
package/src/Separator.tsx
CHANGED
package/src/ShortcutHints.tsx
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useEffect, useLayoutEffect, useRef, useState, type CSSProperties } from 'react';
|
|
2
2
|
import { createPortal } from 'react-dom';
|
|
3
3
|
import { isApplePlatform } from './platform.ts';
|
|
4
|
-
import { formatShortcut } from './shortcut.ts';
|
|
5
4
|
import { ModifierHold, placeHint, shortcutHintTargets } from './shortcut-hints.ts';
|
|
5
|
+
import { formatShortcut } from './shortcut.ts';
|
|
6
6
|
|
|
7
7
|
interface PlacedHint {
|
|
8
8
|
id: number;
|
package/src/Skeleton.tsx
CHANGED
package/src/Slider.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useId, type Ref } from 'react';
|
|
2
|
-
import clsx from 'clsx';
|
|
3
1
|
import { Slider as BaseSlider } from '@base-ui/react/slider';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { useId, type Ref } from 'react';
|
|
4
4
|
import { formatFixed } from './format/number.ts';
|
|
5
5
|
import { placesOf } from './step-places.ts';
|
|
6
6
|
|
package/src/SlidingColumn.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useEffect, useRef, useState, type KeyboardEvent as ReactKeyboardEvent, type ReactNode, type Ref, type RefObject } from 'react';
|
|
2
1
|
import clsx from 'clsx';
|
|
2
|
+
import { useEffect, useRef, useState, type KeyboardEvent as ReactKeyboardEvent, type ReactNode, type Ref, type RefObject } from 'react';
|
|
3
3
|
import { ColumnResizeHandle } from './ColumnResizeHandle.tsx';
|
|
4
4
|
import { mergeRefs } from './merge-refs.ts';
|
|
5
5
|
import { useColumnResize } from './useColumnResize.ts';
|
package/src/Spinner.tsx
CHANGED
package/src/SplitButton.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useState, type ComponentProps, type ReactNode } from 'react';
|
|
2
1
|
import clsx from 'clsx';
|
|
3
2
|
import { ChevronDown } from 'lucide-react';
|
|
3
|
+
import { useState, type ComponentProps, type ReactNode } from 'react';
|
|
4
4
|
import { splitFrameClass, splitHalfClass, type ButtonSize, type ButtonVariant } from './button-class.ts';
|
|
5
5
|
import { Icon } from './Icon.tsx';
|
|
6
6
|
import { MenuPopup, MenuRoot, MenuTrigger, type MenuPopupProps } from './menu/parts.tsx';
|
package/src/Stepper.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Ref } from 'react';
|
|
2
1
|
import clsx from 'clsx';
|
|
3
2
|
import { Minus, Plus } from 'lucide-react';
|
|
3
|
+
import type { Ref } from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
import { ButtonGroup } from './ButtonGroup.tsx';
|
|
6
6
|
import { formatFixed } from './format/number.ts';
|
package/src/Surface.tsx
CHANGED
package/src/Switch.tsx
CHANGED
package/src/TextMenu.tsx
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { useRef, useState, type ComponentProps, type KeyboardEvent as ReactKeyboardEvent, type ReactNode } from 'react';
|
|
2
1
|
import { Copy, Scan } from 'lucide-react';
|
|
2
|
+
import { useRef, useState, type ComponentProps, type KeyboardEvent as ReactKeyboardEvent, type ReactNode } from 'react';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import { copyText } from './clipboard.ts';
|
|
5
5
|
import { Icon } from './Icon.tsx';
|
|
6
6
|
import { Kbd } from './Kbd.tsx';
|
|
7
|
-
import { mergeRefs } from './merge-refs.ts';
|
|
8
7
|
import { ContextMenuRoot, ContextMenuTrigger, MenuItem, MenuPopup, MenuSeparator } from './menu/parts.tsx';
|
|
8
|
+
import { mergeRefs } from './merge-refs.ts';
|
|
9
9
|
import { isApplePlatform } from './platform.ts';
|
|
10
10
|
import { selectAllWithin, selectionWithin } from './selection.ts';
|
|
11
11
|
import { EDIT_SHORTCUTS, matchesShortcut } from './shortcut.ts';
|
package/src/Tile.tsx
CHANGED
package/src/Toasts.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { useState, type ReactNode, type Ref } from 'react';
|
|
2
1
|
import clsx from 'clsx';
|
|
3
|
-
import { useTranslation } from 'react-i18next';
|
|
4
2
|
import { CircleAlert, CircleCheck, Trash, X } from 'lucide-react';
|
|
3
|
+
import { useState, type ReactNode, type Ref } from 'react';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
5
5
|
import { useStore } from 'zustand';
|
|
6
6
|
import { Button } from './Button.tsx';
|
|
7
7
|
import { Icon } from './Icon.tsx';
|
package/src/Tooltip.tsx
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { type ComponentProps, type ReactElement, type ReactNode } from 'react';
|
|
2
1
|
import { Tooltip as BaseTooltip } from '@base-ui/react/tooltip';
|
|
2
|
+
import { type ComponentProps, type ReactElement, type ReactNode } from 'react';
|
|
3
3
|
import { Kbd } from './Kbd.tsx';
|
|
4
|
-
import type { Shortcut } from './shortcut.ts';
|
|
5
4
|
import { registerShortcutHint } from './shortcut-hints.ts';
|
|
5
|
+
import type { Shortcut } from './shortcut.ts';
|
|
6
6
|
|
|
7
7
|
export type TooltipSide = 'top' | 'bottom' | 'left' | 'right';
|
|
8
8
|
|
package/src/UIProvider.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useLayoutEffect, useState, type ReactNode } from 'react';
|
|
2
1
|
import type { i18n as I18n } from 'i18next';
|
|
2
|
+
import { useLayoutEffect, useState, type ReactNode } from 'react';
|
|
3
3
|
import { I18nextProvider } from 'react-i18next';
|
|
4
4
|
import { setFormatSource, type FormatSource } from './format/locale.ts';
|
|
5
5
|
import { addUiResources } from './locales.ts';
|
package/src/Waveform.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useRef, type KeyboardEvent, type PointerEvent, type Ref } from 'react';
|
|
2
1
|
import clsx from 'clsx';
|
|
2
|
+
import { useRef, type KeyboardEvent, type PointerEvent, type Ref } from 'react';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import { formatClockDuration } from './format/duration.ts';
|
|
5
5
|
import { mergeRefs } from './merge-refs.ts';
|
package/src/Wipe.tsx
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { useRef, type KeyboardEvent, type PointerEvent, type ReactNode, type Ref } from 'react';
|
|
2
1
|
import clsx from 'clsx';
|
|
3
2
|
import { ChevronsLeftRight } from 'lucide-react';
|
|
4
|
-
import {
|
|
3
|
+
import { useRef, type KeyboardEvent, type PointerEvent, type ReactNode, type Ref } from 'react';
|
|
5
4
|
import { formatPercent } from './format/number.ts';
|
|
5
|
+
import { Icon } from './Icon.tsx';
|
|
6
6
|
import { mergeRefs } from './merge-refs.ts';
|
|
7
7
|
import { splitAt, splitForKey } from './wipe-split.ts';
|
|
8
8
|
|
package/src/ZoomControls.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Ref } from 'react';
|
|
2
1
|
import clsx from 'clsx';
|
|
3
2
|
import { Maximize, Minus, Plus, Scan, type LucideIcon } from 'lucide-react';
|
|
3
|
+
import type { Ref } from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
import { ButtonGroup } from './ButtonGroup.tsx';
|
|
6
6
|
import { Icon } from './Icon.tsx';
|
package/src/combobox/parts.tsx
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Autocomplete } from '@base-ui/react/autocomplete';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
3
|
import type { LucideIcon } from 'lucide-react';
|
|
4
|
+
import { useState, type ComponentProps, type ReactNode } from 'react';
|
|
4
5
|
import { useTranslation } from 'react-i18next';
|
|
5
|
-
import { Autocomplete } from '@base-ui/react/autocomplete';
|
|
6
6
|
import { withClass } from '../class-name.ts';
|
|
7
7
|
import { fieldControlProps, useFieldControl } from '../field-context.ts';
|
|
8
8
|
import { Icon } from '../Icon.tsx';
|
|
9
9
|
import { Kbd } from '../Kbd.tsx';
|
|
10
10
|
import { MENU_LABEL } from '../menu/parts.tsx';
|
|
11
|
+
import { mergeRefs } from '../merge-refs.ts';
|
|
11
12
|
import { splitPlacement, type PlacementKey } from '../placement.ts';
|
|
12
13
|
import { renderPositioner } from '../popup-layer.ts';
|
|
13
14
|
import type { Shortcut } from '../shortcut.ts';
|
|
15
|
+
import { useOverlayScrollbars } from '../useOverlayScrollbars.tsx';
|
|
14
16
|
|
|
15
17
|
/* It takes no room while it has nothing to say. */
|
|
16
18
|
const LIST_NOTE = 'text-center text-xs text-text-faint not-empty:px-3 not-empty:py-4';
|
|
@@ -63,13 +65,16 @@ type Placement = Pick<ComponentProps<typeof Autocomplete.Positioner>, PlacementK
|
|
|
63
65
|
|
|
64
66
|
export type ComboboxPopupProps = ComponentProps<typeof Autocomplete.Popup> & Placement;
|
|
65
67
|
|
|
66
|
-
export function ComboboxPopup({ side = 'bottom', align = 'start', sideOffset = 6, className, ...props }: ComboboxPopupProps) {
|
|
68
|
+
export function ComboboxPopup({ side = 'bottom', align = 'start', sideOffset = 6, className, ref, ...props }: ComboboxPopupProps) {
|
|
67
69
|
const [placement, popupProps] = splitPlacement(props);
|
|
70
|
+
const [popup, setPopup] = useState<HTMLDivElement | null>(null);
|
|
71
|
+
const scrollbars = useOverlayScrollbars(popup);
|
|
68
72
|
|
|
69
73
|
return (
|
|
70
74
|
<Autocomplete.Portal>
|
|
71
75
|
<Autocomplete.Positioner className="popup-positioner" render={renderPositioner} {...placement} side={side} align={align} sideOffset={sideOffset}>
|
|
72
|
-
<Autocomplete.Popup className={withClass('menu-popup min-w-(--anchor-width)', className)} {...popupProps} />
|
|
76
|
+
<Autocomplete.Popup ref={mergeRefs(setPopup, ref)} className={withClass('menu-popup min-w-(--anchor-width)', className)} {...popupProps} />
|
|
77
|
+
{scrollbars}
|
|
73
78
|
</Autocomplete.Positioner>
|
|
74
79
|
</Autocomplete.Portal>
|
|
75
80
|
);
|