Merge branch 'next' into icon-properties

This commit is contained in:
Lea Verou
2025-01-07 10:17:39 -05:00
committed by GitHub
9 changed files with 125 additions and 119 deletions

View File

@@ -58,6 +58,71 @@ Set the `variant` attribute to change the callout's variant.
</wa-callout>
```
### Appearance
Use the `appearance` attribute to change the callout's visual appearance (the default is `outlined filled`).
```html {.example}
<wa-callout variant="brand" appearance="outlined accent">
<wa-icon slot="icon" name="check-to-slot"></wa-icon>
This <strong>accent</strong> callout is also <strong>outlined</strong>
</wa-callout>
<br />
<wa-callout variant="brand" appearance="accent">
<wa-icon slot="icon" name="square-check"></wa-icon>
This <strong>accent</strong> callout draws attention without an outline
</wa-callout>
<br />
<wa-callout variant="brand" appearance="outlined filled">
<wa-icon slot="icon" name="fill-drip" variant="regular"></wa-icon>
This callout is both <strong>filled</strong> and <strong>outlined</strong>
</wa-callout>
<br />
<wa-callout variant="brand" appearance="filled">
<wa-icon slot="icon" name="fill" variant="regular"></wa-icon>
This callout is only <strong>filled</strong>
</wa-callout>
<br />
<wa-callout variant="brand" appearance="outlined">
<wa-icon slot="icon" name="lines-leaning" variant="regular"></wa-icon>
Here's an <strong>outlined</strong> callout
</wa-callout>
<br />
<wa-callout variant="brand" appearance="plain">
<wa-icon slot="icon" name="font" variant="regular"></wa-icon>
No bells and whistles on this <strong>plain</strong> callout
</wa-callout>
```
### Sizes
Use the `size` attribute to change a callout's size.
```html {.example}
<wa-callout variant="brand" appearance="outlined accent" size="large">
<wa-icon slot="icon" name="circle-info" variant="solid"></wa-icon>
This is meant to be very emphasized.
</wa-callout>
<wa-callout>
<wa-icon slot="icon" name="circle-info" variant="regular"></wa-icon>
Normal-sized callout.
</wa-callout>
<wa-callout variant="plain" appearance="plain" size="small">
<wa-icon slot="icon" name="circle-info" variant="regular"></wa-icon>
Just a small tip!
</wa-callout>
```
### Without Icons
Icons are optional. Simply omit the `icon` slot if you don't want them.

View File

@@ -60,7 +60,8 @@ Basic cards aren't very exciting, but they can display any content you want them
### Card with Header
Headers can be used to display titles and more. Use the `with-header` attribute to add a header to the card.
Headers can be used to display titles and more.
If using SSR, you need to also use the `with-header` attribute to add a header to the card (if not, it is added automatically).
```html {.example}
<wa-card with-header class="card-header">
@@ -95,7 +96,8 @@ Headers can be used to display titles and more. Use the `with-header` attribute
### Card with Footer
Footers can be used to display actions, summaries, or other relevant content. Use the `with-footer` attribute to add a footer to the card.
Footers can be used to display actions, summaries, or other relevant content.
If using SSR, you need to also use the `with-footer` attribute to add a footer to the card (if not, it is added automatically).
```html {.example}
<wa-card with-footer class="card-footer">
@@ -122,7 +124,8 @@ Footers can be used to display actions, summaries, or other relevant content. Us
### Images
Card images are displayed atop the card and will stretch to fit. Use the `with-image` attribute to add an image to the card.
Card images are displayed atop the card and will stretch to fit.
If using SSR, you need to also use the `with-image` attribute to add an image to the card (if not, it is added automatically).
```html {.example}
<wa-card with-image class="card-image">

View File

@@ -14,6 +14,7 @@ During the alpha period, things might break! We take breaking changes very serio
## Next
- Simplified the internal structure and CSS properties of `<wa-card>`, removed `base` part.
- Fixed a bug in `<wa-switch>` where it would not properly change its "checked" state when its property changed.
- Fixed a bug in the `wa-split` CSS utility that caused it to behave incorrectly
- Improved performance of `<wa-select>` when using a large number of options
@@ -147,4 +148,4 @@ Here's a list of some of the things that have changed since Shoelace v2. For que
Did we miss something? [Let us know!](https://github.com/shoelace-style/webawesome-alpha/discussions)
Are you coming from Shoelace? [The 2.x changelog can be found here.](https://shoelace.style/resources/changelog/)
Are you coming from Shoelace? [The 2.x changelog can be found here.](https://shoelace.style/resources/changelog/)

View File

@@ -8,13 +8,17 @@
align-items: stretch;
border-radius: var(--wa-panel-border-radius);
background-color: var(--background-color, var(--wa-color-fill-quiet));
border-color: var(--border-color, var(--wa-color-border-quiet));
border-color: var(--border-color, transparent);
border-style: var(--wa-panel-border-style);
border-width: var(--wa-panel-border-width);
color: var(--text-color, var(--wa-color-on-normal));
padding: var(--spacing);
}
:host([appearance~='accent']) {
font-weight: var(--wa-font-weight-semibold);
}
[part~='icon'] {
flex: 0 0 auto;
display: flex;

View File

@@ -1,6 +1,8 @@
import { html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import appearanceStyles from '../../styles/utilities/appearance.css';
import sizeStyles from '../../styles/utilities/size.css';
import variantStyles from '../../styles/utilities/variants.css';
import styles from './callout.css';
@@ -22,11 +24,23 @@ import styles from './callout.css';
*/
@customElement('wa-callout')
export default class WaCallout extends WebAwesomeElement {
static shadowStyle = [variantStyles, styles];
static shadowStyle = [variantStyles, appearanceStyles, sizeStyles, styles];
/** The callout's theme variant. */
@property({ reflect: true }) variant: 'brand' | 'success' | 'neutral' | 'warning' | 'danger' = 'brand';
/** The callout's visual appearance. */
@property({ reflect: true }) appearance:
| 'accent'
| 'filled'
| 'outlined'
| 'plain'
| 'outlined filled'
| 'outlined accent' = 'outlined filled';
/** The callout's size. */
@property({ reflect: true }) size: 'small' | 'medium' | 'large' = 'medium';
render() {
return html`
<div part="icon">

View File

@@ -1,45 +1,30 @@
:host {
--background-color: var(--wa-color-surface-default);
--border-color: var(--wa-color-surface-border);
--border-radius: var(--wa-panel-border-radius);
--border-style: var(--wa-panel-border-style);
--border-width: var(--wa-panel-border-width);
--box-shadow: var(--wa-shadow-s);
--spacing: var(--wa-space-xl);
display: inline-block;
}
.card {
display: flex;
flex-direction: column;
background-color: var(--background-color);
border-color: var(--border-color);
border-radius: var(--border-radius);
border-style: var(--border-style);
border-width: var(--border-width);
box-shadow: var(--box-shadow);
background-color: var(--wa-color-surface-default);
border-color: var(--wa-color-surface-border);
border-radius: var(--wa-panel-border-radius);
border-style: var(--wa-panel-border-style);
border-width: var(--wa-panel-border-width);
box-shadow: var(--wa-shadow-s);
color: var(--wa-color-text-normal);
font: inherit;
}
.image {
display: flex;
border-top-left-radius: var(--border-radius);
border-top-right-radius: var(--border-radius);
border-top-left-radius: inherit;
border-top-right-radius: inherit;
margin: calc(-1 * var(--border-width));
overflow: hidden;
}
.image::slotted(img) {
display: block;
width: 100%;
border-bottom-left-radius: 0 !important;
border-bottom-right-radius: 0 !important;
}
.card:not(.card--has-image) .image {
display: none;
&::slotted(img) {
display: block;
width: 100%;
border-bottom-left-radius: 0 !important;
border-bottom-right-radius: 0 !important;
}
}
.header {
@@ -48,13 +33,9 @@
padding: calc(var(--spacing) / 2) var(--spacing);
}
.card:not(.card--has-header) .header {
display: none;
}
.card:not(.card--has-image) .header {
border-top-left-radius: var(--border-radius);
border-top-right-radius: var(--border-radius);
:host(:not([with-image])) .header {
border-top-left-radius: inherit;
border-top-right-radius: inherit;
}
.body {
@@ -62,14 +43,16 @@
padding: var(--spacing);
}
.card--has-footer .footer {
.footer {
display: block;
border-top: inherit;
border-bottom-left-radius: var(--border-radius);
border-bottom-right-radius: var(--border-radius);
border-bottom-left-radius: inherit;
border-bottom-right-radius: inherit;
padding: var(--spacing);
}
.card:not(.card--has-footer) .footer {
:host(:not([with-header])) .header,
:host(:not([with-footer])) .footer,
:host(:not([with-image])) .image {
display: none;
}

View File

@@ -22,14 +22,6 @@ describe('<wa-card>', () => {
`);
await expect(el).to.be.accessible();
});
it('should contain the class card.', async () => {
const el = await fixture<WaCard>(html`
<wa-card>This is just a basic card. No image, no header, and no footer. Just your content.</wa-card>
`);
const card = el.shadowRoot!.querySelector('.card')!;
expect(card.classList.value.trim()).to.eq('card');
});
});
describe('when provided an element in the slot "header" to render a header', () => {
@@ -76,17 +68,6 @@ describe('<wa-card>', () => {
expect(childNodes.length).to.eq(1);
});
it('should contain the class card--has-header.', async () => {
const el = await fixture<WaCard>(
html`<wa-card with-header>
<div slot="header">Header Title</div>
This card has a header. You can put all sorts of things in it!
</wa-card>`,
);
const card = el.shadowRoot!.querySelector('.card')!;
expect(card.classList.value.trim()).to.eq('card card--has-header');
});
});
describe('when provided an element in the slot "footer" to render a footer', () => {
@@ -137,19 +118,6 @@ describe('<wa-card>', () => {
expect(childNodes.length).to.eq(1);
});
it('should contain the class card--has-footer.', async () => {
const el = await fixture<WaCard>(
html`<wa-card with-footer>
This card has a footer. You can put all sorts of things in it!
<div slot="footer">Footer Content</div>
</wa-card>`,
);
const card = el.shadowRoot!.querySelector('.card')!;
expect(card.classList.value.trim()).to.eq('card card--has-footer');
});
});
describe('when provided an element in the slot "image" to render a image', () => {
@@ -201,22 +169,6 @@ describe('<wa-card>', () => {
expect(childNodes.length).to.eq(1);
});
it('should contain the class card--has-image.', async () => {
const el = await fixture<WaCard>(
html`<wa-card with-image>
<img
slot="image"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
alt="A kitten walks towards camera on top of pallet."
/>
This is a kitten, but not just any kitten. This kitten likes walking along pallets.
</wa-card>`,
);
const card = el.shadowRoot!.querySelector('.card')!;
expect(card.classList.value.trim()).to.eq('card card--has-image');
});
});
});
}

View File

@@ -1,6 +1,5 @@
import { html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import WebAwesomeElement from '../../internal/webawesome-element.js';
import styles from './card.css';
@@ -15,49 +14,32 @@ import styles from './card.css';
* @slot footer - An optional footer for the card.
* @slot image - An optional image to render at the start of the card.
*
* @csspart base - The component's base wrapper.
* @csspart image - The container that wraps the card's image.
* @csspart header - The container that wraps the card's header.
* @csspart body - The container that wraps the card's main content.
* @csspart footer - The container that wraps the card's footer.
*
* @cssproperty --background-color - The card's background color.
* @cssproperty --border-color - The card's border color, including borders that occur inside the card.
* @cssproperty --border-radius - The radius for the card's corners. Expects a single value.
* @cssproperty --border-style - The style of the card's borders.
* @cssproperty --border-width - The width of the card's borders. Expects a single value.
* @cssproperty --box-shadow - The shadow effects around the edges of the card.
* @cssproperty --spacing - The amount of space around and between sections of the card. Expects a single value.
*/
@customElement('wa-card')
export default class WaCard extends WebAwesomeElement {
static shadowStyle = styles;
/** Renders the card with a header */
/** Renders the card with a header. Only needed for SSR, otherwise is automatically added. */
@property({ attribute: 'with-header', type: Boolean }) withHeader = false;
/** Renders the card with an image */
/** Renders the card with an image. Only needed for SSR, otherwise is automatically added. */
@property({ attribute: 'with-image', type: Boolean }) withImage = false;
/** Renders the card with a footer */
/** Renders the card with a footer. Only needed for SSR, otherwise is automatically added. */
@property({ attribute: 'with-footer', type: Boolean }) withFooter = false;
render() {
return html`
<div
part="base"
class=${classMap({
card: true,
'card--has-footer': this.withFooter,
'card--has-image': this.withImage,
'card--has-header': this.withHeader,
})}
>
<slot name="image" part="image" class="image"></slot>
<slot name="header" part="header" class="header"></slot>
<slot part="body" class="body"></slot>
<slot name="footer" part="footer" class="footer"></slot>
</div>
<slot name="image" part="image" class="image"></slot>
<slot name="header" part="header" class="header"></slot>
<slot part="body" class="body"></slot>
<slot name="footer" part="footer" class="footer"></slot>
`;
}
}

View File

@@ -39,6 +39,8 @@
.wa-plain,
:host([appearance~='plain']) {
--background-color: transparent;
--text-color: var(--wa-color-on-quiet);
--background-color-hover: var(--wa-color-fill-quiet);
--background-color-active: color-mix(in oklab, var(--background-color-hover), transparent 20%);