@jetbrains/ring-ui 8.0.0-beta.7 → 8.0.0-beta.9
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/components/select/select-popup.d.ts +2 -1
- package/components/select/select-popup.js +3 -3
- package/components/select/select.d.ts +2 -0
- package/components/select/select.js +1 -1
- package/components/selection-toolbar/selection-toolbar.css +86 -0
- package/components/selection-toolbar/selection-toolbar.d.ts +11 -0
- package/components/selection-toolbar/selection-toolbar.js +23 -0
- package/components/tooltip/tooltip.d.ts +2 -1
- package/components/tooltip/tooltip.js +4 -3
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { type ComponentType, type CSSProperties, PureComponent, type ReactNode, type Ref, type SyntheticEvent } from 'react';
|
|
5
5
|
import * as React from 'react';
|
|
6
6
|
import { type IconType } from '../icon/icon';
|
|
7
|
-
import Popup from '../popup/popup';
|
|
7
|
+
import Popup, { type PopupAttrs } from '../popup/popup';
|
|
8
8
|
import { type Directions } from '../popup/position';
|
|
9
9
|
import List, { type SelectHandlerParams } from '../list/list';
|
|
10
10
|
import Caret from '../caret/caret';
|
|
@@ -60,6 +60,7 @@ export interface SelectPopupProps<T = unknown> {
|
|
|
60
60
|
ringPopupTarget: string | null;
|
|
61
61
|
onSelectAll: (isSelectAll: boolean) => void;
|
|
62
62
|
onEmptyPopupEnter: (e: KeyboardEvent) => void;
|
|
63
|
+
popupProps?: Partial<PopupAttrs> | undefined;
|
|
63
64
|
className?: string | null | undefined;
|
|
64
65
|
compact?: boolean | null | undefined;
|
|
65
66
|
dir?: 'ltr' | 'rtl' | undefined;
|
|
@@ -323,8 +323,8 @@ export default class SelectPopup extends PureComponent {
|
|
|
323
323
|
right: event => this.handleNavigation(event),
|
|
324
324
|
};
|
|
325
325
|
render() {
|
|
326
|
-
const { toolbar, topbar, className, multiple, hidden, isInputMode, anchorElement, minWidth, onCloseAttempt, onOutsideClick, directions, top, left, offset, style, dir, filter, } = this.props;
|
|
327
|
-
const classes = classNames(styles.popup, className);
|
|
326
|
+
const { toolbar, topbar, className, multiple, hidden, isInputMode, anchorElement, minWidth, onCloseAttempt, onOutsideClick, directions, top, left, offset, style, dir, filter, popupProps, } = this.props;
|
|
327
|
+
const classes = classNames(styles.popup, className, popupProps?.className);
|
|
328
328
|
return (<PopupTargetContext.Consumer>
|
|
329
329
|
{ringPopupTarget => {
|
|
330
330
|
const filterWithTags = this.getFilterWithTags();
|
|
@@ -332,7 +332,7 @@ export default class SelectPopup extends PureComponent {
|
|
|
332
332
|
const list = this.getList(this.props.ringPopupTarget || normalizePopupTarget(ringPopupTarget));
|
|
333
333
|
const bottomLine = this.getBottomLine();
|
|
334
334
|
const hasContent = filterWithTags || selectAll || list || bottomLine || toolbar || topbar;
|
|
335
|
-
return (<Popup trapFocus={false} ref={this.popupRef} hidden={hidden || !hasContent} attached={isInputMode} className={classes} dontCloseOnAnchorClick anchorElement={anchorElement} minWidth={minWidth} onCloseAttempt={onCloseAttempt} onOutsideClick={onOutsideClick} directions={directions} top={top} left={left} offset={offset} onMouseDown={this.mouseDownHandler} target={this.props.ringPopupTarget} autoCorrectTopOverflow={false} style={style} largeBorderRadius>
|
|
335
|
+
return (<Popup {...popupProps} trapFocus={false} ref={this.popupRef} hidden={hidden || !hasContent} attached={isInputMode} className={classes} dontCloseOnAnchorClick anchorElement={anchorElement} minWidth={minWidth} onCloseAttempt={onCloseAttempt} onOutsideClick={onOutsideClick} directions={directions} top={top} left={left} offset={offset} onMouseDown={this.mouseDownHandler} target={this.props.ringPopupTarget} autoCorrectTopOverflow={false} style={{ ...popupProps?.style, ...style }} largeBorderRadius>
|
|
336
336
|
<div dir={dir}>
|
|
337
337
|
{!hidden && filter && <Shortcuts map={this.shortcutsMap} scope={this.shortcutsScope}/>}
|
|
338
338
|
{topbar}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type ButtonHTMLAttributes, Component, type ComponentType, type CSSProperties, type HTMLAttributes, type ReactNode, type Ref, type RefCallback, type SyntheticEvent } from 'react';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
+
import { type PopupAttrs } from '../popup/popup';
|
|
3
4
|
import { type SelectHandlerParams } from '../list/list';
|
|
4
5
|
import { Size } from '../input/input';
|
|
5
6
|
import { type LabelType } from '../control-label/control-label';
|
|
@@ -99,6 +100,7 @@ export interface BaseSelectProps<T = unknown> {
|
|
|
99
100
|
getInitial?: (() => string) | null | undefined;
|
|
100
101
|
minWidth?: number | undefined;
|
|
101
102
|
popupClassName?: string | null | undefined;
|
|
103
|
+
popupProps?: Partial<PopupAttrs> | undefined;
|
|
102
104
|
popupStyle?: CSSProperties | undefined;
|
|
103
105
|
top?: number | undefined;
|
|
104
106
|
left?: number | undefined;
|
|
@@ -454,7 +454,7 @@ export default class Select extends Component {
|
|
|
454
454
|
else if (!shownData.length) {
|
|
455
455
|
message = this.props.notFoundMessage ?? translate('noOptionsFound');
|
|
456
456
|
}
|
|
457
|
-
return (<SelectPopup data={_shownData} message={message} toolbar={showPopup && this.getToolbar()} topbar={this.getTopbar()} loading={this.props.loading} activeIndex={activeIndex} hidden={!showPopup} ref={this.popupRef} maxHeight={this.props.maxHeight} minWidth={this.props.minWidth} directions={this.props.directions} className={this.props.popupClassName} style={this.props.popupStyle} top={this.props.top} left={this.props.left} offset={this.props.offset} filter={this.isInputMode() ? false : this.props.filter} // disable popup filter in INPUT mode
|
|
457
|
+
return (<SelectPopup data={_shownData} message={message} toolbar={showPopup && this.getToolbar()} topbar={this.getTopbar()} loading={this.props.loading} activeIndex={activeIndex} hidden={!showPopup} ref={this.popupRef} maxHeight={this.props.maxHeight} minWidth={this.props.minWidth} directions={this.props.directions} popupProps={this.props.popupProps} className={this.props.popupClassName} style={this.props.popupStyle} top={this.props.top} left={this.props.left} offset={this.props.offset} filter={this.isInputMode() ? false : this.props.filter} // disable popup filter in INPUT mode
|
|
458
458
|
filterIcon={this.props.filterIcon} filterRef={this.props.filterRef} multiple={this.props.multiple} filterValue={this.state.filterValue} anchorElement={anchorElement} onCloseAttempt={this._onCloseAttempt} onOutsideClick={this.props.onOutsideClick} onSelect={this._listSelectHandler} onSelectAll={this._listSelectAllHandler} onFilter={this._filterChangeHandler} onClear={this.clearFilter} onLoadMore={this.props.onLoadMore} isInputMode={this.isInputMode()} selected={this.state.selected} tags={this.props.tags} compact={this.props.compact} renderOptimization={this.props.renderOptimization} ringPopupTarget={this.props.ringPopupTarget} disableMoveOverflow={this.props.disableMoveOverflow} disableScrollToActive={this.props.disableScrollToActive} dir={this.props.dir} onEmptyPopupEnter={this.onEmptyPopupEnter} listId={this.listId} preventListOverscroll={this.props.preventListOverscroll}/>);
|
|
459
459
|
}}
|
|
460
460
|
</I18nContext.Consumer>);
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
@import '../global/variables.css';
|
|
2
|
+
|
|
3
|
+
.toolbar {
|
|
4
|
+
display: inline-flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
|
|
7
|
+
box-sizing: border-box;
|
|
8
|
+
max-width: 100%;
|
|
9
|
+
height: calc(var(--ring-unit) * 5);
|
|
10
|
+
padding: 10px calc(var(--ring-unit) * 2);
|
|
11
|
+
|
|
12
|
+
pointer-events: auto;
|
|
13
|
+
|
|
14
|
+
color: var(--ring-white-text-color);
|
|
15
|
+
border-radius: var(--ring-border-radius-large);
|
|
16
|
+
background-color: var(--ring-sidebar-background-color);
|
|
17
|
+
box-shadow:
|
|
18
|
+
0 2px 8px rgb(0 28 54 / 10%),
|
|
19
|
+
0 1px 2px rgb(0 28 54 / 4%);
|
|
20
|
+
|
|
21
|
+
line-height: var(--ring-line-height);
|
|
22
|
+
gap: calc(var(--ring-unit) * 2);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.content {
|
|
26
|
+
display: flex;
|
|
27
|
+
align-items: center;
|
|
28
|
+
gap: calc(var(--ring-unit) * 3);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.selectAll {
|
|
32
|
+
flex: none;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.actions {
|
|
36
|
+
display: flex;
|
|
37
|
+
align-items: center;
|
|
38
|
+
gap: calc(var(--ring-unit) * 2);
|
|
39
|
+
|
|
40
|
+
min-width: 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.closeAction {
|
|
44
|
+
flex: none;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.separator {
|
|
48
|
+
flex: none;
|
|
49
|
+
|
|
50
|
+
width: 1px;
|
|
51
|
+
height: calc(var(--ring-unit) * 2);
|
|
52
|
+
margin-inline: var(--ring-unit);
|
|
53
|
+
|
|
54
|
+
background-color: var(--ring-line-color);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.compact {
|
|
58
|
+
min-width: 0;
|
|
59
|
+
max-width: 100%;
|
|
60
|
+
padding-inline: 12px;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.compact .content {
|
|
64
|
+
min-width: 0;
|
|
65
|
+
gap: var(--ring-unit);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.compact .label {
|
|
69
|
+
overflow: hidden;
|
|
70
|
+
|
|
71
|
+
flex: 1 1 auto;
|
|
72
|
+
|
|
73
|
+
min-width: 0;
|
|
74
|
+
|
|
75
|
+
white-space: nowrap;
|
|
76
|
+
|
|
77
|
+
text-overflow: ellipsis;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.compact .actions {
|
|
81
|
+
flex-shrink: 1;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.compact .separator {
|
|
85
|
+
margin-inline: 2px;
|
|
86
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ComponentPropsWithRef, type ReactNode } from 'react';
|
|
2
|
+
export interface SelectionToolbarProps extends ComponentPropsWithRef<'div'> {
|
|
3
|
+
label: ReactNode;
|
|
4
|
+
selectAll?: ReactNode;
|
|
5
|
+
closeAction: ReactNode;
|
|
6
|
+
compact?: boolean;
|
|
7
|
+
'data-test'?: string | null;
|
|
8
|
+
}
|
|
9
|
+
export declare function SelectionToolbar({ ref, label, selectAll, closeAction, compact, className, children, 'data-test': dataTest, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, ...restProps }: SelectionToolbarProps): import("react").JSX.Element;
|
|
10
|
+
export declare function SelectionToolbarSeparator(): import("react").JSX.Element;
|
|
11
|
+
export default SelectionToolbar;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useId } from 'react';
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import dataTests from '../global/data-tests';
|
|
4
|
+
import Theme, { ThemeProvider } from '../global/theme';
|
|
5
|
+
import styles from './selection-toolbar.css';
|
|
6
|
+
export function SelectionToolbar({ ref, label, selectAll, closeAction, compact, className, children, 'data-test': dataTest, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, ...restProps }) {
|
|
7
|
+
const labelId = useId();
|
|
8
|
+
const hasSelectAll = selectAll != null;
|
|
9
|
+
return (<ThemeProvider {...restProps} ref={ref} theme={Theme.DARK} role='group' aria-label={ariaLabel} aria-labelledby={ariaLabelledBy ?? (ariaLabel == null ? labelId : undefined)} data-test={dataTests('ring-selection-toolbar', dataTest)} className={classNames(styles.toolbar, { [styles.compact]: compact }, className)}>
|
|
10
|
+
<div className={styles.content}>
|
|
11
|
+
<span id={labelId} className={styles.label}>
|
|
12
|
+
{label}
|
|
13
|
+
</span>
|
|
14
|
+
{hasSelectAll && <span className={styles.selectAll}>{selectAll}</span>}
|
|
15
|
+
<div className={styles.actions}>{children}</div>
|
|
16
|
+
</div>
|
|
17
|
+
<div className={styles.closeAction}>{closeAction}</div>
|
|
18
|
+
</ThemeProvider>);
|
|
19
|
+
}
|
|
20
|
+
export function SelectionToolbarSeparator() {
|
|
21
|
+
return <span role='separator' aria-orientation='vertical' className={styles.separator}/>;
|
|
22
|
+
}
|
|
23
|
+
export default SelectionToolbar;
|
|
@@ -8,7 +8,8 @@ interface Context {
|
|
|
8
8
|
onNestedTooltipHide: () => void;
|
|
9
9
|
}
|
|
10
10
|
declare const TooltipContext: React.Context<Context | undefined>;
|
|
11
|
-
export interface TooltipProps extends Omit<AllHTMLAttributes<
|
|
11
|
+
export interface TooltipProps extends Omit<AllHTMLAttributes<HTMLElement>, 'title'> {
|
|
12
|
+
TagName?: 'span' | 'div' | null | undefined;
|
|
12
13
|
delay?: number | null | undefined;
|
|
13
14
|
selfOverflowOnly?: boolean | null | undefined;
|
|
14
15
|
popupProps?: Partial<PopupAttrs> | null | undefined;
|
|
@@ -129,19 +129,20 @@ export default class Tooltip extends Component {
|
|
|
129
129
|
this.setState({ showNestedPopup: false });
|
|
130
130
|
};
|
|
131
131
|
render() {
|
|
132
|
-
const { children, 'data-test': dataTest, title, delay, theme, selfOverflowOnly, popupProps, long, hide, ...restProps } = this.props;
|
|
132
|
+
const { children, TagName, 'data-test': dataTest, title, delay, theme, selfOverflowOnly, popupProps, long, hide, ...restProps } = this.props;
|
|
133
133
|
const ariaProps = typeof title === 'string' && Tooltip.isShow({ title, hide }) ? { 'aria-label': title, role: 'tooltip' } : {};
|
|
134
134
|
const { onNestedTooltipShow, onNestedTooltipHide } = this;
|
|
135
|
+
const WrapperElement = TagName || 'span';
|
|
135
136
|
const popup = (<Popup trapFocus={false} anchorElement={this.containerNode} hidden={!this.state.showPopup || this.state.showNestedPopup} onCloseAttempt={this.hidePopup} maxHeight={400} attached={false} onMouseOut={this.hideIfMovedOutsidePopup} top={4} dontCloseOnAnchorClick ref={this.popupRef} {...popupProps} className={classNames(styles.tooltip, { [styles.long]: long, [styles.inheritedTheme]: theme === 'inherit' }, popupProps?.className)}>
|
|
136
137
|
{title}
|
|
137
138
|
</Popup>);
|
|
138
139
|
return (<TooltipContext value={{ onNestedTooltipShow, onNestedTooltipHide }}>
|
|
139
|
-
<
|
|
140
|
+
<WrapperElement {...ariaProps} {...restProps} ref={this.containerRef} data-test={dataTests('ring-tooltip', dataTest)} data-test-title={typeof title === 'string' ? title : undefined}>
|
|
140
141
|
{children}
|
|
141
142
|
{theme === 'inherit' ? (popup) : (<ThemeProvider theme={theme} passToPopups WrapperComponent={props => <span {...props}/>}>
|
|
142
143
|
{popup}
|
|
143
144
|
</ThemeProvider>)}
|
|
144
|
-
</
|
|
145
|
+
</WrapperElement>
|
|
145
146
|
</TooltipContext>);
|
|
146
147
|
}
|
|
147
148
|
}
|