From f64f144b4ba727756da96a64a74ec78c03328b91 Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Thu, 10 Nov 2022 12:27:03 -0500 Subject: [PATCH] fixes #985 --- docs/components/checkbox.md | 8 ++++ docs/resources/changelog.md | 2 + docs/resources/contributing.md | 10 +++++ src/components/button/button.styles.ts | 8 +--- src/components/button/button.ts | 21 ++------- src/components/checkbox/checkbox.styles.ts | 5 --- src/components/checkbox/checkbox.ts | 34 +++------------ .../icon-button/icon-button.test.ts | 6 +-- src/components/icon/library.system.ts | 43 +++++++++++++++++-- .../image-comparer/image-comparer.styles.ts | 2 +- .../image-comparer/image-comparer.ts | 9 +--- src/components/menu-item/menu-item.ts | 4 +- src/components/radio/radio.ts | 13 +++--- 13 files changed, 84 insertions(+), 81 deletions(-) diff --git a/docs/components/checkbox.md b/docs/components/checkbox.md index 87bfe8e4..54cfbc7d 100644 --- a/docs/components/checkbox.md +++ b/docs/components/checkbox.md @@ -72,14 +72,17 @@ Use the `setCustomValidity()` method to set a custom validation message. This wi const form = document.querySelector('.custom-validity'); const checkbox = form.querySelector('sl-checkbox'); const errorMessage = `Don't forget to check me!`; + // Set initial validity as soon as the element is defined customElements.whenDefined('sl-checkbox').then(() => { checkbox.setCustomValidity(errorMessage); }); + // Update validity on change checkbox.addEventListener('sl-change', () => { checkbox.setCustomValidity(checkbox.checked ? '' : errorMessage); }); + // Handle submit form.addEventListener('submit', event => { event.preventDefault(); @@ -91,19 +94,24 @@ Use the `setCustomValidity()` method to set a custom validation message. This wi ```jsx react import { useEffect, useRef } from 'react'; import { SlButton, SlCheckbox } from '@shoelace-style/shoelace/dist/react'; + const App = () => { const checkbox = useRef(null); const errorMessage = `Don't forget to check me!`; + function handleChange() { checkbox.current.setCustomValidity(checkbox.current.checked ? '' : errorMessage); } + function handleSubmit(event) { event.preventDefault(); alert('All fields are valid!'); } + useEffect(() => { checkbox.current.setCustomValidity(errorMessage); }, []); + return (
diff --git a/docs/resources/changelog.md b/docs/resources/changelog.md index 61a7f76e..2cae5751 100644 --- a/docs/resources/changelog.md +++ b/docs/resources/changelog.md @@ -19,6 +19,8 @@ _During the beta period, these restrictions may be relaxed in the event of a mis - Added `--indicator-transition-duration` custom property to `` [#986](https://github.com/shoelace-style/shoelace/issues/986) - Added the ability to cancel `sl-show` and `sl-hide` events in `` [#993](https://github.com/shoelace-style/shoelace/issues/993) - Added `focus()` and `blur()` methods to `` +- Added the `handle-icon` part to `` +- Added `caret`, `check`, `grip-vertical`, `indeterminate`, and `radio` icons to the system library and removed `check-lg` [#985](https://github.com/shoelace-style/shoelace/issues/985) - Fixed a bug in `` that prevented the border radius to apply correctly to the header [#934](https://github.com/shoelace-style/shoelace/pull/934) - Fixed a bug in `` where the inner border disappeared on focus [#980](https://github.com/shoelace-style/shoelace/pull/980) - Fixed a bug that caused prefix/suffix animations in `` to wobble [#996](https://github.com/shoelace-style/shoelace/issues/996) diff --git a/docs/resources/contributing.md b/docs/resources/contributing.md index 45135442..9aca2bfb 100644 --- a/docs/resources/contributing.md +++ b/docs/resources/contributing.md @@ -302,3 +302,13 @@ Form controls should support submission and validation through the following con - All form controls must have an `invalid` property that reflects their validity - All form controls should mirror their native validation attributes such as `required`, `pattern`, `minlength`, `maxlength`, etc. when possible - All form controls must be tested to work with the standard `` element + +### System Icons + +Avoid inlining SVG icons inside of templates. If a component requires an icon, make sure `` is a dependency of the component and use the [system library](/components/icon#customizing-the-system-library): + +```html + +``` + +This will render the icons instantly whereas the default library will fetch them from a remote source. If an icon isn't available in the system library, you will need to add it to `library.system.ts`. Using the system library ensures that all icons load instantly and are customizable by users who wish to provide a custom resolver for the system library. diff --git a/src/components/button/button.styles.ts b/src/components/button/button.styles.ts index 344d88b7..fb9169ce 100644 --- a/src/components/button/button.styles.ts +++ b/src/components/button/button.styles.ts @@ -408,13 +408,7 @@ export default css` } .button--caret .button__caret { - display: flex; - align-items: center; - } - - .button--caret .button__caret svg { - width: 1em; - height: 1em; + height: auto; } /* diff --git a/src/components/button/button.ts b/src/components/button/button.ts index e4d939da..c9ffa977 100644 --- a/src/components/button/button.ts +++ b/src/components/button/button.ts @@ -6,6 +6,7 @@ import { FormSubmitController } from '../../internal/form'; import ShoelaceElement from '../../internal/shoelace-element'; import { HasSlotController } from '../../internal/slot'; import { LocalizeController } from '../../utilities/localize'; +import '../icon/icon'; import '../spinner/spinner'; import styles from './button.styles'; import type { CSSResultGroup } from 'lit'; @@ -16,6 +17,7 @@ import type { CSSResultGroup } from 'lit'; * @since 2.0 * @status stable * + * @dependency sl-icon * @dependency sl-spinner * * @event sl-blur - Emitted when the button loses focus. @@ -29,7 +31,7 @@ import type { CSSResultGroup } from 'lit'; * @csspart prefix - The prefix slot's container. * @csspart label - The button's label. * @csspart suffix - The suffix slot's container. - * @csspart caret - The button's caret. + * @csspart caret - The button's caret icon. */ @customElement('sl-button') export default class SlButton extends ShoelaceElement { @@ -219,22 +221,7 @@ export default class SlButton extends ShoelaceElement { ${ - this.caret - ? html` - - - - - - ` - : '' + this.caret ? html` ` : '' } ${this.loading ? html`` : ''} diff --git a/src/components/checkbox/checkbox.styles.ts b/src/components/checkbox/checkbox.styles.ts index 71e3ccb9..e9b16e5b 100644 --- a/src/components/checkbox/checkbox.styles.ts +++ b/src/components/checkbox/checkbox.styles.ts @@ -49,11 +49,6 @@ export default css` height: var(--sl-toggle-size); } - .checkbox__control .checkbox__icon svg { - width: 100%; - height: 100%; - } - /* Hover */ .checkbox:not(.checkbox--checked):not(.checkbox--disabled) .checkbox__control:hover { border-color: var(--sl-input-border-color-hover); diff --git a/src/components/checkbox/checkbox.ts b/src/components/checkbox/checkbox.ts index 8ff39e2c..dcaae848 100644 --- a/src/components/checkbox/checkbox.ts +++ b/src/components/checkbox/checkbox.ts @@ -7,6 +7,7 @@ import { defaultValue } from '../../internal/default-value'; import { FormSubmitController } from '../../internal/form'; import ShoelaceElement from '../../internal/shoelace-element'; import { watch } from '../../internal/watch'; +import '../icon/icon'; import styles from './checkbox.styles'; import type { CSSResultGroup } from 'lit'; @@ -16,6 +17,8 @@ import type { CSSResultGroup } from 'lit'; * @since 2.0 * @status stable * + * @dependency sl-icon + * * @slot - The checkbox's label. * * @event sl-blur - Emitted when the control loses focus. @@ -24,8 +27,8 @@ import type { CSSResultGroup } from 'lit'; * * @csspart base - The component's internal wrapper. * @csspart control - The checkbox control. - * @csspart checked-icon - The container the wraps the checked icon. - * @csspart indeterminate-icon - The container that wraps the indeterminate icon. + * @csspart checked-icon - The checked icon. + * @csspart indeterminate-icon - The indeterminate icon. * @csspart label - The checkbox label. */ @customElement('sl-checkbox') @@ -155,32 +158,9 @@ export default class SlCheckbox extends ShoelaceElement { /> - ${this.checked - ? html` - - - - - - - - - - - ` - : ''} + ${this.checked ? html` ` : ''} ${!this.checked && this.indeterminate - ? html` - - - - - - - - - - ` + ? html` ` : ''} diff --git a/src/components/icon-button/icon-button.test.ts b/src/components/icon-button/icon-button.test.ts index 3648d14e..5cab71df 100644 --- a/src/components/icon-button/icon-button.test.ts +++ b/src/components/icon-button/icon-button.test.ts @@ -33,7 +33,7 @@ describe('', () => { html` ` @@ -48,9 +48,7 @@ describe('', () => { describe('when icon attributes are present', () => { it('renders an sl-icon from a library', async () => { - const el = await fixture( - html` ` - ); + const el = await fixture(html` `); expect(el.shadowRoot?.querySelector('sl-icon')).to.exist; }); diff --git a/src/components/icon/library.system.ts b/src/components/icon/library.system.ts index 40bac682..de00b8fc 100644 --- a/src/components/icon/library.system.ts +++ b/src/components/icon/library.system.ts @@ -8,9 +8,21 @@ import type { IconLibrary } from './library'; // icons are a subset of Bootstrap Icons. // const icons = { - 'check-lg': ` - - + caret: ` + + + + `, + check: ` + + + + + + + + + `, 'chevron-down': ` @@ -46,6 +58,22 @@ const icons = { `, + 'grip-vertical': ` + + + + `, + indeterminate: ` + + + + + + + + + + `, 'person-fill': ` @@ -61,6 +89,15 @@ const icons = { `, + radio: ` + + + + + + + + `, 'star-fill': ` diff --git a/src/components/image-comparer/image-comparer.styles.ts b/src/components/image-comparer/image-comparer.styles.ts index 9e73f5de..a829a4f7 100644 --- a/src/components/image-comparer/image-comparer.styles.ts +++ b/src/components/image-comparer/image-comparer.styles.ts @@ -64,7 +64,7 @@ export default css` background-color: var(--sl-color-neutral-0); border-radius: var(--sl-border-radius-circle); font-size: calc(var(--handle-size) * 0.5); - color: var(--sl-color-neutral-600); + color: var(--sl-color-neutral-700); cursor: inherit; z-index: 10; } diff --git a/src/components/image-comparer/image-comparer.ts b/src/components/image-comparer/image-comparer.ts index 0d03f1a7..1591bde5 100644 --- a/src/components/image-comparer/image-comparer.ts +++ b/src/components/image-comparer/image-comparer.ts @@ -30,6 +30,7 @@ import type { CSSResultGroup } from 'lit'; * @csspart after - The container that holds the "after" image. * @csspart divider - The divider that separates the images. * @csspart handle - The handle that the user drags to expose the after image. + * @csspart handle-icon - The drag icon that appears inside the handle. * * @cssproperty --divider-width - The width of the dividing line. * @cssproperty --handle-size - The size of the compare handle. @@ -143,13 +144,7 @@ export default class SlImageComparer extends ShoelaceElement { tabindex="0" > - - - - - + diff --git a/src/components/menu-item/menu-item.ts b/src/components/menu-item/menu-item.ts index 0403e0a8..766cfd25 100644 --- a/src/components/menu-item/menu-item.ts +++ b/src/components/menu-item/menu-item.ts @@ -24,7 +24,7 @@ import type { CSSResultGroup } from 'lit'; * @slot suffix - Used to append an icon or similar element to the menu item. * * @csspart base - The component's internal wrapper. - * @csspart checked-icon - The checkmark's container, only visible when the menu item is checked. + * @csspart checked-icon - The checked icon, which is only visible when the menu item is checked. * @csspart prefix - The prefix container. * @csspart label - The menu item label. * @csspart suffix - The suffix container. @@ -93,7 +93,7 @@ export default class SlMenuItem extends ShoelaceElement { })} > - + diff --git a/src/components/radio/radio.ts b/src/components/radio/radio.ts index 66bcb65a..13d93d2f 100644 --- a/src/components/radio/radio.ts +++ b/src/components/radio/radio.ts @@ -3,6 +3,7 @@ import { customElement, property, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import ShoelaceElement from '../../internal/shoelace-element'; import { watch } from '../../internal/watch'; +import '../icon/icon'; import styles from './radio.styles'; import type { CSSResultGroup } from 'lit'; @@ -12,6 +13,8 @@ import type { CSSResultGroup } from 'lit'; * @since 2.0 * @status stable * + * @dependency sl-icon + * * @slot - The radio's label. * * @event sl-blur - Emitted when the control loses focus. @@ -20,7 +23,7 @@ import type { CSSResultGroup } from 'lit'; * @csspart base - The component's internal wrapper. * @csspart control - The radio control. * @csspart control--checked - The radio control if radio is checked. - * @csspart checked-icon - The container the wraps the checked icon. + * @csspart checked-icon - The checked icon. * @csspart label - The radio label. */ @customElement('sl-radio') @@ -93,13 +96,7 @@ export default class SlRadio extends ShoelaceElement { })} > - - - - - - - + ${this.checked ? html` ` : ''}