mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 04:09:12 +00:00
Merge pull request #19 from shoelace-style/backport-menu-item-loading
backport `<sl-menu-item loading>`
This commit is contained in:
@@ -60,35 +60,6 @@ const App = () => (
|
||||
|
||||
## Examples
|
||||
|
||||
### Disabled
|
||||
|
||||
Add the `disabled` attribute to disable the menu item so it cannot be selected.
|
||||
|
||||
```html:preview
|
||||
<wa-menu style="max-width: 200px;">
|
||||
<wa-menu-item>Option 1</wa-menu-item>
|
||||
<wa-menu-item disabled>Option 2</wa-menu-item>
|
||||
<wa-menu-item>Option 3</wa-menu-item>
|
||||
</wa-menu>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
|
||||
```jsx:react
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaMenu style={{ maxWidth: '200px' }}>
|
||||
<WaMenuItem>Option 1</WaMenuItem>
|
||||
<WaMenuItem disabled>Option 2</WaMenuItem>
|
||||
<WaMenuItem>Option 3</WaMenuItem>
|
||||
</WaMenu>
|
||||
);
|
||||
```
|
||||
|
||||
{% endraw %}
|
||||
|
||||
### Prefix & Suffix
|
||||
|
||||
Add content to the start and end of menu items using the `prefix` and `suffix` slots.
|
||||
@@ -151,6 +122,64 @@ const App = () => (
|
||||
|
||||
{% endraw %}
|
||||
|
||||
### Disabled
|
||||
|
||||
Add the `disabled` attribute to disable the menu item so it cannot be selected.
|
||||
|
||||
```html:preview
|
||||
<wa-menu style="max-width: 200px;">
|
||||
<wa-menu-item>Option 1</wa-menu-item>
|
||||
<wa-menu-item disabled>Option 2</wa-menu-item>
|
||||
<wa-menu-item>Option 3</wa-menu-item>
|
||||
</wa-menu>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
|
||||
```jsx:react
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaMenu style={{ maxWidth: '200px' }}>
|
||||
<WaMenuItem>Option 1</WaMenuItem>
|
||||
<WaMenuItem disabled>Option 2</WaMenuItem>
|
||||
<WaMenuItem>Option 3</WaMenuItem>
|
||||
</WaMenu>
|
||||
);
|
||||
```
|
||||
|
||||
{% endraw %}
|
||||
|
||||
### Loading
|
||||
|
||||
Use the `loading` attribute to indicate that a menu item is busy. Like a disabled menu item, clicks will be suppressed until the loading state is removed.
|
||||
|
||||
```html:preview
|
||||
<wa-menu style="max-width: 200px;">
|
||||
<wa-menu-item>Option 1</wa-menu-item>
|
||||
<wa-menu-item loading>Option 2</wa-menu-item>
|
||||
<wa-menu-item>Option 3</wa-menu-item>
|
||||
</wa-menu>
|
||||
```
|
||||
|
||||
{% raw %}
|
||||
|
||||
```jsx:react
|
||||
import WaMenu from '@shoelace-style/shoelace/dist/react/menu';
|
||||
import WaMenuItem from '@shoelace-style/shoelace/dist/react/menu-item';
|
||||
|
||||
const App = () => (
|
||||
<WaMenu style={{ maxWidth: '200px' }}>
|
||||
<WaMenuItem>Option 1</WaMenuItem>
|
||||
<WaMenuItem loading>Option 2</WaMenuItem>
|
||||
<WaMenuItem>Option 3</WaMenuItem>
|
||||
</WaMenu>
|
||||
);
|
||||
```
|
||||
|
||||
{% endraw %}
|
||||
|
||||
### Checkbox Menu Items
|
||||
|
||||
Set the `type` attribute to `checkbox` to create a menu item that will toggle on and off when selected. You can use the `checked` attribute to set the initial state.
|
||||
|
||||
@@ -26,6 +26,7 @@ New versions of Web Awesome are released as-needed and generally occur when a cr
|
||||
|
||||
## Next
|
||||
|
||||
- Added the `loading` attribute and the `spinner` and `spinner__base` part to `<sl-menu-item>` [#1700]
|
||||
- Added the `hover-bridge` feature to `<sl-popup>` to support better tooltip accessibility [#1734]
|
||||
- Added the `loading` attribute and the `spinner` and `spinner__base` part to `<sl-menu-item>` [#1700]
|
||||
- Fixed files that did not have `.js` extensions. [#1770]
|
||||
|
||||
@@ -8,6 +8,7 @@ import { watch } from '../../internal/watch.js';
|
||||
import styles from './menu-item.styles.js';
|
||||
import WaIcon from '../icon/icon.component.js';
|
||||
import WaPopup from '../popup/popup.component.js';
|
||||
import WaSpinner from '../spinner/spinner.component.js';
|
||||
import WebAwesomeElement from '../../internal/webawesome-element.js';
|
||||
import type { CSSResultGroup } from 'lit';
|
||||
|
||||
@@ -30,6 +31,8 @@ import type { CSSResultGroup } from 'lit';
|
||||
* @csspart prefix - The prefix container.
|
||||
* @csspart label - The menu item label.
|
||||
* @csspart suffix - The suffix container.
|
||||
* @csspart spinner - The spinner that shows when the menu item is in the loading state.
|
||||
* @csspart spinner__base - The spinner's base part.
|
||||
* @csspart submenu-icon - The submenu icon, visible only when the menu item has a submenu (not yet implemented).
|
||||
*
|
||||
* @cssproperty [--submenu-offset=-2px] - The distance submenus shift to overlap the parent menu.
|
||||
@@ -38,7 +41,8 @@ export default class WaMenuItem extends WebAwesomeElement {
|
||||
static styles: CSSResultGroup = styles;
|
||||
static dependencies = {
|
||||
'wa-icon': WaIcon,
|
||||
'wa-popup': WaPopup
|
||||
'wa-popup': WaPopup,
|
||||
'wa-spinner': WaSpinner
|
||||
};
|
||||
|
||||
private cachedTextLabel: string;
|
||||
@@ -55,6 +59,9 @@ export default class WaMenuItem extends WebAwesomeElement {
|
||||
/** A unique value to store in the menu item. This can be used as a way to identify menu items when selected. */
|
||||
@property() value = '';
|
||||
|
||||
/** Draws the menu item in a loading state. */
|
||||
@property({ type: Boolean, reflect: true }) loading = false;
|
||||
|
||||
/** Draws the menu item in a disabled state, preventing selection. */
|
||||
@property({ type: Boolean, reflect: true }) disabled = false;
|
||||
|
||||
@@ -158,6 +165,7 @@ export default class WaMenuItem extends WebAwesomeElement {
|
||||
'menu-item--rtl': isRtl,
|
||||
'menu-item--checked': this.checked,
|
||||
'menu-item--disabled': this.disabled,
|
||||
'menu-item--loading': this.loading,
|
||||
'menu-item--has-submenu': this.isSubmenu(),
|
||||
'menu-item--submenu-expanded': isSubmenuExpanded
|
||||
})}
|
||||
@@ -183,7 +191,7 @@ export default class WaMenuItem extends WebAwesomeElement {
|
||||
></wa-icon>
|
||||
</span>
|
||||
|
||||
${this.submenuController.renderSubmenu()}
|
||||
${this.submenuController.renderSubmenu()} ${this.loading ? html`<sl-spinner part="spinner"></sl-spinner>` : ''}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,25 @@ export default css`
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.menu-item.menu-item--loading {
|
||||
outline: none;
|
||||
cursor: wait;
|
||||
}
|
||||
|
||||
.menu-item.menu-item--loading *:not(wa-spinner) {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.menu-item--loading wa-spinner {
|
||||
--indicator-color: currentColor;
|
||||
--track-width: 1px;
|
||||
position: absolute;
|
||||
font-size: 0.75em;
|
||||
top: calc(50% - 0.5em);
|
||||
left: 0.65rem;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.menu-item .menu-item__label {
|
||||
flex: 1 1 auto;
|
||||
display: inline-block;
|
||||
|
||||
@@ -40,6 +40,7 @@ describe('<wa-menu-item>', () => {
|
||||
|
||||
expect(el.value).to.equal('');
|
||||
expect(el.disabled).to.be.false;
|
||||
expect(el.loading).to.equal(false);
|
||||
expect(el.getAttribute('aria-disabled')).to.equal('false');
|
||||
});
|
||||
|
||||
@@ -48,6 +49,13 @@ describe('<wa-menu-item>', () => {
|
||||
expect(el.getAttribute('aria-disabled')).to.equal('true');
|
||||
});
|
||||
|
||||
describe('when loading', () => {
|
||||
it('should have a spinner present', async () => {
|
||||
const el = await fixture<WaMenuItem>(html` <wa-menu-item loading>Menu Item Label</wa-menu-item> `);
|
||||
expect(el.shadowRoot!.querySelector('wa-spinner')).to.exist;
|
||||
});
|
||||
});
|
||||
|
||||
it('should return a text label when calling getTextLabel()', async () => {
|
||||
const el = await fixture<WaMenuItem>(html` <wa-menu-item>Test</wa-menu-item> `);
|
||||
expect(el.getTextLabel()).to.equal('Test');
|
||||
|
||||
Reference in New Issue
Block a user