@wordpress/ui 0.11.0 → 0.12.1-next.v.202604201441.0
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/CHANGELOG.md +24 -0
- package/README.md +4 -4
- package/build/alert-dialog/popup.cjs +4 -4
- package/build/alert-dialog/popup.cjs.map +2 -2
- package/build/collapsible-card/header.cjs +10 -0
- package/build/collapsible-card/header.cjs.map +3 -3
- package/build/dialog/context.cjs +21 -9
- package/build/dialog/context.cjs.map +2 -2
- package/build/dialog/footer.cjs +4 -4
- package/build/dialog/footer.cjs.map +2 -2
- package/build/dialog/header.cjs +4 -4
- package/build/dialog/header.cjs.map +2 -2
- package/build/dialog/popup.cjs +4 -4
- package/build/dialog/popup.cjs.map +2 -2
- package/build/dialog/title.cjs +9 -6
- package/build/dialog/title.cjs.map +2 -2
- package/build/form/primitives/select/item.cjs +3 -3
- package/build/form/primitives/select/item.cjs.map +2 -2
- package/build/form/primitives/select/popup.cjs +3 -3
- package/build/form/primitives/select/popup.cjs.map +2 -2
- package/build/link/link.cjs +8 -18
- package/build/link/link.cjs.map +2 -2
- package/build/link/types.cjs.map +1 -1
- package/build/notice/action-button.cjs +3 -3
- package/build/notice/action-button.cjs.map +2 -2
- package/build/notice/action-link.cjs +8 -7
- package/build/notice/action-link.cjs.map +2 -2
- package/build/notice/actions.cjs +3 -3
- package/build/notice/actions.cjs.map +2 -2
- package/build/notice/close-icon.cjs +3 -3
- package/build/notice/close-icon.cjs.map +2 -2
- package/build/notice/description.cjs +3 -3
- package/build/notice/description.cjs.map +2 -2
- package/build/notice/root.cjs +3 -3
- package/build/notice/root.cjs.map +2 -2
- package/build/notice/title.cjs +3 -3
- package/build/notice/title.cjs.map +2 -2
- package/build/popover/arrow.cjs +4 -4
- package/build/popover/arrow.cjs.map +2 -2
- package/build/popover/context.cjs +21 -9
- package/build/popover/context.cjs.map +2 -2
- package/build/popover/description.cjs +4 -4
- package/build/popover/description.cjs.map +2 -2
- package/build/popover/popup.cjs +8 -5
- package/build/popover/popup.cjs.map +2 -2
- package/build/popover/title.cjs +5 -2
- package/build/popover/title.cjs.map +2 -2
- package/build/tabs/context.cjs +9 -22
- package/build/tabs/context.cjs.map +2 -2
- package/build/tabs/list.cjs +4 -4
- package/build/tabs/list.cjs.map +2 -2
- package/build/tabs/panel.cjs +19 -6
- package/build/tabs/panel.cjs.map +3 -3
- package/build/tabs/tab.cjs +4 -4
- package/build/tabs/tab.cjs.map +2 -2
- package/build/tooltip/popup.cjs +4 -4
- package/build/tooltip/popup.cjs.map +2 -2
- package/build/utils/use-schedule-validation.cjs +59 -0
- package/build/utils/use-schedule-validation.cjs.map +7 -0
- package/build-module/alert-dialog/popup.mjs +4 -4
- package/build-module/alert-dialog/popup.mjs.map +2 -2
- package/build-module/collapsible-card/header.mjs +10 -0
- package/build-module/collapsible-card/header.mjs.map +3 -3
- package/build-module/dialog/context.mjs +21 -9
- package/build-module/dialog/context.mjs.map +2 -2
- package/build-module/dialog/footer.mjs +4 -4
- package/build-module/dialog/footer.mjs.map +2 -2
- package/build-module/dialog/header.mjs +4 -4
- package/build-module/dialog/header.mjs.map +2 -2
- package/build-module/dialog/popup.mjs +4 -4
- package/build-module/dialog/popup.mjs.map +2 -2
- package/build-module/dialog/title.mjs +10 -7
- package/build-module/dialog/title.mjs.map +2 -2
- package/build-module/form/primitives/select/item.mjs +3 -3
- package/build-module/form/primitives/select/item.mjs.map +2 -2
- package/build-module/form/primitives/select/popup.mjs +3 -3
- package/build-module/form/primitives/select/popup.mjs.map +2 -2
- package/build-module/link/link.mjs +8 -18
- package/build-module/link/link.mjs.map +2 -2
- package/build-module/notice/action-button.mjs +3 -3
- package/build-module/notice/action-button.mjs.map +2 -2
- package/build-module/notice/action-link.mjs +8 -7
- package/build-module/notice/action-link.mjs.map +2 -2
- package/build-module/notice/actions.mjs +3 -3
- package/build-module/notice/actions.mjs.map +2 -2
- package/build-module/notice/close-icon.mjs +3 -3
- package/build-module/notice/close-icon.mjs.map +2 -2
- package/build-module/notice/description.mjs +3 -3
- package/build-module/notice/description.mjs.map +2 -2
- package/build-module/notice/root.mjs +3 -3
- package/build-module/notice/root.mjs.map +2 -2
- package/build-module/notice/title.mjs +3 -3
- package/build-module/notice/title.mjs.map +2 -2
- package/build-module/popover/arrow.mjs +4 -4
- package/build-module/popover/arrow.mjs.map +2 -2
- package/build-module/popover/context.mjs +21 -9
- package/build-module/popover/context.mjs.map +2 -2
- package/build-module/popover/description.mjs +4 -4
- package/build-module/popover/description.mjs.map +2 -2
- package/build-module/popover/popup.mjs +8 -5
- package/build-module/popover/popup.mjs.map +2 -2
- package/build-module/popover/title.mjs +6 -3
- package/build-module/popover/title.mjs.map +2 -2
- package/build-module/tabs/context.mjs +11 -24
- package/build-module/tabs/context.mjs.map +2 -2
- package/build-module/tabs/list.mjs +4 -4
- package/build-module/tabs/list.mjs.map +2 -2
- package/build-module/tabs/panel.mjs +19 -6
- package/build-module/tabs/panel.mjs.map +3 -3
- package/build-module/tabs/tab.mjs +4 -4
- package/build-module/tabs/tab.mjs.map +2 -2
- package/build-module/tooltip/popup.mjs +4 -4
- package/build-module/tooltip/popup.mjs.map +2 -2
- package/build-module/utils/use-schedule-validation.mjs +34 -0
- package/build-module/utils/use-schedule-validation.mjs.map +7 -0
- package/build-types/alert-dialog/stories/index.story.d.ts +1 -1
- package/build-types/alert-dialog/stories/index.story.d.ts.map +1 -1
- package/build-types/badge/stories/index.story.d.ts.map +1 -1
- package/build-types/collapsible-card/header.d.ts.map +1 -1
- package/build-types/dialog/context.d.ts +1 -1
- package/build-types/dialog/context.d.ts.map +1 -1
- package/build-types/dialog/title.d.ts.map +1 -1
- package/build-types/empty-state/stories/index.story.d.ts +1 -1
- package/build-types/empty-state/stories/index.story.d.ts.map +1 -1
- package/build-types/form/input-control/stories/index.story.d.ts +1 -1
- package/build-types/form/input-control/stories/index.story.d.ts.map +1 -1
- package/build-types/form/primitives/field/stories/index.story.d.ts +1 -1
- package/build-types/form/primitives/field/stories/index.story.d.ts.map +1 -1
- package/build-types/form/primitives/fieldset/stories/index.story.d.ts +1 -1
- package/build-types/form/primitives/fieldset/stories/index.story.d.ts.map +1 -1
- package/build-types/form/primitives/input/stories/index.story.d.ts +1 -1
- package/build-types/form/primitives/input/stories/index.story.d.ts.map +1 -1
- package/build-types/form/primitives/input-layout/stories/index.story.d.ts +1 -1
- package/build-types/form/primitives/input-layout/stories/index.story.d.ts.map +1 -1
- package/build-types/form/primitives/select/stories/index.story.d.ts +1 -1
- package/build-types/form/primitives/select/stories/index.story.d.ts.map +1 -1
- package/build-types/link/link.d.ts.map +1 -1
- package/build-types/link/types.d.ts +1 -2
- package/build-types/link/types.d.ts.map +1 -1
- package/build-types/notice/action-link.d.ts.map +1 -1
- package/build-types/popover/context.d.ts +1 -1
- package/build-types/popover/context.d.ts.map +1 -1
- package/build-types/popover/popup.d.ts.map +1 -1
- package/build-types/popover/stories/index.story.d.ts +1 -1
- package/build-types/popover/stories/index.story.d.ts.map +1 -1
- package/build-types/popover/title.d.ts.map +1 -1
- package/build-types/stack/stories/index.story.d.ts.map +1 -1
- package/build-types/tabs/context.d.ts.map +1 -1
- package/build-types/tabs/panel.d.ts.map +1 -1
- package/build-types/tabs/stories/index.story.d.ts +1 -1
- package/build-types/tabs/stories/index.story.d.ts.map +1 -1
- package/build-types/text/stories/index.story.d.ts.map +1 -1
- package/build-types/tooltip/stories/index.story.d.ts +1 -1
- package/build-types/tooltip/stories/index.story.d.ts.map +1 -1
- package/build-types/tooltip/stories/usage-guidelines.story.d.ts.map +1 -1
- package/build-types/utils/use-schedule-validation.d.ts +13 -0
- package/build-types/utils/use-schedule-validation.d.ts.map +1 -0
- package/package.json +11 -11
- package/src/alert-dialog/stories/index.story.tsx +2 -2
- package/src/badge/stories/choosing-intent.story.tsx +1 -1
- package/src/badge/stories/index.story.tsx +1 -0
- package/src/collapsible-card/header.tsx +2 -0
- package/src/dialog/context.tsx +28 -15
- package/src/dialog/style.module.css +12 -0
- package/src/dialog/test/index.test.tsx +222 -142
- package/src/dialog/title.tsx +6 -4
- package/src/empty-state/stories/index.story.tsx +2 -1
- package/src/form/input-control/stories/index.story.tsx +4 -1
- package/src/form/primitives/field/stories/index.story.tsx +1 -1
- package/src/form/primitives/fieldset/stories/index.story.tsx +1 -1
- package/src/form/primitives/input/stories/index.story.tsx +2 -1
- package/src/form/primitives/input-layout/stories/index.story.tsx +2 -1
- package/src/form/primitives/select/stories/index.story.tsx +1 -1
- package/src/link/link.tsx +12 -26
- package/src/link/style.module.css +4 -16
- package/src/link/test/index.test.tsx +31 -27
- package/src/link/types.ts +1 -2
- package/src/notice/action-link.tsx +7 -4
- package/src/notice/style.module.css +5 -5
- package/src/popover/context.tsx +28 -12
- package/src/popover/popup.tsx +4 -1
- package/src/popover/stories/index.story.tsx +2 -1
- package/src/popover/style.module.css +23 -1
- package/src/popover/test/index.test.tsx +146 -70
- package/src/popover/title.tsx +6 -3
- package/src/stack/stories/index.story.tsx +1 -0
- package/src/tabs/context.tsx +14 -34
- package/src/tabs/panel.tsx +7 -2
- package/src/tabs/stories/index.story.tsx +2 -1
- package/src/tabs/style.module.css +0 -17
- package/src/tabs/test/index.test.tsx +7 -3
- package/src/text/stories/index.story.tsx +1 -0
- package/src/tooltip/stories/index.story.tsx +2 -1
- package/src/tooltip/stories/usage-guidelines.story.tsx +5 -1
- package/src/tooltip/style.module.css +12 -0
- package/src/utils/css/item-popup.module.css +12 -0
- package/src/utils/use-schedule-validation.ts +45 -0
- package/build/types/css-modules.d.cjs +0 -2
- package/build/types/css-modules.d.cjs.map +0 -7
- package/build/types/react.d.cjs +0 -5
- package/build/types/react.d.cjs.map +0 -7
- package/build-module/types/css-modules.d.mjs +0 -1
- package/build-module/types/css-modules.d.mjs.map +0 -7
- package/build-module/types/react.d.mjs +0 -3
- package/build-module/types/react.d.mjs.map +0 -7
- package/src/types/css-modules.d.ts +0 -4
- package/src/types/react.d.ts +0 -7
package/src/dialog/title.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Dialog as _Dialog } from '@base-ui/react/dialog';
|
|
2
2
|
import { useMergeRefs } from '@wordpress/compose';
|
|
3
|
-
import { forwardRef,
|
|
3
|
+
import { forwardRef, useEffect, useRef } from '@wordpress/element';
|
|
4
4
|
import { Text } from '../text';
|
|
5
5
|
import { useDialogValidationContext } from './context';
|
|
6
6
|
import styles from './style.module.css';
|
|
@@ -30,9 +30,11 @@ const Title = forwardRef< HTMLHeadingElement, TitleProps >(
|
|
|
30
30
|
const internalRef = useRef< HTMLHeadingElement >( null );
|
|
31
31
|
const mergedRef = useMergeRefs( [ internalRef, forwardedRef ] );
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
useEffect( () => {
|
|
34
|
+
if ( validationContext ) {
|
|
35
|
+
return validationContext.registerTitle( internalRef.current );
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
36
38
|
}, [ validationContext ] );
|
|
37
39
|
|
|
38
40
|
return (
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
2
|
import { search } from '@wordpress/icons';
|
|
3
|
-
import { Button
|
|
3
|
+
import { Button } from '../../button';
|
|
4
|
+
import * as EmptyState from '../';
|
|
4
5
|
|
|
5
6
|
const meta: Meta< typeof EmptyState.Root > = {
|
|
6
7
|
title: 'Design System/Components/EmptyState',
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
2
|
import { useState } from '@wordpress/element';
|
|
3
3
|
import { plus, reset, seen, unseen } from '@wordpress/icons';
|
|
4
|
-
import {
|
|
4
|
+
import { InputControl } from '../';
|
|
5
|
+
import { IconButton } from '../../../icon-button';
|
|
6
|
+
import { InputLayout } from '../../primitives/input-layout';
|
|
7
|
+
import { Stack } from '../../../stack';
|
|
5
8
|
import {
|
|
6
9
|
WithPrefix,
|
|
7
10
|
WithSuffixControl,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
2
|
import { useId } from '@wordpress/element';
|
|
3
|
-
import
|
|
3
|
+
import * as Field from '../';
|
|
4
4
|
import { DETAILS_EXAMPLE } from '../../../stories/shared';
|
|
5
5
|
|
|
6
6
|
const meta: Meta< typeof Field.Root > = {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
-
import { Input
|
|
2
|
+
import { Input } from '../';
|
|
3
|
+
import { InputLayout } from '../../input-layout';
|
|
3
4
|
import { WithSuffixControl } from '../../input-layout/stories/index.story';
|
|
4
5
|
|
|
5
6
|
const meta: Meta< typeof Input > = {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
2
|
import { copy } from '@wordpress/icons';
|
|
3
|
-
import {
|
|
3
|
+
import { InputLayout } from '../';
|
|
4
|
+
import { IconButton } from '../../../../icon-button';
|
|
4
5
|
|
|
5
6
|
const meta: Meta< typeof InputLayout > = {
|
|
6
7
|
title: 'Design System/Components/Form/Primitives/InputLayout',
|
package/src/link/link.tsx
CHANGED
|
@@ -20,20 +20,10 @@ export const Link = forwardRef< HTMLAnchorElement, LinkProps >( function Link(
|
|
|
20
20
|
openInNewTab = false,
|
|
21
21
|
render,
|
|
22
22
|
className,
|
|
23
|
-
onClick,
|
|
24
23
|
...props
|
|
25
24
|
},
|
|
26
25
|
ref
|
|
27
26
|
) {
|
|
28
|
-
const isInternalAnchor = !! props.href?.startsWith( '#' );
|
|
29
|
-
|
|
30
|
-
const handleClick = ( event: React.MouseEvent< HTMLAnchorElement > ) => {
|
|
31
|
-
if ( openInNewTab && isInternalAnchor ) {
|
|
32
|
-
event.preventDefault();
|
|
33
|
-
}
|
|
34
|
-
onClick?.( event );
|
|
35
|
-
};
|
|
36
|
-
|
|
37
27
|
const element = useRender( {
|
|
38
28
|
render,
|
|
39
29
|
defaultTagName: 'a',
|
|
@@ -46,27 +36,23 @@ export const Link = forwardRef< HTMLAnchorElement, LinkProps >( function Link(
|
|
|
46
36
|
variant !== 'unstyled' && styles.link,
|
|
47
37
|
variant !== 'unstyled' && styles[ `is-${ tone }` ],
|
|
48
38
|
variant === 'unstyled' && styles[ 'is-unstyled' ],
|
|
49
|
-
openInNewTab && styles[ 'has-link-icon' ],
|
|
50
39
|
className
|
|
51
40
|
),
|
|
52
|
-
onClick: handleClick,
|
|
53
41
|
target: openInNewTab ? '_blank' : undefined,
|
|
54
|
-
children:
|
|
42
|
+
children: (
|
|
55
43
|
<>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
44
|
+
{ children }
|
|
45
|
+
{ openInNewTab && (
|
|
46
|
+
<span
|
|
47
|
+
className={ styles[ 'link-icon' ] }
|
|
48
|
+
role="img"
|
|
49
|
+
aria-label={
|
|
50
|
+
/* translators: accessibility text appended to link text */
|
|
51
|
+
__( '(opens in a new tab)' )
|
|
52
|
+
}
|
|
53
|
+
/>
|
|
54
|
+
) }
|
|
67
55
|
</>
|
|
68
|
-
) : (
|
|
69
|
-
children
|
|
70
56
|
),
|
|
71
57
|
} ),
|
|
72
58
|
} );
|
|
@@ -46,26 +46,14 @@
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
/* Link icon pattern — arrow rendered via ::after pseudo-element to avoid
|
|
49
|
-
* Twemoji replacement and text-selection issues.
|
|
50
|
-
*
|
|
51
|
-
* text-underline-offset is inherited and propagates from .link
|
|
52
|
-
* automatically. text-decoration-thickness and text-decoration-color
|
|
53
|
-
* are NOT inherited, so they are explicitly redeclared on
|
|
54
|
-
* .link-contents (the latter via `inherit` to carry the neutral
|
|
55
|
-
* tone's custom color token through). */
|
|
56
|
-
.has-link-icon {
|
|
57
|
-
text-decoration: none;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
.link-contents {
|
|
61
|
-
text-decoration: underline;
|
|
62
|
-
text-decoration-color: inherit;
|
|
63
|
-
text-decoration-thickness: 0.5px;
|
|
64
|
-
}
|
|
49
|
+
* Twemoji replacement and text-selection issues. The icon is an
|
|
50
|
+
* inline-block so the link underline stays scoped to the text. */
|
|
65
51
|
|
|
66
52
|
.link-icon {
|
|
53
|
+
display: inline-block;
|
|
67
54
|
margin-inline-start: var(--wpds-dimension-padding-xs);
|
|
68
55
|
font-weight: var(--wpds-typography-font-weight-regular);
|
|
56
|
+
text-decoration: none;
|
|
69
57
|
}
|
|
70
58
|
|
|
71
59
|
.link-icon::after {
|
|
@@ -16,6 +16,24 @@ describe( 'Link', () => {
|
|
|
16
16
|
expect( ref.current ).toBeInstanceOf( HTMLAnchorElement );
|
|
17
17
|
} );
|
|
18
18
|
|
|
19
|
+
it( 'calls onClick when clicked (often used for analytics tracking)', async () => {
|
|
20
|
+
const user = userEvent.setup();
|
|
21
|
+
const onClick = jest.fn(
|
|
22
|
+
( event: React.MouseEvent< HTMLAnchorElement > ) =>
|
|
23
|
+
event.preventDefault()
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
render(
|
|
27
|
+
<Link href="/page" onClick={ onClick }>
|
|
28
|
+
Go to page
|
|
29
|
+
</Link>
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
await user.click( screen.getByRole( 'link', { name: 'Go to page' } ) );
|
|
33
|
+
|
|
34
|
+
expect( onClick ).toHaveBeenCalledTimes( 1 );
|
|
35
|
+
} );
|
|
36
|
+
|
|
19
37
|
describe( 'openInNewTab', () => {
|
|
20
38
|
it( 'sets target="_blank" when true', () => {
|
|
21
39
|
render(
|
|
@@ -47,47 +65,33 @@ describe( 'Link', () => {
|
|
|
47
65
|
|
|
48
66
|
expect(
|
|
49
67
|
screen.getByLabelText( '(opens in a new tab)' )
|
|
50
|
-
).
|
|
68
|
+
).toBeVisible();
|
|
51
69
|
} );
|
|
52
70
|
|
|
53
|
-
it( '
|
|
54
|
-
const user = userEvent.setup();
|
|
55
|
-
const onClick = jest.fn();
|
|
56
|
-
|
|
71
|
+
it( 'keeps the link text on the anchor element', () => {
|
|
57
72
|
render(
|
|
58
|
-
<Link href="
|
|
59
|
-
|
|
73
|
+
<Link href="https://example.com" openInNewTab>
|
|
74
|
+
External
|
|
60
75
|
</Link>
|
|
61
76
|
);
|
|
62
77
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
expect( onClick ).toHaveBeenCalledTimes( 1 );
|
|
66
|
-
expect( onClick.mock.calls[ 0 ][ 0 ].defaultPrevented ).toBe(
|
|
67
|
-
true
|
|
78
|
+
expect( screen.getByText( 'External' ) ).toBe(
|
|
79
|
+
screen.getByRole( 'link' )
|
|
68
80
|
);
|
|
69
81
|
} );
|
|
70
82
|
|
|
71
|
-
it( '
|
|
72
|
-
const user = userEvent.setup();
|
|
73
|
-
const onClick = jest.fn();
|
|
74
|
-
|
|
83
|
+
it( 'includes the new tab notice in the link name', () => {
|
|
75
84
|
render(
|
|
76
|
-
<Link
|
|
77
|
-
href="https://example.com"
|
|
78
|
-
openInNewTab
|
|
79
|
-
onClick={ onClick }
|
|
80
|
-
>
|
|
85
|
+
<Link href="https://example.com" openInNewTab>
|
|
81
86
|
External
|
|
82
87
|
</Link>
|
|
83
88
|
);
|
|
84
89
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
);
|
|
90
|
+
expect(
|
|
91
|
+
screen.getByRole( 'link', {
|
|
92
|
+
name: 'External (opens in a new tab)',
|
|
93
|
+
} )
|
|
94
|
+
).toBeVisible();
|
|
91
95
|
} );
|
|
92
96
|
} );
|
|
93
97
|
} );
|
package/src/link/types.ts
CHANGED
|
@@ -22,8 +22,7 @@ export interface LinkProps extends Omit< ComponentProps< 'a' >, 'target' > {
|
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* Whether to open the link in a new browser tab.
|
|
25
|
-
* When true, sets `target="_blank"
|
|
26
|
-
* and prevents navigation for internal anchors (`#`-prefixed hrefs).
|
|
25
|
+
* When true, sets `target="_blank"` and appends a visual arrow indicator.
|
|
27
26
|
*
|
|
28
27
|
* @default false
|
|
29
28
|
*/
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
2
|
import { forwardRef } from '@wordpress/element';
|
|
3
3
|
import { Link } from '../link';
|
|
4
|
+
import { Text } from '../text';
|
|
4
5
|
import type { ActionLinkProps } from './types';
|
|
5
6
|
import styles from './style.module.css';
|
|
6
7
|
|
|
@@ -8,14 +9,16 @@ import styles from './style.module.css';
|
|
|
8
9
|
* An action link for use within Notice.Actions.
|
|
9
10
|
*/
|
|
10
11
|
export const ActionLink = forwardRef< HTMLAnchorElement, ActionLinkProps >(
|
|
11
|
-
function NoticeActionLink( { className, ...props }, ref ) {
|
|
12
|
+
function NoticeActionLink( { className, render, ...props }, ref ) {
|
|
12
13
|
return (
|
|
13
|
-
<
|
|
14
|
+
<Text
|
|
14
15
|
ref={ ref }
|
|
15
16
|
className={ clsx( styles[ 'action-link' ], className ) }
|
|
16
17
|
{ ...props }
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
variant="body-md"
|
|
19
|
+
render={
|
|
20
|
+
<Link tone="neutral" variant="default" render={ render } />
|
|
21
|
+
}
|
|
19
22
|
/>
|
|
20
23
|
);
|
|
21
24
|
}
|
|
@@ -64,11 +64,6 @@
|
|
|
64
64
|
|
|
65
65
|
.action-link {
|
|
66
66
|
flex-shrink: 0;
|
|
67
|
-
font-family: var(--wpds-typography-font-family-body);
|
|
68
|
-
font-size: var(--wpds-typography-font-size-md);
|
|
69
|
-
font-weight: var(--wpds-typography-font-weight-regular);
|
|
70
|
-
line-height: var(--wpds-typography-line-height-sm);
|
|
71
|
-
margin-block: auto;
|
|
72
67
|
|
|
73
68
|
/* Add more horizontal space when following another action link/button */
|
|
74
69
|
&:not(:first-child) {
|
|
@@ -125,6 +120,11 @@
|
|
|
125
120
|
}
|
|
126
121
|
|
|
127
122
|
@layer wp-ui-compositions {
|
|
123
|
+
/* Override `Text` margin */
|
|
124
|
+
.action-link {
|
|
125
|
+
margin-block: auto;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
128
|
/* Add partial transparency to CloseIcon and outline/minimal ActionButton
|
|
129
129
|
* for a better look over tinted backgrounds */
|
|
130
130
|
.close-icon,
|
package/src/popover/context.tsx
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
useMemo,
|
|
7
7
|
useRef,
|
|
8
8
|
} from '@wordpress/element';
|
|
9
|
+
import { useScheduleValidation } from '../utils/use-schedule-validation';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Whether validation is enabled. This is a build-time constant that allows
|
|
@@ -14,7 +15,7 @@ import {
|
|
|
14
15
|
const VALIDATION_ENABLED = process.env.NODE_ENV !== 'production';
|
|
15
16
|
|
|
16
17
|
type PopoverValidationContextType = {
|
|
17
|
-
registerTitle: ( element: HTMLElement | null ) => void;
|
|
18
|
+
registerTitle: ( element: HTMLElement | null ) => () => void;
|
|
18
19
|
};
|
|
19
20
|
|
|
20
21
|
const PopoverValidationContext = VALIDATION_ENABLED
|
|
@@ -47,16 +48,7 @@ function PopoverValidationProviderDev( {
|
|
|
47
48
|
} ) {
|
|
48
49
|
const titleElementRef = useRef< HTMLElement | null >( null );
|
|
49
50
|
|
|
50
|
-
const
|
|
51
|
-
titleElementRef.current = element;
|
|
52
|
-
}, [] );
|
|
53
|
-
|
|
54
|
-
const contextValue = useMemo(
|
|
55
|
-
() => ( { registerTitle } ),
|
|
56
|
-
[ registerTitle ]
|
|
57
|
-
);
|
|
58
|
-
|
|
59
|
-
useEffect( () => {
|
|
51
|
+
const scheduleValidation = useScheduleValidation( () => {
|
|
60
52
|
const titleElement = titleElementRef.current;
|
|
61
53
|
|
|
62
54
|
if ( ! titleElement ) {
|
|
@@ -74,7 +66,31 @@ function PopoverValidationProviderDev( {
|
|
|
74
66
|
'Provide meaningful text content for the popover title.'
|
|
75
67
|
);
|
|
76
68
|
}
|
|
77
|
-
}
|
|
69
|
+
} );
|
|
70
|
+
|
|
71
|
+
const registerTitle = useCallback(
|
|
72
|
+
( element: HTMLElement | null ) => {
|
|
73
|
+
titleElementRef.current = element;
|
|
74
|
+
scheduleValidation();
|
|
75
|
+
|
|
76
|
+
return () => {
|
|
77
|
+
titleElementRef.current = null;
|
|
78
|
+
scheduleValidation();
|
|
79
|
+
};
|
|
80
|
+
},
|
|
81
|
+
[ scheduleValidation ]
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
// Schedule an initial validation on mount to catch missing titles
|
|
85
|
+
// (when no Title component is rendered, registerTitle is never called).
|
|
86
|
+
useEffect( () => {
|
|
87
|
+
scheduleValidation();
|
|
88
|
+
}, [ scheduleValidation ] );
|
|
89
|
+
|
|
90
|
+
const contextValue = useMemo(
|
|
91
|
+
() => ( { registerTitle } ),
|
|
92
|
+
[ registerTitle ]
|
|
93
|
+
);
|
|
78
94
|
|
|
79
95
|
return (
|
|
80
96
|
<PopoverValidationContext.Provider value={ contextValue }>
|
package/src/popover/popup.tsx
CHANGED
|
@@ -84,7 +84,10 @@ const Popup = forwardRef< HTMLDivElement, PopupProps >( function PopoverPopup(
|
|
|
84
84
|
ref={ mergedPopupRef }
|
|
85
85
|
initialFocus={ resolvedInitialFocus }
|
|
86
86
|
finalFocus={ finalFocus }
|
|
87
|
-
className={ clsx(
|
|
87
|
+
className={ clsx(
|
|
88
|
+
styles.popup,
|
|
89
|
+
variant !== 'unstyled' && styles.default
|
|
90
|
+
) }
|
|
88
91
|
{ ...props }
|
|
89
92
|
>
|
|
90
93
|
<PopoverValidationProvider>
|
|
@@ -2,7 +2,8 @@ import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
|
2
2
|
import { useId, useRef, useState } from '@wordpress/element';
|
|
3
3
|
import { SlotFillProvider, Slot } from '@wordpress/components';
|
|
4
4
|
import { close, info } from '@wordpress/icons';
|
|
5
|
-
import
|
|
5
|
+
import * as Popover from '../';
|
|
6
|
+
import { VisuallyHidden } from '../../visually-hidden';
|
|
6
7
|
import { Icon } from '../../icon';
|
|
7
8
|
import { IconButton } from '../../icon-button';
|
|
8
9
|
import { GenericIframe, useMeasure } from './utils';
|
|
@@ -1,11 +1,33 @@
|
|
|
1
1
|
@layer wp-ui-utilities, wp-ui-components, wp-ui-compositions, wp-ui-overrides;
|
|
2
2
|
|
|
3
|
+
/*
|
|
4
|
+
* Temporary workaround for a Base UI tabbability regression with
|
|
5
|
+
* checkVisibility() and display: contents.
|
|
6
|
+
* See: https://github.com/mui/base-ui/issues/4622
|
|
7
|
+
*
|
|
8
|
+
* This must stay outside the CSS layers to override ThemeProvider's
|
|
9
|
+
* unlayered display: contents.
|
|
10
|
+
*/
|
|
11
|
+
[data-wpds-theme-provider-id]:has(> .popup) {
|
|
12
|
+
display: block;
|
|
13
|
+
}
|
|
14
|
+
|
|
3
15
|
@layer wp-ui-components {
|
|
4
16
|
.positioner {
|
|
5
17
|
z-index: var(--wp-ui-popover-z-index, initial);
|
|
6
18
|
}
|
|
7
19
|
|
|
8
|
-
|
|
20
|
+
/*
|
|
21
|
+
* Structural marker; no visual styles. Always applied to the popup so
|
|
22
|
+
* the ThemeProvider display workaround above matches regardless of
|
|
23
|
+
* `variant`. Visuals live in `.default`.
|
|
24
|
+
*/
|
|
25
|
+
/* stylelint-disable-next-line block-no-empty -- structural marker for the
|
|
26
|
+
* ThemeProvider display workaround above; kept class-based (not a data
|
|
27
|
+
* attribute) so it is defined alongside the other component classes. */
|
|
28
|
+
.popup {}
|
|
29
|
+
|
|
30
|
+
.default {
|
|
9
31
|
background-color: var(--wpds-color-bg-surface-neutral-strong);
|
|
10
32
|
padding: var(--wpds-dimension-padding-lg);
|
|
11
33
|
border-radius: var(--wpds-border-radius-md);
|