Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/dataviews/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

### Enhancements

- DataViews: Add `onReset` prop to control view reset functionality from the view config dropdown. [#75093](https://github.com/WordPress/gutenberg/pull/75093)
- DataForm: Add automatic field labeling - forms now automatically mark the minority of fields (required or optional) to reduce visual noise. [#74430](https://github.com/WordPress/gutenberg/pull/74430)
- DataViews: Add details form layout validation. [#74996](https://github.com/WordPress/gutenberg/pull/74996)
- Add new `adaptiveSelect` DataForm control. [#74937](https://github.com/WordPress/gutenberg/pull/74937)
Expand Down
27 changes: 27 additions & 0 deletions packages/dataviews/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,33 @@ Optional. Pass an object with a list of `perPageSizes` to control the available

An element to display when the `data` prop is empty. Defaults to `<p>No results</p>`.

#### `onReset`: `( () => void ) | false`

Callback function to reset the view to its default state, or `false` to indicate the view is not modified.

- Type: `function` or `false`
- Optional

This prop controls the "Reset view" button in the view configuration dropdown:

- When `undefined` (not provided): No reset functionality is shown. Use this when view persistence is not supported.
- When `false`: The "Reset view" button is shown but disabled. Use this when view persistence is supported but the current view matches the default (not modified).
- When a function: The "Reset view" button is shown and enabled. A blue dot indicator appears on the view options button to signal that the view has been modified. The function is called when the user clicks the reset button.

Example:

```jsx
const { view, setView, isModified, resetToDefault } = useView( 'my-view-key' );

<DataViews
data={ data }
view={ view }
onChangeView={ setView }
onReset={ isModified ? resetToDefault : false }
// ...other props
/>
```

### Styling

These are the CSS Custom Properties that can be used to tweak the appearance of the component:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ type DataViewsContextType< Item > = {
empty?: ReactNode;
hasInfiniteScrollHandler: boolean;
itemListLabel?: string;
onReset?: ( () => void ) | false;
Comment thread
ntsekouras marked this conversation as resolved.
Resolved
};

const DataViewsContext = createContext< DataViewsContextType< any > >( {
Expand Down
107 changes: 59 additions & 48 deletions packages/dataviews/src/components/dataviews-view-config/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ import {
__experimentalToggleGroupControlOption as ToggleGroupControlOption,
__experimentalToggleGroupControlOptionIcon as ToggleGroupControlOptionIcon,
SelectControl,
__experimentalGrid as Grid,
__experimentalHeading as Heading,
__experimentalText as Text,
privateApis as componentsPrivateApis,
} from '@wordpress/components';
import { __, _x } from '@wordpress/i18n';
Expand Down Expand Up @@ -247,53 +245,44 @@ function ItemsPerPageControl() {
);
}

function SettingsSection( {
title,
description,
children,
}: {
title: string;
description?: string;
children: React.ReactNode;
} ) {
function ResetViewButton() {
const { onReset } = useContext( DataViewsContext );

// Don't render if no persistence support (onReset is undefined)
if ( onReset === undefined ) {
return null;
}

const isDisabled = onReset === false;

return (
<Grid columns={ 12 } className="dataviews-settings-section" gap={ 4 }>
Comment thread
youknowriad marked this conversation as resolved.
Resolved
<div className="dataviews-settings-section__sidebar">
<Heading
level={ 2 }
className="dataviews-settings-section__title"
>
{ title }
</Heading>
{ description && (
<Text
variant="muted"
className="dataviews-settings-section__description"
>
{ description }
</Text>
) }
</div>
<Grid
columns={ 8 }
gap={ 4 }
className="dataviews-settings-section__content"
>
{ children }
</Grid>
</Grid>
<Button

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use the Button component from the ui package?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would have a lot of impacts (We'd need to support user color profiles ... which is currently broken if you use ui package in places where ThemeProvider is not setup properly.

cc @aduth as we discussed this elsewhere, see how this seemingly naive suggestion would have broken things.

variant="tertiary"
size="compact"
disabled={ isDisabled }
accessibleWhenDisabled
className="dataviews-view-config__reset-button"
onClick={ () => {
if ( typeof onReset === 'function' ) {
onReset();
}
} }
>
{ __( 'Reset view' ) }
</Button>
);
}

export function DataviewsViewConfigDropdown() {
const { view } = useContext( DataViewsContext );
const { view, onReset } = useContext( DataViewsContext );
const popoverId = useInstanceId(
_DataViewsViewConfig,
'dataviews-view-config-dropdown'
);
const activeLayout = VIEW_LAYOUTS.find(
( layout ) => layout.type === view.type
);
const isModified = typeof onReset === 'function';
return (
<Dropdown
expandOnMobile
Expand All @@ -303,14 +292,22 @@ export function DataviewsViewConfigDropdown() {
} }
renderToggle={ ( { onToggle, isOpen } ) => {
return (
<Button
size="compact"
icon={ cog }
label={ _x( 'View options', 'View is used as a noun' ) }
onClick={ onToggle }
aria-expanded={ isOpen ? 'true' : 'false' }
aria-controls={ popoverId }
/>
<div className="dataviews-view-config__toggle-wrapper">
<Button
size="compact"
icon={ cog }
label={ _x(
'View options',
'View is used as a noun'
) }
onClick={ onToggle }
aria-expanded={ isOpen ? 'true' : 'false' }
aria-controls={ popoverId }
/>
{ isModified && (
<span className="dataviews-view-config__modified-indicator" />
) }
</div>
);
} }
renderContent={ () => (
Expand All @@ -323,11 +320,25 @@ export function DataviewsViewConfigDropdown() {
className="dataviews-view-config"
gap="xl"
>
<SettingsSection title={ __( 'Appearance' ) }>
<Stack
direction="row"
justify="space-between"
align="center"
className="dataviews-view-config__header"
>
<Heading
level={ 2 }
className="dataviews-settings-section__title"
>
{ __( 'Appearance' ) }
</Heading>
<ResetViewButton />
</Stack>
<Stack direction="column" gap="lg">
<Stack
direction="row"
gap="sm"
className="is-divided-in-two"
className="dataviews-view-config__sort-controls"
>
<SortFieldControl />
<SortDirectionControl />
Expand All @@ -338,7 +349,7 @@ export function DataviewsViewConfigDropdown() {
<InfiniteScrollToggle />
<ItemsPerPageControl />
<PropertiesSection />
</SettingsSection>
</Stack>
</Stack>
</DropdownContentWrapper>
) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,27 @@
}
}

.dataviews-view-config__sort-controls > * {
flex: 1;
}

.dataviews-view-config__label {
text-wrap: nowrap;
}

.dataviews-view-config__toggle-wrapper {
position: relative;
display: inline-flex;
}

.dataviews-view-config__modified-indicator {
position: absolute;
top: $grid-unit-05;
right: $grid-unit-05;
width: $grid-unit-05;
height: $grid-unit-05;
background: var(--wp-admin-theme-color, #3858e9);
border-radius: 50%;
pointer-events: none;
}

3 changes: 3 additions & 0 deletions packages/dataviews/src/dataviews/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ type DataViewsProps< Item > = {
perPageSizes: number[];
};
empty?: ReactNode;
onReset?: ( () => void ) | false;
} & ( Item extends ItemWithId
? { getItemId?: ( item: Item ) => string }
: { getItemId: ( item: Item ) => string } );
Expand Down Expand Up @@ -140,6 +141,7 @@ function DataViews< Item >( {
children,
config = { perPageSizes: [ 10, 20, 50, 100 ] },
empty,
onReset,
}: DataViewsProps< Item > ) {
const { infiniteScrollHandler } = paginationInfo;
const containerRef = useRef< HTMLDivElement | null >( null );
Expand Down Expand Up @@ -267,6 +269,7 @@ function DataViews< Item >( {
config,
empty,
hasInfiniteScrollHandler: !! infiniteScrollHandler,
onReset,
} }
>
<div className="dataviews-wrapper" ref={ containerRef }>
Expand Down
20 changes: 5 additions & 15 deletions packages/edit-site/src/components/page-patterns/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { privateApis as routerPrivateApis } from '@wordpress/router';
import { useView } from '@wordpress/views';
import { useSelect } from '@wordpress/data';
import { addQueryArgs } from '@wordpress/url';
import { Button } from '@wordpress/components';

/**
* Internal dependencies
Expand Down Expand Up @@ -205,20 +204,10 @@ export default function DataviewsPatterns() {
title={ title }
subTitle={ description }
actions={
<>
{ isModified && (
<Button
__next40pxDefaultSize
onClick={ resetToDefault }
>
{ __( 'Reset view' ) }
</Button>
) }
<PatternsActions
categoryId={ categoryId }
postType={ postType }
/>
</>
<PatternsActions
categoryId={ categoryId }
postType={ postType }
/>
}
>
<DataViews
Expand Down Expand Up @@ -247,6 +236,7 @@ export default function DataviewsPatterns() {
view={ view }
onChangeView={ updateView }
defaultLayouts={ defaultLayouts }
onReset={ isModified ? resetToDefault : false }
/>
</Page>
</ExperimentalBlockEditorProvider>
Expand Down
26 changes: 9 additions & 17 deletions packages/edit-site/src/components/page-templates/index-legacy.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { privateApis as editorPrivateApis } from '@wordpress/editor';
import { addQueryArgs } from '@wordpress/url';
import { useEvent } from '@wordpress/compose';
import { useView } from '@wordpress/views';
import { Button } from '@wordpress/components';

/**
* Internal dependencies
Expand Down Expand Up @@ -134,22 +133,7 @@ export default function PageTemplates() {
<Page
className="edit-site-page-templates"
title={ __( 'Templates' ) }
actions={
<>
{ isModified && (
<Button
__next40pxDefaultSize
onClick={ () => {
resetToDefault();
history.invalidate();
} }
>
{ __( 'Reset view' ) }
</Button>
) }
<AddNewTemplate />
</>
}
actions={ <AddNewTemplate /> }
>
<DataViews
key={ activeView }
Expand All @@ -167,6 +151,14 @@ export default function PageTemplates() {
} }
selection={ selection }
defaultLayouts={ defaultLayouts }
onReset={
isModified
? () => {
resetToDefault();
history.invalidate();
}
: false
}
/>
</Page>
);
Expand Down
27 changes: 10 additions & 17 deletions packages/edit-site/src/components/page-templates/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { addQueryArgs } from '@wordpress/url';
import { useSelect, useDispatch } from '@wordpress/data';
import { useEvent } from '@wordpress/compose';
import { useView } from '@wordpress/views';
import { Button, Modal } from '@wordpress/components';
import { Modal } from '@wordpress/components';
import { store as noticesStore } from '@wordpress/notices';

/**
Expand Down Expand Up @@ -325,22 +325,7 @@ export default function PageTemplates() {
<Page
className="edit-site-page-templates"
title={ __( 'Templates' ) }
actions={
<>
{ isModified && (
<Button
__next40pxDefaultSize
onClick={ () => {
resetToDefault();
history.invalidate();
} }
>
{ __( 'Reset view' ) }
</Button>
) }
<AddNewTemplate />
</>
}
actions={ <AddNewTemplate /> }
>
<DataViews
key={ activeView }
Expand All @@ -364,6 +349,14 @@ export default function PageTemplates() {
} }
selection={ selection }
defaultLayouts={ defaultLayouts }
onReset={
isModified
? () => {
resetToDefault();
history.invalidate();
}
: false
}
/>
{ selectedRegisteredTemplate && duplicateAction && (
<Modal
Expand Down
Loading
Loading