limit collection display
make it clear lists page is truncated lists display page cleanup
This commit is contained in:
parent
7a2adae09c
commit
5df736dc6b
12 changed files with 320 additions and 74 deletions
|
@ -2216,5 +2216,8 @@
|
||||||
"Enable Data Hosting": "Enable Data Hosting",
|
"Enable Data Hosting": "Enable Data Hosting",
|
||||||
"Data over the limit will be deleted within 30 minutes. This will make the Yrbl cry a little bit.": "Data over the limit will be deleted within 30 minutes. This will make the Yrbl cry a little bit.",
|
"Data over the limit will be deleted within 30 minutes. This will make the Yrbl cry a little bit.": "Data over the limit will be deleted within 30 minutes. This will make the Yrbl cry a little bit.",
|
||||||
"Choose %asset%": "Choose %asset%",
|
"Choose %asset%": "Choose %asset%",
|
||||||
|
"Showing %filtered% results of %total%": "Showing %filtered% results of %total%",
|
||||||
|
"filtered": "filtered",
|
||||||
|
"View All Playlists": "View All Playlists",
|
||||||
"--end--": "--end--"
|
"--end--": "--end--"
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ const ALL = 'All';
|
||||||
const PRIVATE = 'Private';
|
const PRIVATE = 'Private';
|
||||||
const PUBLIC = 'Public';
|
const PUBLIC = 'Public';
|
||||||
const COLLECTION_FILTERS = [ALL, PRIVATE, PUBLIC];
|
const COLLECTION_FILTERS = [ALL, PRIVATE, PUBLIC];
|
||||||
|
const COLLECTION_SHOW_COUNT = 12;
|
||||||
|
|
||||||
export default function CollectionsListMine(props: Props) {
|
export default function CollectionsListMine(props: Props) {
|
||||||
const {
|
const {
|
||||||
|
@ -53,18 +54,24 @@ export default function CollectionsListMine(props: Props) {
|
||||||
|
|
||||||
let filteredCollections;
|
let filteredCollections;
|
||||||
if (searchText && collectionsToShow) {
|
if (searchText && collectionsToShow) {
|
||||||
filteredCollections = collectionsToShow.filter((id) => {
|
filteredCollections = collectionsToShow
|
||||||
|
.filter((id) => {
|
||||||
return (
|
return (
|
||||||
(unpublishedCollections[id] &&
|
(unpublishedCollections[id] &&
|
||||||
unpublishedCollections[id].name.toLocaleLowerCase().includes(searchText.toLocaleLowerCase())) ||
|
unpublishedCollections[id].name.toLocaleLowerCase().includes(searchText.toLocaleLowerCase())) ||
|
||||||
(publishedCollections[id] &&
|
(publishedCollections[id] &&
|
||||||
publishedCollections[id].name.toLocaleLowerCase().includes(searchText.toLocaleLowerCase()))
|
publishedCollections[id].name.toLocaleLowerCase().includes(searchText.toLocaleLowerCase()))
|
||||||
);
|
);
|
||||||
});
|
})
|
||||||
|
.slice(0, COLLECTION_SHOW_COUNT);
|
||||||
} else {
|
} else {
|
||||||
filteredCollections = collectionsToShow || [];
|
filteredCollections = collectionsToShow.slice(0, COLLECTION_SHOW_COUNT) || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const totalLength = collectionsToShow ? collectionsToShow.length : 0;
|
||||||
|
const filteredLength = filteredCollections.length;
|
||||||
|
const isTruncated = totalLength > filteredLength;
|
||||||
|
|
||||||
const watchLater = builtinCollectionsList.find((list) => list.id === COLLECTIONS_CONSTS.WATCH_LATER_ID);
|
const watchLater = builtinCollectionsList.find((list) => list.id === COLLECTIONS_CONSTS.WATCH_LATER_ID);
|
||||||
const favorites = builtinCollectionsList.find((list) => list.id === COLLECTIONS_CONSTS.FAVORITES_ID);
|
const favorites = builtinCollectionsList.find((list) => list.id === COLLECTIONS_CONSTS.FAVORITES_ID);
|
||||||
const builtin = [watchLater, favorites];
|
const builtin = [watchLater, favorites];
|
||||||
|
@ -130,7 +137,19 @@ export default function CollectionsListMine(props: Props) {
|
||||||
<div className="claim-grid__wrapper">
|
<div className="claim-grid__wrapper">
|
||||||
<div className="claim-grid__header section">
|
<div className="claim-grid__header section">
|
||||||
<h1 className="claim-grid__title">
|
<h1 className="claim-grid__title">
|
||||||
|
<Button
|
||||||
|
className="claim-grid__title"
|
||||||
|
button="link"
|
||||||
|
navigate={`/$/${PAGES.PLAYLISTS}`}
|
||||||
|
label={
|
||||||
|
<span className="claim-grid__title-span">
|
||||||
{__('Playlists')}
|
{__('Playlists')}
|
||||||
|
<div className="claim-grid__title--empty">
|
||||||
|
<Icon className="icon--margin-right" icon={ICONS.STACK} />
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
/>
|
||||||
{!hasCollections && !fetchingCollections && (
|
{!hasCollections && !fetchingCollections && (
|
||||||
<div className="claim-grid__title--empty">{__('(Empty) --[indicates empty playlist]--')}</div>
|
<div className="claim-grid__title--empty">{__('(Empty) --[indicates empty playlist]--')}</div>
|
||||||
)}
|
)}
|
||||||
|
@ -139,6 +158,7 @@ export default function CollectionsListMine(props: Props) {
|
||||||
)}
|
)}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="section__header-action-stack">
|
||||||
<div className="section__header--actions">
|
<div className="section__header--actions">
|
||||||
<div className="claim-search__wrapper">
|
<div className="claim-search__wrapper">
|
||||||
<div className="claim-search__menu-group">
|
<div className="claim-search__menu-group">
|
||||||
|
@ -168,9 +188,23 @@ export default function CollectionsListMine(props: Props) {
|
||||||
/>
|
/>
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
|
{isTruncated && (
|
||||||
|
<p className="collection-grid__results-summary">
|
||||||
|
{__(`Showing %filtered% results of %total%`, {
|
||||||
|
filtered: filteredLength,
|
||||||
|
total: totalLength,
|
||||||
|
})}
|
||||||
|
{`${searchText ? ' (' + __('filtered') + ') ' : ' '}`}
|
||||||
|
<Button
|
||||||
|
button="link"
|
||||||
|
navigate={`/$/${PAGES.PLAYLISTS}`}
|
||||||
|
label={<span className="claim-grid__title-span">{__('View All Playlists')}</span>}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
{Boolean(hasCollections) && (
|
{Boolean(hasCollections) && (
|
||||||
<div>
|
<div>
|
||||||
{/* TODO: fix above spacing hack */}
|
|
||||||
<div className="claim-grid">
|
<div className="claim-grid">
|
||||||
{filteredCollections &&
|
{filteredCollections &&
|
||||||
filteredCollections.length > 0 &&
|
filteredCollections.length > 0 &&
|
||||||
|
|
29
ui/component/playlistsMine/index.js
Normal file
29
ui/component/playlistsMine/index.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { withRouter } from 'react-router';
|
||||||
|
import {
|
||||||
|
selectMyPublishedPlaylistCollections,
|
||||||
|
selectMyUnpublishedCollections, // should probably distinguish types
|
||||||
|
// selectSavedCollections,
|
||||||
|
} from 'redux/selectors/collections';
|
||||||
|
import { selectFetchingMyCollections } from 'redux/selectors/claims';
|
||||||
|
import PlaylistsMine from './view';
|
||||||
|
import { PAGE_PARAM, PAGE_SIZE_PARAM } from 'constants/claim';
|
||||||
|
const COLLECTIONS_PAGE_SIZE = 12;
|
||||||
|
|
||||||
|
const select = (state, props) => {
|
||||||
|
const { search } = props.location;
|
||||||
|
const urlParams = new URLSearchParams(search);
|
||||||
|
const page = Number(urlParams.get(PAGE_PARAM)) || '1';
|
||||||
|
const pageSize = urlParams.get(PAGE_SIZE_PARAM) || String(COLLECTIONS_PAGE_SIZE);
|
||||||
|
|
||||||
|
return {
|
||||||
|
page,
|
||||||
|
pageSize,
|
||||||
|
publishedCollections: selectMyPublishedPlaylistCollections(state),
|
||||||
|
unpublishedCollections: selectMyUnpublishedCollections(state),
|
||||||
|
// savedCollections: selectSavedCollections(state),
|
||||||
|
fetchingCollections: selectFetchingMyCollections(state),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default withRouter(connect(select)(PlaylistsMine));
|
161
ui/component/playlistsMine/view.jsx
Normal file
161
ui/component/playlistsMine/view.jsx
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
// @flow
|
||||||
|
import React from 'react';
|
||||||
|
import CollectionPreviewTile from 'component/collectionPreviewTile';
|
||||||
|
import Button from 'component/button';
|
||||||
|
import Icon from 'component/common/icon';
|
||||||
|
import * as ICONS from 'constants/icons';
|
||||||
|
import * as KEYCODES from 'constants/keycodes';
|
||||||
|
import Paginate from 'component/common/paginate';
|
||||||
|
|
||||||
|
import Yrbl from 'component/yrbl';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import { FormField, Form } from 'component/common/form';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
publishedCollections: CollectionGroup,
|
||||||
|
unpublishedCollections: CollectionGroup,
|
||||||
|
// savedCollections: CollectionGroup,
|
||||||
|
fetchingCollections: boolean,
|
||||||
|
page: number,
|
||||||
|
pageSize: number,
|
||||||
|
};
|
||||||
|
|
||||||
|
const ALL = 'All';
|
||||||
|
const PRIVATE = 'Private';
|
||||||
|
const PUBLIC = 'Public';
|
||||||
|
const COLLECTION_FILTERS = [ALL, PRIVATE, PUBLIC];
|
||||||
|
|
||||||
|
export default function PlaylistsMine(props: Props) {
|
||||||
|
const {
|
||||||
|
publishedCollections,
|
||||||
|
unpublishedCollections,
|
||||||
|
// savedCollections, these are resolved on startup from sync'd claimIds or urls
|
||||||
|
fetchingCollections,
|
||||||
|
page = 0,
|
||||||
|
pageSize,
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
const unpublishedCollectionsList = (Object.keys(unpublishedCollections || {}): any);
|
||||||
|
const publishedList = (Object.keys(publishedCollections || {}): any);
|
||||||
|
const hasCollections = unpublishedCollectionsList.length || publishedList.length;
|
||||||
|
const [filterType, setFilterType] = React.useState(ALL);
|
||||||
|
const [searchText, setSearchText] = React.useState('');
|
||||||
|
|
||||||
|
let collectionsToShow = [];
|
||||||
|
if (filterType === ALL) {
|
||||||
|
collectionsToShow = unpublishedCollectionsList.concat(publishedList);
|
||||||
|
} else if (filterType === PRIVATE) {
|
||||||
|
collectionsToShow = unpublishedCollectionsList;
|
||||||
|
} else if (filterType === PUBLIC) {
|
||||||
|
collectionsToShow = publishedList;
|
||||||
|
}
|
||||||
|
|
||||||
|
let filteredCollections;
|
||||||
|
if (searchText && collectionsToShow) {
|
||||||
|
filteredCollections = collectionsToShow.filter((id) => {
|
||||||
|
return (
|
||||||
|
(unpublishedCollections[id] &&
|
||||||
|
unpublishedCollections[id].name.toLocaleLowerCase().includes(searchText.toLocaleLowerCase())) ||
|
||||||
|
(publishedCollections[id] &&
|
||||||
|
publishedCollections[id].name.toLocaleLowerCase().includes(searchText.toLocaleLowerCase()))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
filteredCollections = collectionsToShow || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const shouldPaginate = filteredCollections.length > pageSize;
|
||||||
|
const paginateStart = shouldPaginate ? (page - 1) * pageSize : 0;
|
||||||
|
const paginatedCollections = filteredCollections.slice(paginateStart, paginateStart + pageSize);
|
||||||
|
|
||||||
|
function escapeListener(e: SyntheticKeyboardEvent<*>) {
|
||||||
|
if (e.keyCode === KEYCODES.ESCAPE) {
|
||||||
|
e.preventDefault();
|
||||||
|
setSearchText('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTextareaFocus() {
|
||||||
|
window.addEventListener('keydown', escapeListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTextareaBlur() {
|
||||||
|
window.removeEventListener('keydown', escapeListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="claim-grid__wrapper">
|
||||||
|
<div className="claim-grid__header section">
|
||||||
|
<h1 className="claim-grid__title">
|
||||||
|
{__('Playlists')}
|
||||||
|
{!hasCollections && !fetchingCollections && (
|
||||||
|
<div className="claim-grid__title--empty">{__('(Empty) --[indicates empty playlist]--')}</div>
|
||||||
|
)}
|
||||||
|
{!hasCollections && fetchingCollections && (
|
||||||
|
<div className="claim-grid__title--empty">{__('(Empty) --[indicates empty playlist]--')}</div>
|
||||||
|
)}
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div className="section__header--actions">
|
||||||
|
<div className="claim-search__wrapper">
|
||||||
|
<div className="claim-search__menu-group">
|
||||||
|
{COLLECTION_FILTERS.map((value) => (
|
||||||
|
<Button
|
||||||
|
label={__(value)}
|
||||||
|
key={value}
|
||||||
|
button="alt"
|
||||||
|
onClick={() => setFilterType(value)}
|
||||||
|
className={classnames('button-toggle', {
|
||||||
|
'button-toggle--active': filterType === value,
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Form onSubmit={() => {}} className="wunderbar--inline">
|
||||||
|
<Icon icon={ICONS.SEARCH} />
|
||||||
|
<FormField
|
||||||
|
onFocus={onTextareaFocus}
|
||||||
|
onBlur={onTextareaBlur}
|
||||||
|
className="wunderbar__input--inline"
|
||||||
|
value={searchText}
|
||||||
|
onChange={(e) => setSearchText(e.target.value)}
|
||||||
|
type="text"
|
||||||
|
placeholder={__('Search')}
|
||||||
|
/>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
{Boolean(hasCollections) && (
|
||||||
|
<div>
|
||||||
|
{/* TODO: fix above spacing hack */}
|
||||||
|
|
||||||
|
<div className="claim-grid">
|
||||||
|
{paginatedCollections &&
|
||||||
|
paginatedCollections.length > 0 &&
|
||||||
|
paginatedCollections.map((key) => <CollectionPreviewTile tileLayout collectionId={key} key={key} />)}
|
||||||
|
{!paginatedCollections.length && <div className="empty main--empty">{__('No matching playlists')}</div>}
|
||||||
|
</div>
|
||||||
|
{shouldPaginate && (
|
||||||
|
<Paginate
|
||||||
|
totalPages={
|
||||||
|
filteredCollections.length > 0 ? Math.ceil(filteredCollections.length / Number(pageSize)) : 1
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{!hasCollections && !fetchingCollections && (
|
||||||
|
<div className="main--empty">
|
||||||
|
<Yrbl type={'sad'} title={__('You have no lists yet. Better start hoarding!')} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{!hasCollections && fetchingCollections && (
|
||||||
|
<div className="main--empty">
|
||||||
|
<h2 className="main--empty empty">{__('Loading...')}</h2>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
|
@ -45,6 +45,7 @@ import InvitedPage from 'page/invited';
|
||||||
import LibraryPage from 'page/library';
|
import LibraryPage from 'page/library';
|
||||||
import ListBlockedPage from 'page/listBlocked';
|
import ListBlockedPage from 'page/listBlocked';
|
||||||
import ListsPage from 'page/lists';
|
import ListsPage from 'page/lists';
|
||||||
|
import PlaylistsPage from 'page/playlists';
|
||||||
import OwnComments from 'page/ownComments';
|
import OwnComments from 'page/ownComments';
|
||||||
import PasswordResetPage from 'page/passwordReset';
|
import PasswordResetPage from 'page/passwordReset';
|
||||||
import PasswordSetPage from 'page/passwordSet';
|
import PasswordSetPage from 'page/passwordSet';
|
||||||
|
@ -294,6 +295,7 @@ function AppRouter(props: Props) {
|
||||||
<PrivateRoute {...props} path={`/$/${PAGES.REWARDS_VERIFY}`} component={RewardsVerifyPage} />
|
<PrivateRoute {...props} path={`/$/${PAGES.REWARDS_VERIFY}`} component={RewardsVerifyPage} />
|
||||||
<PrivateRoute {...props} path={`/$/${PAGES.LIBRARY}`} component={LibraryPage} />
|
<PrivateRoute {...props} path={`/$/${PAGES.LIBRARY}`} component={LibraryPage} />
|
||||||
<PrivateRoute {...props} path={`/$/${PAGES.LISTS}`} component={ListsPage} />
|
<PrivateRoute {...props} path={`/$/${PAGES.LISTS}`} component={ListsPage} />
|
||||||
|
<PrivateRoute {...props} path={`/$/${PAGES.PLAYLISTS}`} component={PlaylistsPage} />
|
||||||
<PrivateRoute {...props} path={`/$/${PAGES.TAGS_FOLLOWING_MANAGE}`} component={TagsFollowingManagePage} />
|
<PrivateRoute {...props} path={`/$/${PAGES.TAGS_FOLLOWING_MANAGE}`} component={TagsFollowingManagePage} />
|
||||||
<PrivateRoute {...props} path={`/$/${PAGES.SETTINGS_BLOCKED_MUTED}`} component={ListBlockedPage} />
|
<PrivateRoute {...props} path={`/$/${PAGES.SETTINGS_BLOCKED_MUTED}`} component={ListBlockedPage} />
|
||||||
<PrivateRoute {...props} path={`/$/${PAGES.SETTINGS_CREATOR}`} component={SettingsCreatorPage} />
|
<PrivateRoute {...props} path={`/$/${PAGES.SETTINGS_CREATOR}`} component={SettingsCreatorPage} />
|
||||||
|
|
|
@ -27,6 +27,7 @@ exports.HOME = 'home';
|
||||||
exports.HELP = 'help';
|
exports.HELP = 'help';
|
||||||
exports.LIBRARY = 'library';
|
exports.LIBRARY = 'library';
|
||||||
exports.LISTS = 'lists';
|
exports.LISTS = 'lists';
|
||||||
|
exports.PLAYLISTS = 'playlists';
|
||||||
exports.INVITE = 'invite';
|
exports.INVITE = 'invite';
|
||||||
exports.DEPRECATED__PUBLISH = 'publish';
|
exports.DEPRECATED__PUBLISH = 'publish';
|
||||||
exports.DEPRECATED__PUBLISHED = 'published';
|
exports.DEPRECATED__PUBLISHED = 'published';
|
||||||
|
|
|
@ -1,31 +1,3 @@
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
import { doPurchaseList } from 'redux/actions/claims';
|
|
||||||
import { selectMyPurchases, selectIsFetchingMyPurchases } from 'redux/selectors/claims';
|
|
||||||
import { selectDownloadUrlsCount, selectIsFetchingFileList } from 'redux/selectors/file_info';
|
|
||||||
|
|
||||||
import {
|
|
||||||
selectBuiltinCollections,
|
|
||||||
selectMyPublishedMixedCollections,
|
|
||||||
selectMyPublishedPlaylistCollections,
|
|
||||||
selectMyUnpublishedCollections, // should probably distinguish types
|
|
||||||
// selectSavedCollections, // TODO: implement saving and copying collections
|
|
||||||
} from 'redux/selectors/collections';
|
|
||||||
|
|
||||||
import ListsPage from './view';
|
import ListsPage from './view';
|
||||||
|
|
||||||
const select = (state) => ({
|
export default ListsPage;
|
||||||
allDownloadedUrlsCount: selectDownloadUrlsCount(state),
|
|
||||||
fetchingFileList: selectIsFetchingFileList(state),
|
|
||||||
myPurchases: selectMyPurchases(state),
|
|
||||||
fetchingMyPurchases: selectIsFetchingMyPurchases(state),
|
|
||||||
builtinCollections: selectBuiltinCollections(state),
|
|
||||||
publishedCollections: selectMyPublishedMixedCollections(state),
|
|
||||||
publishedPlaylists: selectMyPublishedPlaylistCollections(state),
|
|
||||||
unpublishedCollections: selectMyUnpublishedCollections(state),
|
|
||||||
// savedCollections: selectSavedCollections(state),
|
|
||||||
});
|
|
||||||
|
|
||||||
export default connect(select, {
|
|
||||||
doPurchaseList,
|
|
||||||
})(ListsPage);
|
|
||||||
|
|
3
ui/page/playlists/index.js
Normal file
3
ui/page/playlists/index.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import PlaylistsPage from './view';
|
||||||
|
|
||||||
|
export default PlaylistsPage;
|
22
ui/page/playlists/view.jsx
Normal file
22
ui/page/playlists/view.jsx
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// @flow
|
||||||
|
import * as ICONS from 'constants/icons';
|
||||||
|
import React from 'react';
|
||||||
|
import Page from 'component/page';
|
||||||
|
import PlaylistsMine from 'component/playlistsMine';
|
||||||
|
import Icon from 'component/common/icon';
|
||||||
|
|
||||||
|
function PlaylistsPage() {
|
||||||
|
return (
|
||||||
|
<Page>
|
||||||
|
<label className="claim-list__header-label">
|
||||||
|
<span>
|
||||||
|
<Icon icon={ICONS.STACK} size={10} />
|
||||||
|
{__('Playlists')}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<PlaylistsMine />
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PlaylistsPage;
|
|
@ -136,3 +136,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.collection-grid__results-summary {
|
||||||
|
padding: 0;
|
||||||
|
padding-bottom: var(--spacing-m);
|
||||||
|
color: var(--color-text-help);
|
||||||
|
}
|
||||||
|
|
|
@ -313,17 +313,19 @@ fieldset-group {
|
||||||
}
|
}
|
||||||
|
|
||||||
&:nth-of-type(2) {
|
&:nth-of-type(2) {
|
||||||
|
&:not(input.paginate-channel) {
|
||||||
|
// yuck
|
||||||
input,
|
input,
|
||||||
select {
|
select {
|
||||||
border-top-left-radius: 0;
|
border-top-left-radius: 0;
|
||||||
border-bottom-left-radius: 0;
|
border-bottom-left-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
margin-left: var(--spacing-s);
|
margin-left: var(--spacing-s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.fieldgroup--paginate {
|
&.fieldgroup--paginate {
|
||||||
padding-bottom: var(--spacing-l);
|
padding-bottom: var(--spacing-l);
|
||||||
|
@ -331,6 +333,12 @@ fieldset-group {
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.fieldgroup--paginate-top {
|
||||||
|
padding-bottom: var(--spacing-m);
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is a special case where the prefix appears "inside" the input
|
// This is a special case where the prefix appears "inside" the input
|
||||||
|
|
|
@ -48,6 +48,11 @@
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.section__header-action-stack {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
.section__flex {
|
.section__flex {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|
Loading…
Reference in a new issue