mirror of
https://github.com/apache/superset.git
synced 2026-05-12 19:35:17 +00:00
refactor(ui): replace native HTML elements with Ant Design 5 components for consistent theming (#33231)
This commit is contained in:
@@ -33,7 +33,8 @@
|
||||
"memoize-one": "^5.2.1",
|
||||
"react-table": "^7.8.0",
|
||||
"regenerator-runtime": "^0.14.1",
|
||||
"xss": "^1.0.15"
|
||||
"xss": "^1.0.15",
|
||||
"antd-v5": "npm:antd@^5.24.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@ant-design/icons": "^5.2.6",
|
||||
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
CSSProperties,
|
||||
DragEvent,
|
||||
} from 'react';
|
||||
|
||||
import { css, typedMemo, usePrevious } from '@superset-ui/core';
|
||||
import {
|
||||
useTable,
|
||||
usePagination,
|
||||
@@ -39,7 +39,6 @@ import {
|
||||
Row,
|
||||
} from 'react-table';
|
||||
import { matchSorter, rankings } from 'match-sorter';
|
||||
import { typedMemo, usePrevious } from '@superset-ui/core';
|
||||
import { isEqual } from 'lodash';
|
||||
import GlobalFilter, { GlobalFilterProps } from './components/GlobalFilter';
|
||||
import SelectPageSize, {
|
||||
@@ -381,7 +380,13 @@ export default typedMemo(function DataTable<D extends object>({
|
||||
) : null}
|
||||
</div>
|
||||
{searchInput ? (
|
||||
<div className="col-sm-6">
|
||||
<div
|
||||
className="col-sm-6"
|
||||
css={css`
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
`}
|
||||
>
|
||||
<GlobalFilter<D>
|
||||
searchInput={
|
||||
typeof searchInput === 'boolean' ? undefined : searchInput
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
import { memo, ComponentType, ChangeEventHandler } from 'react';
|
||||
import { Row, FilterValue } from 'react-table';
|
||||
import { Input, Space } from 'antd-v5';
|
||||
import useAsyncState from '../utils/useAsyncState';
|
||||
|
||||
export interface SearchInputProps {
|
||||
@@ -37,15 +38,15 @@ export interface GlobalFilterProps<D extends object> {
|
||||
|
||||
function DefaultSearchInput({ count, value, onChange }: SearchInputProps) {
|
||||
return (
|
||||
<span className="dt-global-filter">
|
||||
Search{' '}
|
||||
<input
|
||||
className="form-control input-sm"
|
||||
<Space direction="horizontal" size={4}>
|
||||
Search
|
||||
<Input
|
||||
size="small"
|
||||
placeholder={`${count} records...`}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</span>
|
||||
</Space>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
* under the License.
|
||||
*/
|
||||
import { memo } from 'react';
|
||||
import { t } from '@superset-ui/core';
|
||||
import { css, t } from '@superset-ui/core';
|
||||
import { formatSelectOptions } from '@superset-ui/chart-controls';
|
||||
import { Select } from 'antd-v5';
|
||||
|
||||
export type SizeOption = [number, string];
|
||||
|
||||
@@ -33,16 +34,18 @@ function DefaultSelectRenderer({
|
||||
options,
|
||||
onChange,
|
||||
}: SelectPageSizeRendererProps) {
|
||||
const { Option } = Select;
|
||||
|
||||
return (
|
||||
<span className="dt-select-page-size form-inline">
|
||||
{t('Show')}{' '}
|
||||
<select
|
||||
className="form-control input-sm"
|
||||
<Select<number>
|
||||
value={current}
|
||||
onBlur={() => {}}
|
||||
onChange={e => {
|
||||
onChange(Number((e.target as HTMLSelectElement).value));
|
||||
}}
|
||||
onChange={value => onChange(value)}
|
||||
size="small"
|
||||
css={theme => css`
|
||||
width: ${theme.sizeUnit * 18}px;
|
||||
`}
|
||||
>
|
||||
{options.map(option => {
|
||||
const [size, text] = Array.isArray(option)
|
||||
@@ -50,16 +53,16 @@ function DefaultSelectRenderer({
|
||||
: [option, option];
|
||||
const sizeLabel = size === 0 ? t('all') : size;
|
||||
return (
|
||||
<option
|
||||
aria-label={t('Show %s entries', sizeLabel)}
|
||||
<Option
|
||||
key={size}
|
||||
value={size}
|
||||
value={Number(size)}
|
||||
aria-label={t('Show %s entries', sizeLabel)}
|
||||
>
|
||||
{text}
|
||||
</option>
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</select>{' '}
|
||||
</Select>{' '}
|
||||
{t('entries')}
|
||||
</span>
|
||||
);
|
||||
|
||||
@@ -101,13 +101,29 @@ export default styled.div`
|
||||
/* use padding instead of margin so clientHeight can capture it */
|
||||
padding-top: 0.5em;
|
||||
}
|
||||
.dt-pagination .pagination {
|
||||
margin: 0;
|
||||
|
||||
.dt-pagination .pagination > li > a,
|
||||
.dt-pagination .pagination > li > span {
|
||||
background-color: ${theme.colorBgBase};
|
||||
color: ${theme.colorText};
|
||||
border-color: ${theme.colorBorderSecondary};
|
||||
}
|
||||
|
||||
.dt-pagination .pagination > li.active > a,
|
||||
.dt-pagination .pagination > li.active > span,
|
||||
.dt-pagination .pagination > li.active > a:focus,
|
||||
.dt-pagination .pagination > li.active > a:hover,
|
||||
.dt-pagination .pagination > li.active > span:focus,
|
||||
.dt-pagination .pagination > li.active > span:hover {
|
||||
background-color: ${theme.colorPrimary};
|
||||
color: ${theme.colorBgContainer};
|
||||
border-color: ${theme.colorBorderSecondary};
|
||||
}
|
||||
|
||||
.pagination > li > span.dt-pagination-ellipsis:focus,
|
||||
.pagination > li > span.dt-pagination-ellipsis:hover {
|
||||
background: ${theme.colorBgLayout};
|
||||
border-color: ${theme.colorBorderSecondary};
|
||||
}
|
||||
|
||||
.dt-no-results {
|
||||
|
||||
@@ -51,6 +51,7 @@ import {
|
||||
t,
|
||||
tn,
|
||||
useTheme,
|
||||
SupersetTheme,
|
||||
} from '@superset-ui/core';
|
||||
import { Dropdown, Menu, Tooltip } from '@superset-ui/chart-controls';
|
||||
import {
|
||||
@@ -62,6 +63,7 @@ import {
|
||||
TableOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { Input, Space, Select } from 'antd-v5';
|
||||
import {
|
||||
ColorSchemeEnum,
|
||||
DataColumnMeta,
|
||||
@@ -178,16 +180,16 @@ function SortIcon<D extends object>({ column }: { column: ColumnInstance<D> }) {
|
||||
|
||||
function SearchInput({ count, value, onChange }: SearchInputProps) {
|
||||
return (
|
||||
<span className="dt-global-filter">
|
||||
{t('Search')}{' '}
|
||||
<input
|
||||
<Space direction="horizontal" size={4}>
|
||||
{t('Search')}
|
||||
<Input
|
||||
size="small"
|
||||
aria-label={t('Search %s records', count)}
|
||||
className="form-control input-sm"
|
||||
placeholder={tn('search.num_records', count)}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</span>
|
||||
</Space>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -196,23 +198,22 @@ function SelectPageSize({
|
||||
current,
|
||||
onChange,
|
||||
}: SelectPageSizeRendererProps) {
|
||||
const { Option } = Select;
|
||||
|
||||
return (
|
||||
<span
|
||||
className="dt-select-page-size form-inline"
|
||||
role="group"
|
||||
aria-label={t('Select page size')}
|
||||
>
|
||||
<>
|
||||
<label htmlFor="pageSizeSelect" className="sr-only">
|
||||
{t('Select page size')}
|
||||
</label>
|
||||
{t('Show')}{' '}
|
||||
<select
|
||||
<Select<number>
|
||||
id="pageSizeSelect"
|
||||
className="form-control input-sm"
|
||||
value={current}
|
||||
onChange={e => {
|
||||
onChange(Number((e.target as HTMLSelectElement).value));
|
||||
}}
|
||||
onChange={value => onChange(value)}
|
||||
size="small"
|
||||
css={(theme: SupersetTheme) => css`
|
||||
width: ${theme.sizeUnit * 18}px;
|
||||
`}
|
||||
aria-label={t('Show entries per page')}
|
||||
>
|
||||
{options.map(option => {
|
||||
@@ -220,14 +221,14 @@ function SelectPageSize({
|
||||
? option
|
||||
: [option, option];
|
||||
return (
|
||||
<option key={size} value={size}>
|
||||
<Option key={size} value={Number(size)}>
|
||||
{text}
|
||||
</option>
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</select>{' '}
|
||||
</Select>{' '}
|
||||
{t('entries per page')}
|
||||
</span>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -953,7 +954,7 @@ export default function TableChart<D extends DataRecord = DataRecord>(
|
||||
},
|
||||
Header: ({ column: col, onClick, style, onDragStart, onDrop }) => (
|
||||
<th
|
||||
id={`header-${column.key}`}
|
||||
id={`header-${column.originalLabel}`}
|
||||
title={t('Shift + Click to sort by multiple columns')}
|
||||
className={[className, col.isSorted ? 'is-sorted' : ''].join(' ')}
|
||||
style={{
|
||||
|
||||
@@ -495,7 +495,7 @@ describe('plugin-chart-table', () => {
|
||||
'rgb(255, 255, 255)',
|
||||
);
|
||||
});
|
||||
it('should display originalLabel in grouped headers', () => {
|
||||
it('should display original label in grouped headers', () => {
|
||||
const props = transformProps(testData.comparison);
|
||||
|
||||
render(
|
||||
|
||||
Reference in New Issue
Block a user