mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
(core) add new filter bar
Summary: - add new filterBar option to views section - add toggle to the section menu - add filter bar - shows Save/Revert btn when unsaved change - shows all filered fields witch edit and delete buttons Test Plan: Add new FilterBar nbrowser test Reviewers: paulfitz, dsagal Reviewed By: dsagal Differential Revision: https://phab.getgrist.com/D2769
This commit is contained in:
parent
9e8e895abd
commit
2b1b586ecd
@ -12,6 +12,7 @@ import {Delay} from 'app/client/lib/Delay';
|
|||||||
import {createObsArray} from 'app/client/lib/koArrayWrap';
|
import {createObsArray} from 'app/client/lib/koArrayWrap';
|
||||||
import {ViewRec, ViewSectionRec} from 'app/client/models/DocModel';
|
import {ViewRec, ViewSectionRec} from 'app/client/models/DocModel';
|
||||||
import {reportError} from 'app/client/models/errors';
|
import {reportError} from 'app/client/models/errors';
|
||||||
|
import {filterBar} from 'app/client/ui/FilterBar';
|
||||||
import {viewSectionMenu} from 'app/client/ui/ViewSectionMenu';
|
import {viewSectionMenu} from 'app/client/ui/ViewSectionMenu';
|
||||||
import {colors, mediaSmall, testId} from 'app/client/ui2018/cssVars';
|
import {colors, mediaSmall, testId} from 'app/client/ui2018/cssVars';
|
||||||
import {editableLabel} from 'app/client/ui2018/editableLabel';
|
import {editableLabel} from 'app/client/ui2018/editableLabel';
|
||||||
@ -202,6 +203,7 @@ export class ViewLayout extends DisposableWithEvents implements IDomComponent {
|
|||||||
viewSectionMenu(this.docModel, vs, this.viewModel, this.gristDoc.isReadonly, this.gristDoc.app.useNewUI)
|
viewSectionMenu(this.docModel, vs, this.viewModel, this.gristDoc.isReadonly, this.gristDoc.app.useNewUI)
|
||||||
)
|
)
|
||||||
)),
|
)),
|
||||||
|
dom.maybe(vs.activeFilterBar, () => dom.create(filterBar, vs)),
|
||||||
dom.maybe<BaseView|null>(vs.viewInstance, (viewInstance) =>
|
dom.maybe<BaseView|null>(vs.viewInstance, (viewInstance) =>
|
||||||
dom('div.view_data_pane_container.flexvbox',
|
dom('div.view_data_pane_container.flexvbox',
|
||||||
cssResizing.cls('', this._isResizing),
|
cssResizing.cls('', this._isResizing),
|
||||||
|
@ -88,6 +88,7 @@ export interface ViewSectionRec extends IRowModel<"_grist_Views_section"> {
|
|||||||
|
|
||||||
isSorted: ko.Computed<boolean>;
|
isSorted: ko.Computed<boolean>;
|
||||||
disableDragRows: ko.Computed<boolean>;
|
disableDragRows: ko.Computed<boolean>;
|
||||||
|
activeFilterBar: modelUtil.CustomComputed<boolean>;
|
||||||
|
|
||||||
// Save all filters of fields in the section.
|
// Save all filters of fields in the section.
|
||||||
saveFilters(): Promise<void>;
|
saveFilters(): Promise<void>;
|
||||||
@ -131,6 +132,7 @@ export function createViewSectionRec(this: ViewSectionRec, docModel: DocModel):
|
|||||||
horizontalGridlines: true,
|
horizontalGridlines: true,
|
||||||
zebraStripes: false,
|
zebraStripes: false,
|
||||||
customView: '',
|
customView: '',
|
||||||
|
filterBar: false,
|
||||||
};
|
};
|
||||||
this.optionsObj = modelUtil.jsonObservable(this.options,
|
this.optionsObj = modelUtil.jsonObservable(this.options,
|
||||||
(obj: any) => defaults(obj || {}, defaultOptions));
|
(obj: any) => defaults(obj || {}, defaultOptions));
|
||||||
@ -272,4 +274,6 @@ export function createViewSectionRec(this: ViewSectionRec, docModel: DocModel):
|
|||||||
|
|
||||||
this.isSorted = ko.pureComputed(() => this.activeSortSpec().length > 0);
|
this.isSorted = ko.pureComputed(() => this.activeSortSpec().length > 0);
|
||||||
this.disableDragRows = ko.pureComputed(() => this.isSorted() || !this.table().supportsManualSort());
|
this.disableDragRows = ko.pureComputed(() => this.isSorted() || !this.table().supportsManualSort());
|
||||||
|
|
||||||
|
this.activeFilterBar = modelUtil.customValue(this.optionsObj.prop('filterBar'));
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {allInclusive, ColumnFilter, isEquivalentFilter} from 'app/client/models/ColumnFilter';
|
import {allInclusive, ColumnFilter, isEquivalentFilter} from 'app/client/models/ColumnFilter';
|
||||||
import {ViewFieldRec} from 'app/client/models/DocModel';
|
import {ViewFieldRec, ViewSectionRec} from 'app/client/models/DocModel';
|
||||||
import {FilteredRowSource} from 'app/client/models/rowset';
|
import {FilteredRowSource} from 'app/client/models/rowset';
|
||||||
import {SectionFilter} from 'app/client/models/SectionFilter';
|
import {SectionFilter} from 'app/client/models/SectionFilter';
|
||||||
import {TableData} from 'app/client/models/TableData';
|
import {TableData} from 'app/client/models/TableData';
|
||||||
@ -15,9 +15,9 @@ import {colors, vars} from 'app/client/ui2018/cssVars';
|
|||||||
import {icon} from 'app/client/ui2018/icons';
|
import {icon} from 'app/client/ui2018/icons';
|
||||||
import {menuCssClass, menuDivider} from 'app/client/ui2018/menus';
|
import {menuCssClass, menuDivider} from 'app/client/ui2018/menus';
|
||||||
import {CellValue} from 'app/common/DocActions';
|
import {CellValue} from 'app/common/DocActions';
|
||||||
import {Computed, Disposable, dom, IDisposableOwner, input, makeTestId, styled} from 'grainjs';
|
import {Computed, Disposable, dom, DomElementMethod, IDisposableOwner, input, makeTestId, styled} from 'grainjs';
|
||||||
import identity = require('lodash/identity');
|
import identity = require('lodash/identity');
|
||||||
import {IOpenController} from 'popweasel';
|
import {IOpenController, IPopupOptions, setPopupToCreateDom} from 'popweasel';
|
||||||
import {ColumnFilterMenuModel, IFilterCount} from '../models/ColumnFilterMenuModel';
|
import {ColumnFilterMenuModel, IFilterCount} from '../models/ColumnFilterMenuModel';
|
||||||
|
|
||||||
|
|
||||||
@ -313,6 +313,24 @@ function getCount(values: Array<[CellValue, IFilterCount]>) {
|
|||||||
return values.reduce((acc, val) => acc + val[1].count, 0);
|
return values.reduce((acc, val) => acc + val[1].count, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const defaultPopupOptions: IPopupOptions = {
|
||||||
|
placement: 'bottom-start',
|
||||||
|
boundaries: 'viewport',
|
||||||
|
trigger: ['click'],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper to attach the column filter menu.
|
||||||
|
export function attachColumnFilterMenu(viewSection: ViewSectionRec, field: ViewFieldRec,
|
||||||
|
popupOptions: IPopupOptions): DomElementMethod {
|
||||||
|
const options = {...defaultPopupOptions, ...popupOptions};
|
||||||
|
return (elem) => {
|
||||||
|
const instance = viewSection.viewInstance();
|
||||||
|
if (instance && instance.createFilterMenu) { // Should be set if using BaseView
|
||||||
|
setPopupToCreateDom(elem, ctl => instance.createFilterMenu(ctl, field), options);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const cssMenu = styled('div', `
|
const cssMenu = styled('div', `
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
102
app/client/ui/FilterBar.ts
Normal file
102
app/client/ui/FilterBar.ts
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import { ViewFieldRec, ViewSectionRec } from "app/client/models/DocModel";
|
||||||
|
import { attachColumnFilterMenu } from "app/client/ui/ColumnFilterMenu";
|
||||||
|
import { cssButton, cssButtonGroup } from "app/client/ui2018/buttons";
|
||||||
|
import { colors, testId } from "app/client/ui2018/cssVars";
|
||||||
|
import { icon } from "app/client/ui2018/icons";
|
||||||
|
import { dom, IDisposableOwner, IDomArgs, styled } from "grainjs";
|
||||||
|
|
||||||
|
export function filterBar(_owner: IDisposableOwner, viewSection: ViewSectionRec) {
|
||||||
|
return cssFilterBar(
|
||||||
|
testId('filter-bar'),
|
||||||
|
dom.forEach(viewSection.filteredFields, (field) => makeFilterField(viewSection, field)),
|
||||||
|
cssSpacer(),
|
||||||
|
dom.maybe(viewSection.filterSpecChanged, () => [
|
||||||
|
primaryButton(
|
||||||
|
'Save', testId('btn'),
|
||||||
|
dom.on('click', async () => await viewSection.saveFilters()),
|
||||||
|
),
|
||||||
|
basicButton(
|
||||||
|
'Revert', testId('btn'),
|
||||||
|
dom.on('click', () => viewSection.revertFilters()),
|
||||||
|
)
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeFilterField(viewSection: ViewSectionRec, field: ViewFieldRec) {
|
||||||
|
return cssFilterBarItem(
|
||||||
|
testId('filter-field'),
|
||||||
|
primaryButton(
|
||||||
|
testId('btn'),
|
||||||
|
cssIcon('FilterSimple'),
|
||||||
|
cssMenuTextLabel(dom.text(field.label)),
|
||||||
|
cssBtn.cls('-disabled', field.activeFilter.isSaved),
|
||||||
|
attachColumnFilterMenu(viewSection, field, {placement: 'bottom-start', attach: 'body'}),
|
||||||
|
),
|
||||||
|
deleteButton(
|
||||||
|
testId('delete'),
|
||||||
|
cssIcon('CrossSmall'),
|
||||||
|
cssBtn.cls('-disabled', field.activeFilter.isSaved),
|
||||||
|
dom.on('click', () => field.activeFilter('')),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const cssFilterBar = styled('div', `
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
margin-left: -4px;
|
||||||
|
overflow-x: scroll;
|
||||||
|
scrollbar-width: none;
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
const cssFilterBarItem = styled(cssButtonGroup, `
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin: 0 4px;
|
||||||
|
& > .${cssButton.className}:first-child {
|
||||||
|
border-right: 0.5px solid white;
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
const cssMenuTextLabel = styled('span', `
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 0 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
`);
|
||||||
|
const cssIcon = styled(icon, `
|
||||||
|
margin-top: -3px;
|
||||||
|
`);
|
||||||
|
const cssBtn = styled('div', `
|
||||||
|
height: 24px;
|
||||||
|
padding: 3px 8px;
|
||||||
|
.${cssFilterBar.className} > & {
|
||||||
|
margin: 0 4px;
|
||||||
|
}
|
||||||
|
&-disabled {
|
||||||
|
color: ${colors.light};
|
||||||
|
--icon-color: ${colors.light};
|
||||||
|
background-color: ${colors.slate};
|
||||||
|
border-color: ${colors.slate};
|
||||||
|
}
|
||||||
|
&-disabled:hover {
|
||||||
|
background-color: ${colors.darkGrey};
|
||||||
|
border-color: ${colors.darkGrey};
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
const primaryButton = (...args: IDomArgs<HTMLDivElement>) => (
|
||||||
|
dom('div', cssButton.cls(''), cssButton.cls('-primary'),
|
||||||
|
cssBtn.cls(''), ...args)
|
||||||
|
);
|
||||||
|
const basicButton = (...args: IDomArgs<HTMLDivElement>) => (
|
||||||
|
dom('div', cssButton.cls(''), cssBtn.cls(''), ...args)
|
||||||
|
);
|
||||||
|
const deleteButton = styled(primaryButton, `
|
||||||
|
padding: 3px 4px;
|
||||||
|
`);
|
||||||
|
const cssSpacer = styled('div', `
|
||||||
|
width: 8px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
`);
|
@ -1,13 +1,14 @@
|
|||||||
import {flipColDirection, parseSortColRefs} from 'app/client/lib/sortUtil';
|
import {flipColDirection, parseSortColRefs} from 'app/client/lib/sortUtil';
|
||||||
import {ColumnRec, DocModel, ViewFieldRec, ViewRec, ViewSectionRec} from 'app/client/models/DocModel';
|
import {ColumnRec, DocModel, ViewFieldRec, ViewRec, ViewSectionRec} from 'app/client/models/DocModel';
|
||||||
|
import {CustomComputed} from 'app/client/models/modelUtil';
|
||||||
|
import {attachColumnFilterMenu} from 'app/client/ui/ColumnFilterMenu';
|
||||||
|
import {makeViewLayoutMenu} from 'app/client/ui/ViewLayoutMenu';
|
||||||
|
import {basicButton, primaryButton} from 'app/client/ui2018/buttons';
|
||||||
import {colors, vars} from 'app/client/ui2018/cssVars';
|
import {colors, vars} from 'app/client/ui2018/cssVars';
|
||||||
import {icon} from 'app/client/ui2018/icons';
|
import {icon} from 'app/client/ui2018/icons';
|
||||||
import {menu, menuDivider} from 'app/client/ui2018/menus';
|
import {menu, menuDivider} from 'app/client/ui2018/menus';
|
||||||
import {Computed, dom, fromKo, makeTestId, Observable, styled} from 'grainjs';
|
import {Computed, dom, fromKo, makeTestId, Observable, styled} from 'grainjs';
|
||||||
import difference = require('lodash/difference');
|
import difference = require('lodash/difference');
|
||||||
import {setPopupToCreateDom} from 'popweasel';
|
|
||||||
import {makeViewLayoutMenu} from '../ui/ViewLayoutMenu';
|
|
||||||
import {basicButton, primaryButton} from '../ui2018/buttons';
|
|
||||||
|
|
||||||
const testId = makeTestId('test-section-menu-');
|
const testId = makeTestId('test-section-menu-');
|
||||||
|
|
||||||
@ -23,7 +24,8 @@ export function viewSectionMenu(docModel: DocModel, viewSection: ViewSectionRec,
|
|||||||
// it started in the "unsaved" state (in which a dynamic use()-based subscription to
|
// it started in the "unsaved" state (in which a dynamic use()-based subscription to
|
||||||
// emptySortFilterObs wouldn't be active, which could result in a wrong order of evaluation).
|
// emptySortFilterObs wouldn't be active, which could result in a wrong order of evaluation).
|
||||||
const iconSuffixObs: Computed<IconSuffix> = Computed.create(null, emptySortFilterObs, (use, empty) => {
|
const iconSuffixObs: Computed<IconSuffix> = Computed.create(null, emptySortFilterObs, (use, empty) => {
|
||||||
if (use(viewSection.filterSpecChanged) || !use(viewSection.activeSortJson.isSaved)) {
|
if (use(viewSection.filterSpecChanged) || !use(viewSection.activeSortJson.isSaved)
|
||||||
|
|| !use(viewSection.activeFilterBar.isSaved)) {
|
||||||
return '-unsaved';
|
return '-unsaved';
|
||||||
} else if (!empty) {
|
} else if (!empty) {
|
||||||
return '-saved';
|
return '-saved';
|
||||||
@ -49,21 +51,26 @@ export function viewSectionMenu(docModel: DocModel, viewSection: ViewSectionRec,
|
|||||||
}),
|
}),
|
||||||
dom.domComputed(viewSection.filteredFields, fields =>
|
dom.domComputed(viewSection.filteredFields, fields =>
|
||||||
makeFilterPanel(viewSection, fields)),
|
makeFilterPanel(viewSection, fields)),
|
||||||
|
makeFilterBarToggle(viewSection.activeFilterBar),
|
||||||
dom.domComputed(iconSuffixObs, iconSuffix => {
|
dom.domComputed(iconSuffixObs, iconSuffix => {
|
||||||
const displaySave = iconSuffix === '-unsaved';
|
const displaySave = iconSuffix === '-unsaved';
|
||||||
return [
|
return [
|
||||||
displaySave ? cssMenuInfoHeader(
|
displaySave ? cssMenuInfoHeader(
|
||||||
cssSaveButton('Save', testId('btn-save'),
|
cssSaveButton('Save', testId('btn-save'),
|
||||||
dom.on('click', async () => {
|
dom.on('click', async () => {
|
||||||
await viewSection.activeSortJson.save(); // Save sort
|
await docModel.docData.bundleActions("Update Sort&Filter settings", () => Promise.all([
|
||||||
await viewSection.saveFilters(); // Save filter
|
viewSection.activeSortJson.save(), // Save sort
|
||||||
|
viewSection.saveFilters(), // Save filter
|
||||||
|
viewSection.activeFilterBar.save(), // Save bar
|
||||||
|
]));
|
||||||
}),
|
}),
|
||||||
dom.boolAttr('disabled', isReadonly),
|
dom.boolAttr('disabled', isReadonly),
|
||||||
),
|
),
|
||||||
basicButton('Revert', testId('btn-revert'),
|
basicButton('Revert', testId('btn-revert'),
|
||||||
dom.on('click', () => {
|
dom.on('click', () => {
|
||||||
viewSection.activeSortJson.revert(); // Revert sort
|
viewSection.activeSortJson.revert(); // Revert sort
|
||||||
viewSection.revertFilters(); // Revert filter
|
viewSection.revertFilters(); // Revert filter
|
||||||
|
viewSection.activeFilterBar.revert(); // Revert bar
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
) : null,
|
) : null,
|
||||||
@ -108,10 +115,29 @@ function makeSortPanel(section: ViewSectionRec, sortSpec: number[], getColumn: (
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
cssMenuInfoHeader('Sorted by', testId('heading-sorted')),
|
cssMenuInfoHeader('Sorted by', testId('heading-sorted')),
|
||||||
sortColumns.length > 0 ? sortColumns : cssMenuText('(Default)')
|
sortColumns.length > 0 ? sortColumns : cssGrayedMenuText('(Default)')
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function makeFilterBarToggle(activeFilterBar: CustomComputed<boolean>) {
|
||||||
|
return cssMenuText(
|
||||||
|
cssMenuIconWrapper(
|
||||||
|
testId('btn'),
|
||||||
|
cssMenuIconWrapper.cls('-changed', (use) => !use(activeFilterBar.isSaved)),
|
||||||
|
dom.domComputed((use) => {
|
||||||
|
const filterBar = use(activeFilterBar);
|
||||||
|
const isSaved = use(activeFilterBar.isSaved);
|
||||||
|
return cssIcon(filterBar ? "Tick" : (isSaved ? "Plus" : "CrossSmall"),
|
||||||
|
cssIcon.cls('-green', Boolean(filterBar)),
|
||||||
|
testId('icon'));
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
dom.on('click', () => activeFilterBar(!activeFilterBar())),
|
||||||
|
cssMenuTextLabel("Toggle Filter Bar"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function makeFilterPanel(section: ViewSectionRec, filteredFields: ViewFieldRec[]) {
|
function makeFilterPanel(section: ViewSectionRec, filteredFields: ViewFieldRec[]) {
|
||||||
const fields = filteredFields.map(field => {
|
const fields = filteredFields.map(field => {
|
||||||
const fieldChanged = Computed.create(null, fromKo(field.activeFilter.isSaved), (_use, isSaved) => !isSaved);
|
const fieldChanged = Computed.create(null, fromKo(field.activeFilter.isSaved), (_use, isSaved) => !isSaved);
|
||||||
@ -120,26 +146,18 @@ function makeFilterPanel(section: ViewSectionRec, filteredFields: ViewFieldRec[]
|
|||||||
cssMenuIconWrapper(
|
cssMenuIconWrapper(
|
||||||
cssMenuIconWrapper.cls('-changed', fieldChanged),
|
cssMenuIconWrapper.cls('-changed', fieldChanged),
|
||||||
cssIcon('FilterSimple'),
|
cssIcon('FilterSimple'),
|
||||||
(elem) => {
|
attachColumnFilterMenu(section, field, {placement: 'bottom-end'}),
|
||||||
const instance = section.viewInstance();
|
testId('filter-icon'),
|
||||||
if (instance && instance.createFilterMenu) { // Should be set if using BaseView
|
|
||||||
setPopupToCreateDom(elem, ctl => instance.createFilterMenu(ctl, field), {
|
|
||||||
placement: 'bottom-end',
|
|
||||||
boundaries: 'viewport',
|
|
||||||
trigger: ['click']
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
),
|
),
|
||||||
cssMenuTextLabel(field.label()),
|
cssMenuTextLabel(field.label()),
|
||||||
cssMenuIconWrapper(cssIcon('Remove'), dom.on('click', () => field.activeFilter(''))),
|
cssMenuIconWrapper(cssIcon('Remove', testId('btn-remove-filter')), dom.on('click', () => field.activeFilter(''))),
|
||||||
testId('filter-col')
|
testId('filter-col')
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return [
|
return [
|
||||||
cssMenuInfoHeader('Filtered by', {style: 'margin-top: 4px'}, testId('heading-filtered')),
|
cssMenuInfoHeader('Filtered by', {style: 'margin-top: 4px'}, testId('heading-filtered')),
|
||||||
filteredFields.length > 0 ? fields : cssMenuText('(Not filtered)')
|
filteredFields.length > 0 ? fields : cssGrayedMenuText('(Not filtered)')
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +202,7 @@ const cssIconWrapper = styled('div', `
|
|||||||
`);
|
`);
|
||||||
|
|
||||||
const cssMenuIconWrapper = styled(cssIconWrapper, `
|
const cssMenuIconWrapper = styled(cssIconWrapper, `
|
||||||
padding: 3px;
|
display: flex;
|
||||||
margin: -3px 0;
|
margin: -3px 0;
|
||||||
width: 22px;
|
width: 22px;
|
||||||
height: 22px;
|
height: 22px;
|
||||||
@ -212,6 +230,10 @@ const cssIcon = styled(icon, `
|
|||||||
.${clsOldUI.className} & {
|
.${clsOldUI.className} & {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-green {
|
||||||
|
background-color: ${colors.lightGreen};
|
||||||
|
}
|
||||||
`);
|
`);
|
||||||
|
|
||||||
const cssDotsIconWrapper = styled(cssIconWrapper, `
|
const cssDotsIconWrapper = styled(cssIconWrapper, `
|
||||||
@ -251,9 +273,14 @@ const cssMenuInfoHeader = styled('div', `
|
|||||||
const cssMenuText = styled('div', `
|
const cssMenuText = styled('div', `
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: ${colors.slate};
|
|
||||||
padding: 0px 24px 8px 24px;
|
padding: 0px 24px 8px 24px;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
|
white-space: nowrap;
|
||||||
|
`);
|
||||||
|
|
||||||
|
const cssGrayedMenuText = styled(cssMenuText, `
|
||||||
|
color: ${colors.slate};
|
||||||
|
padding-left: 24px;
|
||||||
`);
|
`);
|
||||||
|
|
||||||
const cssMenuTextLabel = styled('span', `
|
const cssMenuTextLabel = styled('span', `
|
||||||
|
Loading…
Reference in New Issue
Block a user