diff --git a/docs/components/dialog.md b/docs/components/dialog.md index 2e40d184..ada3d12c 100644 --- a/docs/components/dialog.md +++ b/docs/components/dialog.md @@ -123,7 +123,7 @@ By default, the dialog's panel will gain focus when opened. To set focus on a di dialog.addEventListener('sl-initial-focus', event => { event.preventDefault(); - input.setFocus({ preventScroll: true }); + input.focus({ preventScroll: true }); }); </script> ``` diff --git a/docs/components/drawer.md b/docs/components/drawer.md index 68fe92dd..7f83e03e 100644 --- a/docs/components/drawer.md +++ b/docs/components/drawer.md @@ -211,7 +211,7 @@ By default, the drawer's panel will gain focus when opened. To set focus on a di drawer.addEventListener('sl-initial-focus', event => { event.preventDefault(); - input.setFocus({ preventScroll: true }); + input.focus({ preventScroll: true }); }); </script> ``` diff --git a/docs/getting-started/usage.md b/docs/getting-started/usage.md index 67bbec95..1a6735ce 100644 --- a/docs/getting-started/usage.md +++ b/docs/getting-started/usage.md @@ -50,14 +50,14 @@ Refer to a component's documentation for a complete list of its custom events. ### Methods -Some components have methods you can call to trigger various behaviors. For example, you can set focus on a Shoelace input using the `setFocus()` method. +Some components have methods you can call to trigger various behaviors. For example, you can set focus on a Shoelace input using the `focus()` method. ```html <sl-input></sl-input> <script> const input = document.querySelector('sl-input'); - input.setFocus(); + input.focus(); </script> ``` @@ -102,7 +102,7 @@ Custom elements cannot have self-closing tags. Similar to `<script>` and `<texta You might expect similarly named elements to share the same API as native HTML elements. This is not always the case. Shoelace components **are not** designed to be one-to-one replacements for their HTML counterparts. -For example, `<button>` and `<sl-button>` both have a `type` attribute, but it does different things (the former controls whether the button submits a form and the latter controls the button's appearance). Similarly, you can't call `focus()` on a Shoelace input — you need to use the component's `setFocus()` method instead. There are technical reasons for some of these design decisions that are outside the scope of this page. +For example, `<button>` and `<sl-button>` both have a `type` attribute, but it does different things (the former controls whether the button submits a form and the latter controls the button's appearance). Similarly, you can't call `focus()` on a Shoelace input — you need to use the component's `focus()` method instead. There are technical reasons for some of these design decisions that are outside the scope of this page. ?> **Don't make assumptions about a component's API!** To prevent unexpected behaviors, please take the time to review the documentation and make sure you understand what each property, method, and event is intended to do. @@ -156,20 +156,20 @@ Now you can "import" Shoelace components as React components! Remember to [insta ```js import wrapCustomElement from '@shoelace-style/react-wrapper'; -const ShoelaceButton = wrapCustomElement('sl-button'); +const SlButton = wrapCustomElement('sl-button'); -return <ShoelaceButton type="primary">Click me</ShoelaceButton>; +return <SlButton type="primary">Click me</SlButton>; ``` A reference ("ref") to the underlying custom element is exposed through the `element` property so you can access it directly. This is useful for calling methods. ```jsx -<ShoelaceButton +<SlButton ref={el => this.button = el} - onClick={() => this.button.element.current.removeFocus()} + onClick={() => this.button.element.current.blur()} > Click me -</ShoelaceButton> +</SlButton> ``` ## Vue diff --git a/docs/resources/changelog.md b/docs/resources/changelog.md index 5ff823cf..f1f5a49c 100644 --- a/docs/resources/changelog.md +++ b/docs/resources/changelog.md @@ -8,9 +8,12 @@ _During the beta period, these restrictions may be relaxed in the event of a mis ## Next +- 🚨 BREAKING: renamed `setFocus()` to `focus()` in button, checkbox, input, menu item, radio, range, rating, select, switch, and tab +- 🚨 BREAKING: renamed `removeFocus()` to `blur()` in button, checkbox, input, menu item, radio, range, rating, select, switch, and tab - Fixed a bug where toggling `open` on `sl-drawer` would skip the transition - Fixed a bug where `sl-color-picker` could be opened when disabled - Fixed a bug in `sl-color-picker` that caused erratic slider behaviors [#388](https://github.com/shoelace-style/shoelace/issues/388) [#389](https://github.com/shoelace-style/shoelace/issues/389) +- Added `click()` method to `sl-button` - Renamed `components.json` to `metadata.json` - Updated to the prerelease versions of LitElement and lit-html - Updated to Bootstrap Icons 1.4.1 diff --git a/src/components/button/button.ts b/src/components/button/button.ts index 94f158ef..a16ffd42 100644 --- a/src/components/button/button.ts +++ b/src/components/button/button.ts @@ -84,13 +84,19 @@ export default class SlButton extends LitElement { this.handleSlotChange(); } - /** setFocus - Sets focus on the button. */ - setFocus(options?: FocusOptions) { + /** Simulates a click on the button. */ + click() { + this.button.focus(); + this.button.click(); + } + + /** Sets focus on the button. */ + focus(options?: FocusOptions) { this.button.focus(options); } - /** removeFocus - Removes focus from the button. */ - removeFocus() { + /** Removes focus from the button. */ + blur() { this.button.blur(); } diff --git a/src/components/checkbox/checkbox.ts b/src/components/checkbox/checkbox.ts index 921316c6..70cc0d04 100644 --- a/src/components/checkbox/checkbox.ts +++ b/src/components/checkbox/checkbox.ts @@ -64,12 +64,12 @@ export default class SlCheckbox extends LitElement { } /** Sets focus on the checkbox. */ - setFocus(options?: FocusOptions) { + focus(options?: FocusOptions) { this.input.focus(options); } /** Removes focus from the checkbox. */ - removeFocus() { + blur() { this.input.blur(); } diff --git a/src/components/dropdown/dropdown.ts b/src/components/dropdown/dropdown.ts index 19938ae3..02e04e28 100644 --- a/src/components/dropdown/dropdown.ts +++ b/src/components/dropdown/dropdown.ts @@ -127,12 +127,8 @@ export default class SlDropdown extends LitElement { focusOnTrigger() { const slot = this.trigger.querySelector('slot')!; const trigger = slot.assignedElements({ flatten: true })[0] as any; - if (trigger) { - if (typeof trigger.setFocus === 'function') { - trigger.setFocus(); - } else if (typeof trigger.focus === 'function') { - trigger.focus(); - } + if (trigger && typeof trigger.focus === 'function') { + trigger.focus(); } } @@ -254,12 +250,12 @@ export default class SlDropdown extends LitElement { // Focus on a menu item if (event.key === 'ArrowDown' && firstMenuItem) { - firstMenuItem.setFocus(); + firstMenuItem.focus(); return; } if (event.key === 'ArrowUp' && lastMenuItem) { - lastMenuItem.setFocus(); + lastMenuItem.focus(); return; } } diff --git a/src/components/input/input.ts b/src/components/input/input.ts index 92cc0ca6..4b85d67d 100644 --- a/src/components/input/input.ts +++ b/src/components/input/input.ts @@ -161,12 +161,12 @@ export default class SlInput extends LitElement { } /** Sets focus on the input. */ - setFocus(options?: FocusOptions) { + focus(options?: FocusOptions) { this.input.focus(options); } /** Removes focus from the input. */ - removeFocus() { + blur() { this.input.blur(); } diff --git a/src/components/menu-item/menu-item.ts b/src/components/menu-item/menu-item.ts index fbec1c51..0d356a0f 100644 --- a/src/components/menu-item/menu-item.ts +++ b/src/components/menu-item/menu-item.ts @@ -38,12 +38,12 @@ export default class SlMenuItem extends LitElement { @property({ type: Boolean, reflect: true }) disabled = false; /** Sets focus on the button. */ - setFocus(options?: FocusOptions) { + focus(options?: FocusOptions) { this.menuItem.focus(options); } /** Removes focus from the button. */ - removeFocus() { + blur() { this.menuItem.blur(); } @@ -56,11 +56,11 @@ export default class SlMenuItem extends LitElement { } handleMouseEnter() { - this.setFocus(); + this.focus(); } handleMouseLeave() { - this.removeFocus(); + this.blur(); } render() { diff --git a/src/components/menu/menu.ts b/src/components/menu/menu.ts index 6ed35e06..c46e621e 100644 --- a/src/components/menu/menu.ts +++ b/src/components/menu/menu.ts @@ -40,7 +40,7 @@ export default class SlMenu extends LitElement { const slot = item.shadowRoot!.querySelector('slot:not([name])') as HTMLSlotElement; const label = getTextContent(slot).toLowerCase().trim(); if (label.substring(0, this.typeToSelectString.length) === this.typeToSelectString) { - item.setFocus(); + item.focus(); break; } } @@ -58,7 +58,7 @@ export default class SlMenu extends LitElement { } setActiveItem(item: SlMenuItem) { - item.setFocus(); + item.focus(); } handleClick(event: MouseEvent) { diff --git a/src/components/radio/radio.ts b/src/components/radio/radio.ts index aae5d816..4d7fd22e 100644 --- a/src/components/radio/radio.ts +++ b/src/components/radio/radio.ts @@ -56,12 +56,12 @@ export default class SlRadio extends LitElement { @event('sl-focus') slFocus: EventEmitter<void>; /** Sets focus on the radio. */ - setFocus(options?: FocusOptions) { + focus(options?: FocusOptions) { this.input.focus(options); } /** Removes focus from the radio. */ - removeFocus() { + blur() { this.input.blur(); } @@ -120,7 +120,7 @@ export default class SlRadio extends LitElement { if (index > radios.length - 1) index = 0; this.getAllRadios().map(radio => (radio.checked = false)); - radios[index].setFocus(); + radios[index].focus(); radios[index].checked = true; event.preventDefault(); diff --git a/src/components/range/range.ts b/src/components/range/range.ts index d9b2597c..790e66c7 100644 --- a/src/components/range/range.ts +++ b/src/components/range/range.ts @@ -105,12 +105,12 @@ export default class SlRange extends LitElement { } /** Sets focus on the input. */ - setFocus(options?: FocusOptions) { + focus(options?: FocusOptions) { this.input.focus(options); } /** Removes focus from the input. */ - removeFocus() { + blur() { this.input.blur(); } @@ -149,7 +149,7 @@ export default class SlRange extends LitElement { } handleTouchStart() { - this.setFocus(); + this.focus(); } syncTooltip() { diff --git a/src/components/rating/rating.ts b/src/components/rating/rating.ts index 3836cb39..c5902037 100644 --- a/src/components/rating/rating.ts +++ b/src/components/rating/rating.ts @@ -48,12 +48,12 @@ export default class SlRating extends LitElement { @event('sl-change') slChange: EventEmitter<void>; /** Sets focus on the rating. */ - setFocus(options?: FocusOptions) { + focus(options?: FocusOptions) { this.rating.focus(options); } /** Removes focus from the rating. */ - removeFocus() { + blur() { this.rating.blur(); } diff --git a/src/components/select/select.ts b/src/components/select/select.ts index 08ea186c..9f56f415 100644 --- a/src/components/select/select.ts +++ b/src/components/select/select.ts @@ -210,12 +210,12 @@ export default class SlSelect extends LitElement { // Focus on a menu item if (event.key === 'ArrowDown' && firstItem) { - firstItem.setFocus(); + firstItem.focus(); return; } if (event.key === 'ArrowUp' && lastItem) { - lastItem.setFocus(); + lastItem.focus(); return; } } diff --git a/src/components/switch/switch.ts b/src/components/switch/switch.ts index 8a041abf..4618e6f4 100644 --- a/src/components/switch/switch.ts +++ b/src/components/switch/switch.ts @@ -56,12 +56,12 @@ export default class SlSwitch extends LitElement { @event('sl-focus') slFocus: EventEmitter<void>; /** Sets focus on the switch. */ - setFocus(options?: FocusOptions) { + focus(options?: FocusOptions) { this.input.focus(options); } /** Removes focus from the switch. */ - removeFocus() { + blur() { this.input.blur(); } diff --git a/src/components/tab-group/tab-group.ts b/src/components/tab-group/tab-group.ts index db3855ce..3349e3ef 100644 --- a/src/components/tab-group/tab-group.ts +++ b/src/components/tab-group/tab-group.ts @@ -175,7 +175,7 @@ export default class SlTabGroup extends LitElement { index = Math.min(this.tabs.length - 1, index + 1); } - this.tabs[index].setFocus({ preventScroll: true }); + this.tabs[index].focus({ preventScroll: true }); if (['top', 'bottom'].includes(this.placement)) { scrollIntoView(this.tabs[index], this.nav, 'horizontal'); diff --git a/src/components/tab/tab.ts b/src/components/tab/tab.ts index 8b4e63fa..989a6e25 100644 --- a/src/components/tab/tab.ts +++ b/src/components/tab/tab.ts @@ -41,12 +41,12 @@ export default class SlTab extends LitElement { @event('sl-close') slClose: EventEmitter<void>; /** Sets focus to the tab. */ - setFocus(options?: FocusOptions) { + focus(options?: FocusOptions) { this.tab.focus(options); } /** Removes focus from the tab. */ - removeFocus() { + blur() { this.tab.blur(); } diff --git a/src/components/textarea/textarea.ts b/src/components/textarea/textarea.ts index 2d4001d1..003a7376 100644 --- a/src/components/textarea/textarea.ts +++ b/src/components/textarea/textarea.ts @@ -148,12 +148,12 @@ export default class SlTextarea extends LitElement { } /** Sets focus on the textarea. */ - setFocus(options?: FocusOptions) { + focus(options?: FocusOptions) { this.input.focus(options); } /** Removes focus from the textarea. */ - removeFocus() { + blur() { this.input.blur(); }