@wordpress/components 23.4.0 → 23.5.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.
Files changed (105) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/build/autocomplete/autocompleter-ui.js +41 -17
  3. package/build/autocomplete/autocompleter-ui.js.map +1 -1
  4. package/build/autocomplete/index.js +31 -33
  5. package/build/autocomplete/index.js.map +1 -1
  6. package/build/circular-option-picker/index.js +63 -14
  7. package/build/circular-option-picker/index.js.map +1 -1
  8. package/build/circular-option-picker/types.js +6 -0
  9. package/build/circular-option-picker/types.js.map +1 -0
  10. package/build/dropdown-menu/index.js +6 -2
  11. package/build/dropdown-menu/index.js.map +1 -1
  12. package/build/higher-order/with-constrained-tabbing/index.js +9 -0
  13. package/build/higher-order/with-constrained-tabbing/index.js.map +1 -1
  14. package/build/mobile/global-styles-context/utils.native.js +2 -1
  15. package/build/mobile/global-styles-context/utils.native.js.map +1 -1
  16. package/build/range-control/index.js +1 -0
  17. package/build/range-control/index.js.map +1 -1
  18. package/build/tools-panel/context.js +2 -0
  19. package/build/tools-panel/context.js.map +1 -1
  20. package/build/tools-panel/tools-panel/hook.js +18 -12
  21. package/build/tools-panel/tools-panel/hook.js.map +1 -1
  22. package/build/tools-panel/tools-panel-item/hook.js +14 -2
  23. package/build/tools-panel/tools-panel-item/hook.js.map +1 -1
  24. package/build/ui/context/context-system-provider.js +8 -4
  25. package/build/ui/context/context-system-provider.js.map +1 -1
  26. package/build-module/autocomplete/autocompleter-ui.js +40 -19
  27. package/build-module/autocomplete/autocompleter-ui.js.map +1 -1
  28. package/build-module/autocomplete/index.js +30 -32
  29. package/build-module/autocomplete/index.js.map +1 -1
  30. package/build-module/circular-option-picker/index.js +59 -16
  31. package/build-module/circular-option-picker/index.js.map +1 -1
  32. package/build-module/circular-option-picker/types.js +2 -0
  33. package/build-module/circular-option-picker/types.js.map +1 -0
  34. package/build-module/dropdown-menu/index.js +6 -2
  35. package/build-module/dropdown-menu/index.js.map +1 -1
  36. package/build-module/higher-order/with-constrained-tabbing/index.js +9 -0
  37. package/build-module/higher-order/with-constrained-tabbing/index.js.map +1 -1
  38. package/build-module/mobile/global-styles-context/utils.native.js +2 -1
  39. package/build-module/mobile/global-styles-context/utils.native.js.map +1 -1
  40. package/build-module/range-control/index.js +1 -0
  41. package/build-module/range-control/index.js.map +1 -1
  42. package/build-module/tools-panel/context.js +2 -0
  43. package/build-module/tools-panel/context.js.map +1 -1
  44. package/build-module/tools-panel/tools-panel/hook.js +18 -12
  45. package/build-module/tools-panel/tools-panel/hook.js.map +1 -1
  46. package/build-module/tools-panel/tools-panel-item/hook.js +14 -2
  47. package/build-module/tools-panel/tools-panel-item/hook.js.map +1 -1
  48. package/build-module/ui/context/context-system-provider.js +7 -4
  49. package/build-module/ui/context/context-system-provider.js.map +1 -1
  50. package/build-style/style-rtl.css +1 -0
  51. package/build-style/style.css +1 -0
  52. package/build-types/circular-option-picker/index.d.ts +56 -7
  53. package/build-types/circular-option-picker/index.d.ts.map +1 -1
  54. package/build-types/circular-option-picker/stories/index.d.ts +14 -0
  55. package/build-types/circular-option-picker/stories/index.d.ts.map +1 -0
  56. package/build-types/circular-option-picker/types.d.ts +49 -0
  57. package/build-types/circular-option-picker/types.d.ts.map +1 -0
  58. package/build-types/dropdown-menu/index.d.ts.map +1 -1
  59. package/build-types/h-stack/stories/e2e/index.d.ts +9 -0
  60. package/build-types/h-stack/stories/e2e/index.d.ts.map +1 -0
  61. package/build-types/higher-order/with-constrained-tabbing/index.d.ts +10 -1
  62. package/build-types/higher-order/with-constrained-tabbing/index.d.ts.map +1 -1
  63. package/build-types/range-control/index.d.ts.map +1 -1
  64. package/build-types/tab-panel/stories/index.d.ts +1 -0
  65. package/build-types/tab-panel/stories/index.d.ts.map +1 -1
  66. package/build-types/tools-panel/context.d.ts.map +1 -1
  67. package/build-types/tools-panel/test/index.d.ts +2 -0
  68. package/build-types/tools-panel/test/index.d.ts.map +1 -0
  69. package/build-types/tools-panel/tools-panel/hook.d.ts +3 -1
  70. package/build-types/tools-panel/tools-panel/hook.d.ts.map +1 -1
  71. package/build-types/tools-panel/tools-panel-header/hook.d.ts +1 -1
  72. package/build-types/tools-panel/tools-panel-item/component.d.ts +1 -0
  73. package/build-types/tools-panel/tools-panel-item/component.d.ts.map +1 -1
  74. package/build-types/tools-panel/tools-panel-item/hook.d.ts.map +1 -1
  75. package/build-types/tools-panel/types.d.ts +11 -9
  76. package/build-types/tools-panel/types.d.ts.map +1 -1
  77. package/build-types/ui/context/context-system-provider.d.ts.map +1 -1
  78. package/build-types/v-stack/stories/e2e/index.d.ts +9 -0
  79. package/build-types/v-stack/stories/e2e/index.d.ts.map +1 -0
  80. package/package.json +23 -21
  81. package/src/autocomplete/autocompleter-ui.js +72 -34
  82. package/src/autocomplete/index.js +36 -36
  83. package/src/circular-option-picker/README.md +141 -0
  84. package/src/circular-option-picker/{index.js → index.tsx} +74 -14
  85. package/src/circular-option-picker/stories/index.tsx +134 -0
  86. package/src/circular-option-picker/types.ts +69 -0
  87. package/src/color-palette/test/__snapshots__/index.tsx.snap +1 -1
  88. package/src/dropdown-menu/index.js +6 -3
  89. package/src/h-stack/stories/e2e/index.tsx +36 -0
  90. package/src/higher-order/navigate-regions/style.scss +2 -1
  91. package/src/higher-order/with-constrained-tabbing/index.tsx +30 -0
  92. package/src/mobile/global-styles-context/utils.native.js +1 -0
  93. package/src/range-control/index.tsx +5 -1
  94. package/src/tab-panel/stories/index.tsx +41 -0
  95. package/src/tab-panel/test/index.tsx +794 -262
  96. package/src/tools-panel/context.ts +2 -0
  97. package/src/tools-panel/test/{index.js → index.tsx} +171 -61
  98. package/src/tools-panel/tools-panel/hook.ts +30 -11
  99. package/src/tools-panel/tools-panel-item/hook.ts +18 -2
  100. package/src/tools-panel/types.ts +12 -9
  101. package/src/tree-grid/test/__snapshots__/index.tsx.snap +1 -1
  102. package/src/ui/context/context-system-provider.js +7 -4
  103. package/src/v-stack/stories/e2e/index.tsx +36 -0
  104. package/tsconfig.tsbuildinfo +1 -1
  105. package/src/higher-order/with-constrained-tabbing/index.js +0 -22
@@ -1,4 +1,3 @@
1
- // @ts-nocheck
2
1
  /**
3
2
  * External dependencies
4
3
  */
@@ -15,15 +14,21 @@ import { Icon, check } from '@wordpress/icons';
15
14
  import Button from '../button';
16
15
  import Dropdown from '../dropdown';
17
16
  import Tooltip from '../tooltip';
17
+ import type {
18
+ CircularOptionPickerProps,
19
+ DropdownLinkActionProps,
20
+ OptionProps,
21
+ } from './types';
22
+ import type { WordPressComponentProps } from '../ui/context';
23
+ import type { ButtonAsButtonProps } from '../button/types';
18
24
 
19
- function Option( props ) {
20
- const {
21
- className,
22
- isSelected,
23
- selectedIconProps,
24
- tooltipText,
25
- ...additionalProps
26
- } = props;
25
+ export function Option( {
26
+ className,
27
+ isSelected,
28
+ selectedIconProps,
29
+ tooltipText,
30
+ ...additionalProps
31
+ }: OptionProps ) {
27
32
  const optionButton = (
28
33
  <Button
29
34
  isPressed={ isSelected }
@@ -53,8 +58,12 @@ function Option( props ) {
53
58
  );
54
59
  }
55
60
 
56
- function DropdownLinkAction( props ) {
57
- const { buttonProps, className, dropdownProps, linkText } = props;
61
+ export function DropdownLinkAction( {
62
+ buttonProps,
63
+ className,
64
+ dropdownProps,
65
+ linkText,
66
+ }: DropdownLinkActionProps ) {
58
67
  return (
59
68
  <Dropdown
60
69
  className={ classnames(
@@ -77,8 +86,11 @@ function DropdownLinkAction( props ) {
77
86
  );
78
87
  }
79
88
 
80
- function ButtonAction( props ) {
81
- const { className, children, ...additionalProps } = props;
89
+ export function ButtonAction( {
90
+ className,
91
+ children,
92
+ ...additionalProps
93
+ }: WordPressComponentProps< ButtonAsButtonProps, 'button', false > ) {
82
94
  return (
83
95
  <Button
84
96
  className={ classnames(
@@ -93,7 +105,53 @@ function ButtonAction( props ) {
93
105
  );
94
106
  }
95
107
 
96
- export default function CircularOptionPicker( props ) {
108
+ /**
109
+ *`CircularOptionPicker` is a component that displays a set of options as circular buttons.
110
+ *
111
+ * ```jsx
112
+ * import { CircularOptionPicker } from '../circular-option-picker';
113
+ * import { useState } from '@wordpress/element';
114
+ *
115
+ * const Example = () => {
116
+ * const [ currentColor, setCurrentColor ] = useState();
117
+ * const colors = [
118
+ * { color: '#f00', name: 'Red' },
119
+ * { color: '#0f0', name: 'Green' },
120
+ * { color: '#00f', name: 'Blue' },
121
+ * ];
122
+ * const colorOptions = (
123
+ * <>
124
+ * { colors.map( ( { color, name }, index ) => {
125
+ * return (
126
+ * <CircularOptionPicker.Option
127
+ * key={ `${ color }-${ index }` }
128
+ * tooltipText={ name }
129
+ * style={ { backgroundColor: color, color } }
130
+ * isSelected={ index === currentColor }
131
+ * onClick={ () => setCurrentColor( index ) }
132
+ * aria-label={ name }
133
+ * />
134
+ * );
135
+ * } ) }
136
+ * </>
137
+ * );
138
+ * return (
139
+ * <CircularOptionPicker
140
+ * options={ colorOptions }
141
+ * actions={
142
+ * <CircularOptionPicker.ButtonAction
143
+ * onClick={ () => setCurrentColor( undefined ) }
144
+ * >
145
+ * { 'Clear' }
146
+ * </CircularOptionPicker.ButtonAction>
147
+ * }
148
+ * />
149
+ * );
150
+ * };
151
+ * ```
152
+ */
153
+
154
+ function CircularOptionPicker( props: CircularOptionPickerProps ) {
97
155
  const { actions, className, options, children } = props;
98
156
  return (
99
157
  <div
@@ -118,3 +176,5 @@ export default function CircularOptionPicker( props ) {
118
176
  CircularOptionPicker.Option = Option;
119
177
  CircularOptionPicker.ButtonAction = ButtonAction;
120
178
  CircularOptionPicker.DropdownLinkAction = DropdownLinkAction;
179
+
180
+ export default CircularOptionPicker;
@@ -0,0 +1,134 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { ComponentMeta, ComponentStory } from '@storybook/react';
5
+ /**
6
+ * WordPress dependencies
7
+ */
8
+ import { useState, createContext, useContext } from '@wordpress/element';
9
+ /**
10
+ * Internal dependencies
11
+ */
12
+ import {
13
+ default as CircularOptionPicker,
14
+ ButtonAction,
15
+ DropdownLinkAction,
16
+ Option,
17
+ } from '..';
18
+
19
+ const CircularOptionPickerStoryContext = createContext< {
20
+ currentColor?: string;
21
+ setCurrentColor?: ( v: string | undefined ) => void;
22
+ } >( {} );
23
+
24
+ const meta: ComponentMeta< typeof CircularOptionPicker > = {
25
+ title: 'Components/CircularOptionPicker',
26
+ component: CircularOptionPicker,
27
+ subcomponents: {
28
+ 'CircularOptionPicker.Option': Option,
29
+ 'CircularOptionPicker.ButtonAction': ButtonAction,
30
+ 'CircularOptionPicker.DropdownLinkAction': DropdownLinkAction,
31
+ },
32
+ argTypes: {
33
+ actions: { control: { type: null } },
34
+ options: { control: { type: null } },
35
+ children: { control: { type: 'text' } },
36
+ },
37
+ parameters: {
38
+ actions: { argTypesRegex: '^on.*' },
39
+ controls: { expanded: true },
40
+ docs: { source: { state: 'open', excludeDecorators: true } },
41
+ },
42
+ decorators: [
43
+ // Share current color state between main component, `actions` and `options`
44
+ ( Story ) => {
45
+ const [ currentColor, setCurrentColor ] = useState< string >();
46
+
47
+ return (
48
+ <CircularOptionPickerStoryContext.Provider
49
+ value={ {
50
+ currentColor,
51
+ setCurrentColor,
52
+ } }
53
+ >
54
+ <Story />
55
+ </CircularOptionPickerStoryContext.Provider>
56
+ );
57
+ },
58
+ ],
59
+ };
60
+ export default meta;
61
+
62
+ const colors = [
63
+ { color: '#f00', name: 'Red' },
64
+ { color: '#0f0', name: 'Green' },
65
+ { color: '#0af', name: 'Blue' },
66
+ ];
67
+
68
+ const DefaultOptions = () => {
69
+ const { currentColor, setCurrentColor } = useContext(
70
+ CircularOptionPickerStoryContext
71
+ );
72
+
73
+ return (
74
+ <>
75
+ { colors.map( ( { color, name }, index ) => {
76
+ return (
77
+ <CircularOptionPicker.Option
78
+ key={ `${ color }-${ index }` }
79
+ tooltipText={ name }
80
+ style={ { backgroundColor: color, color } }
81
+ isSelected={ color === currentColor }
82
+ onClick={ () => {
83
+ setCurrentColor?.( color );
84
+ } }
85
+ aria-label={ name }
86
+ />
87
+ );
88
+ } ) }
89
+ </>
90
+ );
91
+ };
92
+
93
+ const DefaultActions = () => {
94
+ const { setCurrentColor } = useContext( CircularOptionPickerStoryContext );
95
+
96
+ return (
97
+ <CircularOptionPicker.ButtonAction
98
+ onClick={ () => setCurrentColor?.( undefined ) }
99
+ >
100
+ { 'Clear' }
101
+ </CircularOptionPicker.ButtonAction>
102
+ );
103
+ };
104
+
105
+ const Template: ComponentStory< typeof CircularOptionPicker > = ( props ) => (
106
+ <CircularOptionPicker { ...props } />
107
+ );
108
+
109
+ export const Default = Template.bind( {} );
110
+ Default.args = { options: <DefaultOptions /> };
111
+
112
+ export const WithButtonAction = Template.bind( {} );
113
+ WithButtonAction.args = {
114
+ ...Default.args,
115
+ actions: <DefaultActions />,
116
+ };
117
+ WithButtonAction.storyName = 'With ButtonAction';
118
+
119
+ export const WithDropdownLinkAction = Template.bind( {} );
120
+ WithDropdownLinkAction.args = {
121
+ ...Default.args,
122
+ actions: (
123
+ <CircularOptionPicker.DropdownLinkAction
124
+ dropdownProps={ {
125
+ popoverProps: { position: 'top right' },
126
+ renderContent: () => (
127
+ <div>This is an example of a DropdownLinkAction.</div>
128
+ ),
129
+ } }
130
+ linkText="Learn More"
131
+ ></CircularOptionPicker.DropdownLinkAction>
132
+ ),
133
+ };
134
+ WithDropdownLinkAction.storyName = 'With DropdownLinkAction';
@@ -0,0 +1,69 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { ReactNode } from 'react';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import type { Icon } from '@wordpress/icons';
10
+
11
+ /**
12
+ * Internal dependencies
13
+ */
14
+ import type { ButtonAsButtonProps } from '../button/types';
15
+ import type Dropdown from '../dropdown';
16
+ import type { WordPressComponentProps } from '../ui/context';
17
+
18
+ export type CircularOptionPickerProps = {
19
+ /**
20
+ * A CSS class to apply to the wrapper element.
21
+ */
22
+ className?: string;
23
+ /**
24
+ * The action(s) to be rendered after the options,
25
+ * such as a 'clear' button as seen in `ColorPalette`.
26
+ * Usually a `CircularOptionPicker.ButtonAction` or
27
+ * `CircularOptionPicker.DropdownLinkAction` component.
28
+ */
29
+ actions?: ReactNode;
30
+ /**
31
+ * The options to be rendered, such as color swatches.
32
+ * Usually a `CircularOptionPicker.Option` component.
33
+ */
34
+ options: ReactNode;
35
+ /**
36
+ * The child elements.
37
+ */
38
+ children?: ReactNode;
39
+ };
40
+
41
+ export type DropdownLinkActionProps = {
42
+ buttonProps?: Omit<
43
+ WordPressComponentProps< ButtonAsButtonProps, 'button', false >,
44
+ 'children'
45
+ >;
46
+ linkText: string;
47
+ dropdownProps: Omit<
48
+ React.ComponentProps< typeof Dropdown >,
49
+ 'className' | 'renderToggle'
50
+ >;
51
+ className?: string;
52
+ };
53
+
54
+ export type OptionProps = Omit<
55
+ WordPressComponentProps< ButtonAsButtonProps, 'button', false >,
56
+ 'isPressed' | 'className'
57
+ > & {
58
+ className?: string;
59
+ tooltipText?: string;
60
+ isSelected: boolean;
61
+ // `icon` is explicitly defined as 'check' by CircleOptionPicker.Option
62
+ // and is not intended to be overridden.
63
+ // `size` relies on the `Icon` component's default size of `24` to fit
64
+ // `CircularOptionPicker`'s design, and should not be explicitly set.
65
+ selectedIconProps?: Omit<
66
+ React.ComponentProps< typeof Icon >,
67
+ 'icon' | 'size'
68
+ >;
69
+ };
@@ -179,7 +179,7 @@ exports[`ColorPalette should render a dynamic toolbar of colors 1`] = `
179
179
  <button
180
180
  aria-expanded="false"
181
181
  aria-haspopup="true"
182
- aria-label="Custom color picker. The currently selected color is called \\"red\\" and has a value of \\"f00\\"."
182
+ aria-label="Custom color picker. The currently selected color is called "red" and has a value of "f00"."
183
183
  class="components-flex components-color-palette__custom-color emotion-2 emotion-1"
184
184
  data-wp-c16t="true"
185
185
  data-wp-component="Flex"
@@ -91,6 +91,9 @@ function DropdownMenu( dropdownMenuProps ) {
91
91
  onToggle();
92
92
  }
93
93
  };
94
+ const { as: Toggle = Button, ...restToggleProps } =
95
+ toggleProps ?? {};
96
+
94
97
  const mergedToggleProps = mergeProps(
95
98
  {
96
99
  className: classnames(
@@ -100,11 +103,11 @@ function DropdownMenu( dropdownMenuProps ) {
100
103
  }
101
104
  ),
102
105
  },
103
- toggleProps
106
+ restToggleProps
104
107
  );
105
108
 
106
109
  return (
107
- <Button
110
+ <Toggle
108
111
  { ...mergedToggleProps }
109
112
  icon={ icon }
110
113
  onClick={ ( event ) => {
@@ -126,7 +129,7 @@ function DropdownMenu( dropdownMenuProps ) {
126
129
  showTooltip={ toggleProps?.showTooltip ?? true }
127
130
  >
128
131
  { mergedToggleProps.children }
129
- </Button>
132
+ </Toggle>
130
133
  );
131
134
  } }
132
135
  renderContent={ ( props ) => {
@@ -0,0 +1,36 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import type { ComponentStory, ComponentMeta } from '@storybook/react';
5
+
6
+ /**
7
+ * Internal dependencies
8
+ */
9
+ import { View } from '../../../view';
10
+ import { HStack } from '../..';
11
+
12
+ const meta: ComponentMeta< typeof HStack > = {
13
+ component: HStack,
14
+ title: 'Components (Experimental)/HStack',
15
+ };
16
+ export default meta;
17
+
18
+ const Template: ComponentStory< typeof HStack > = ( props ) => {
19
+ return (
20
+ <HStack
21
+ style={ { background: '#eee', minHeight: '3rem' } }
22
+ { ...props }
23
+ >
24
+ { [ 'One', 'Two', 'Three', 'Four', 'Five' ].map( ( text ) => (
25
+ <View key={ text } style={ { background: '#b9f9ff' } }>
26
+ { text }
27
+ </View>
28
+ ) ) }
29
+ </HStack>
30
+ );
31
+ };
32
+
33
+ export const Default: ComponentStory< typeof HStack > = Template.bind( {} );
34
+ Default.args = {
35
+ spacing: 3,
36
+ };
@@ -24,13 +24,14 @@
24
24
  // visible. For the future, it's important to take into consideration that
25
25
  // the navigable regions should always have a computed size. For now, we can
26
26
  // fix some edge cases but these CSS rules should be later removed in favor of
27
- // a more abstracted approach to make the navigabel regions focus style work
27
+ // a more abstracted approach to make the navigable regions focus style work
28
28
  // regardles of the CSS used on other components.
29
29
 
30
30
  // Header top bar when Distraction free mode is on.
31
31
  &.is-distraction-free .interface-interface-skeleton__header .edit-post-header,
32
32
  .interface-interface-skeleton__sidebar .edit-post-layout__toggle-sidebar-panel,
33
33
  .interface-interface-skeleton__actions .edit-post-layout__toggle-publish-panel,
34
+ .interface-interface-skeleton__actions .edit-post-layout__toggle-entities-saved-states-panel,
34
35
  .editor-post-publish-panel {
35
36
  outline: 4px solid $components-color-accent;
36
37
  outline-offset: -4px;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import {
5
+ createHigherOrderComponent,
6
+ useConstrainedTabbing,
7
+ } from '@wordpress/compose';
8
+
9
+ /**
10
+ * `withConstrainedTabbing` is a React [higher-order component](https://facebook.github.io/react/docs/higher-order-components.html)
11
+ * adding the ability to constrain keyboard navigation with the Tab key within a component.
12
+ * For accessibility reasons, some UI components need to constrain Tab navigation, for example
13
+ * modal dialogs or similar UI. Use of this component is recommended only in cases where a way to
14
+ * navigate away from the wrapped component is implemented by other means, usually by pressing
15
+ * the Escape key or using a specific UI control, e.g. a "Close" button.
16
+ */
17
+ const withConstrainedTabbing = createHigherOrderComponent(
18
+ ( WrappedComponent ) =>
19
+ function ComponentWithConstrainedTabbing( props ) {
20
+ const ref = useConstrainedTabbing();
21
+ return (
22
+ <div ref={ ref } tabIndex={ -1 }>
23
+ <WrappedComponent { ...props } />
24
+ </div>
25
+ );
26
+ },
27
+ 'withConstrainedTabbing'
28
+ );
29
+
30
+ export default withConstrainedTabbing;
@@ -416,6 +416,7 @@ export function getGlobalStyles( rawStyles, rawFeatures ) {
416
416
  fontSizes,
417
417
  customLineHeight: features?.custom?.[ 'line-height' ],
418
418
  },
419
+ spacing: features?.spacing,
419
420
  },
420
421
  __experimentalGlobalStylesBaseStyles: globalStyles,
421
422
  };
@@ -269,7 +269,11 @@ function UnforwardedRangeControl< IconProps = unknown >(
269
269
  style={ { width: fillValueOffset } }
270
270
  trackColor={ trackColor }
271
271
  />
272
- <ThumbWrapper style={ offsetStyle } disabled={ disabled }>
272
+ <ThumbWrapper
273
+ className="components-range-control__thumb-wrapper"
274
+ style={ offsetStyle }
275
+ disabled={ disabled }
276
+ >
273
277
  <Thumb
274
278
  aria-hidden={ true }
275
279
  isFocused={ isThumbFocused }
@@ -3,16 +3,25 @@
3
3
  */
4
4
  import type { ComponentMeta, ComponentStory } from '@storybook/react';
5
5
 
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { link, more, wordpress } from '@wordpress/icons';
10
+
6
11
  /**
7
12
  * Internal dependencies
8
13
  */
9
14
  import TabPanel from '..';
15
+ import Popover from '../../popover';
16
+ import { Provider as SlotFillProvider } from '../../slot-fill';
10
17
 
11
18
  const meta: ComponentMeta< typeof TabPanel > = {
12
19
  title: 'Components/TabPanel',
13
20
  component: TabPanel,
14
21
  parameters: {
22
+ actions: { argTypesRegex: '^on.*' },
15
23
  controls: { expanded: true },
24
+ docs: { source: { state: 'open' } },
16
25
  },
17
26
  };
18
27
  export default meta;
@@ -55,3 +64,35 @@ DisabledTab.args = {
55
64
  },
56
65
  ],
57
66
  };
67
+
68
+ const SlotFillTemplate: ComponentStory< typeof TabPanel > = ( props ) => {
69
+ return (
70
+ <SlotFillProvider>
71
+ <TabPanel { ...props } />
72
+ { /* @ts-expect-error The 'Slot' component hasn't been typed yet. */ }
73
+ <Popover.Slot />
74
+ </SlotFillProvider>
75
+ );
76
+ };
77
+
78
+ export const WithTabIconsAndTooltips = SlotFillTemplate.bind( {} );
79
+ WithTabIconsAndTooltips.args = {
80
+ children: ( tab ) => <p>Selected tab: { tab.title }</p>,
81
+ tabs: [
82
+ {
83
+ name: 'tab1',
84
+ title: 'Tab 1',
85
+ icon: wordpress,
86
+ },
87
+ {
88
+ name: 'tab2',
89
+ title: 'Tab 2',
90
+ icon: link,
91
+ },
92
+ {
93
+ name: 'tab3',
94
+ title: 'Tab 3',
95
+ icon: more,
96
+ },
97
+ ],
98
+ };