feat(chip): add small size (#29514)

Co-authored-by: Brandy Carney <brandyscarney@users.noreply.github.com>
This commit is contained in:
Maria Hutt
2024-05-17 12:28:29 -07:00
committed by GitHub
parent 3f12e5850d
commit 9fd1a53c74
30 changed files with 256 additions and 15 deletions

View File

@ -578,6 +578,7 @@ ion-chip,prop,disabled,boolean,false,false,false
ion-chip,prop,mode,"ios" | "md",undefined,false,false
ion-chip,prop,outline,boolean,false,false,false
ion-chip,prop,shape,"rectangular" | "round" | "soft" | undefined,undefined,false,false
ion-chip,prop,size,"large" | "small" | undefined,undefined,false,false
ion-chip,prop,theme,"ios" | "md" | "ionic",undefined,false,false
ion-chip,css-prop,--background,ios
ion-chip,css-prop,--background,md

View File

@ -766,6 +766,10 @@ export namespace Components {
* Set to `"soft"` for a chip with slightly rounded corners, `"round"` for a chip with fully rounded corners, or `"rectangular"` for a chip without rounded corners. Defaults to `"round"` for the `"ionic"` theme and `"soft"` for all other themes.
*/
"shape"?: 'soft' | 'round' | 'rectangular';
/**
* Set to `"small"` for a chip with less height and padding. Defaults to `"large"` for the ionic theme, and undefined for all other themes.
*/
"size"?: 'small' | 'large';
/**
* The theme determines the visual appearance of the component.
*/
@ -6026,6 +6030,10 @@ declare namespace LocalJSX {
* Set to `"soft"` for a chip with slightly rounded corners, `"round"` for a chip with fully rounded corners, or `"rectangular"` for a chip without rounded corners. Defaults to `"round"` for the `"ionic"` theme and `"soft"` for all other themes.
*/
"shape"?: 'soft' | 'round' | 'rectangular';
/**
* Set to `"small"` for a chip with less height and padding. Defaults to `"large"` for the ionic theme, and undefined for all other themes.
*/
"size"?: 'small' | 'large';
/**
* The theme determines the visual appearance of the component.
*/

View File

@ -1,4 +1,5 @@
@use "../../themes/ionic/ionic.globals.scss" as globals;
@use "../../foundations/ionic.vars.scss" as tokens;
// Ionic Chip
// --------------------------------------------------
@ -9,13 +10,12 @@ $ionic-states-hover: #{rgba(#05080f, 0.16)}; // We should review how to make thi
:host {
--background: #{globals.$ionic-color-neutral-10};
--border-color: transparent;
--color: #{globals.$ionic-color-neutral-900};
--focus-ring-color: #{$ionic-states-focus-primary};
--focus-ring-width: #{globals.$ionic-border-size-medium};
@include globals.font-smoothing;
@include globals.padding(globals.$ionic-space-xs, globals.$ionic-space-xxs);
@include globals.padding(globals.$ionic-space-xxs, globals.$ionic-space-xs);
@include globals.border-radius(var(--border-radius));
display: inline-flex;
@ -27,18 +27,10 @@ $ionic-states-hover: #{rgba(#05080f, 0.16)}; // We should review how to make thi
gap: globals.$ionic-space-xxxs;
min-height: 32px;
border-width: globals.$ionic-border-size-small;
border-style: solid;
border-color: var(--border-color);
background: var(--background);
color: var(--color);
font-family: globals.$ionic-font-family;
font-size: globals.$ionic-font-size-m;
font-weight: globals.$ionic-font-weight-medium;
line-height: globals.$ionic-font-line-height-full;
@ -57,6 +49,8 @@ $ionic-states-hover: #{rgba(#05080f, 0.16)}; // We should review how to make thi
:host(.chip-outline) {
--background: transparent;
border-width: globals.$ionic-border-size-small;
border-color: globals.$ionic-color-neutral-100;
}
@ -105,3 +99,18 @@ $ionic-states-hover: #{rgba(#05080f, 0.16)}; // We should review how to make thi
::slotted(ion-icon) {
font-size: globals.$ionic-font-size-l;
}
// Size
// ---------------------------------------------
:host(.chip-small) {
min-height: 24px;
font-size: #{tokens.$ionic-font-size-s};
}
:host(.chip-large) {
min-height: 32px;
font-size: globals.$ionic-font-size-m;
}

View File

@ -1,5 +1,6 @@
import type { ComponentInterface } from '@stencil/core';
import { Component, Host, Prop, h } from '@stencil/core';
import { printIonWarning } from '@utils/logging';
import { createColorClasses } from '@utils/theme';
import { getIonTheme } from '../../global/ionic-global';
@ -57,8 +58,31 @@ export class Chip implements ComponentInterface {
return shape;
}
/**
* Set to `"small"` for a chip with less height and padding.
*
* Defaults to `"large"` for the ionic theme, and undefined for all other themes.
*/
@Prop() size?: 'small' | 'large';
private getSize() {
const theme = getIonTheme(this);
const { size } = this;
if (theme === 'ionic') {
return size !== undefined ? size : 'large';
// TODO(ROU-10695): remove the size !== undefined when we add support for
// the `ios` and `md` themes.
} else if (size !== undefined) {
printIonWarning(`The "${size}" size is not supported in the ${theme} theme.`);
}
return undefined;
}
render() {
const theme = getIonTheme(this);
const size = this.getSize();
const shape = this.getShape();
@ -72,6 +96,7 @@ export class Chip implements ComponentInterface {
'chip-disabled': this.disabled,
'ion-activatable': true,
'ion-focusable': !this.disabled,
[`chip-${size}`]: size !== undefined,
})}
>
<slot></slot>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1023 B

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1010 B

After

Width:  |  Height:  |  Size: 1010 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 889 B

After

Width:  |  Height:  |  Size: 888 B

View File

@ -0,0 +1,35 @@
import { expect } from '@playwright/test';
import { configs, test } from '@utils/test/playwright';
/**
* This behavior does not vary across modes/directions.
*/
configs({ modes: ['ionic-md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
test.describe(title('chip: size'), () => {
test('should render small chip', async ({ page }) => {
await page.setContent(
`<ion-chip size="small">
<ion-label>Small</ion-label>
</ion-chip>`,
config
);
const chip = page.locator('ion-chip');
await expect(chip).toHaveScreenshot(screenshot(`chip-size-small`));
});
test('should render large chip', async ({ page }) => {
await page.setContent(
`<ion-chip size="large">
<ion-label>Large</ion-label>
</ion-chip>`,
config
);
const chip = page.locator('ion-chip');
await expect(chip).toHaveScreenshot(screenshot(`chip-size-large`));
});
});
});

View File

@ -0,0 +1,162 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Chip - Size</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
<style>
.grid {
display: grid;
grid-template-columns: repeat(4, minmax(250px, 1fr));
grid-row-gap: 20px;
grid-column-gap: 20px;
}
@media screen and (max-width: 800px) {
.grid {
grid-template-columns: 1fr;
padding: 0;
}
}
</style>
</head>
<body>
<ion-app>
<ion-header>
<ion-toolbar>
<ion-title>Chip - Size</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding" id="content" style="text-align: center">
<h2>Default Size</h2>
<div class="grid">
<div class="grid-item">
<ion-chip>
<ion-label>Default</ion-label>
</ion-chip>
</div>
<div class="grid-item">
<ion-chip>
<ion-icon name="checkmark-circle"></ion-icon>
<ion-label>With Icon</ion-label>
</ion-chip>
</div>
<div class="grid-item">
<ion-chip>
<ion-avatar>
<img
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MTIgNTEyIj48cGF0aCBmaWxsPSIjYzVkYmZmIiBkPSJNMCAwaDUxMnY1MTJIMHoiLz48cGF0aCBkPSJNMjU2IDMwNGM2MS42IDAgMTEyLTUwLjQgMTEyLTExMlMzMTcuNiA4MCAyNTYgODBzLTExMiA1MC40LTExMiAxMTIgNTAuNCAxMTIgMTEyIDExMnptMCA0MGMtNzQuMiAwLTIyNCAzNy44LTIyNCAxMTJ2NTZoNDQ4di01NmMwLTc0LjItMTQ5LjgtMTEyLTIyNC0xMTJ6IiBmaWxsPSIjODJhZWZmIi8+PC9zdmc+"
/>
</ion-avatar>
<ion-label>With Avatar</ion-label>
</ion-chip>
</div>
<div class="grid-item">
<ion-chip>
<ion-avatar>
<img
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MTIgNTEyIj48cGF0aCBmaWxsPSIjYzVkYmZmIiBkPSJNMCAwaDUxMnY1MTJIMHoiLz48cGF0aCBkPSJNMjU2IDMwNGM2MS42IDAgMTEyLTUwLjQgMTEyLTExMlMzMTcuNiA4MCAyNTYgODBzLTExMiA1MC40LTExMiAxMTIgNTAuNCAxMTIgMTEyIDExMnptMCA0MGMtNzQuMiAwLTIyNCAzNy44LTIyNCAxMTJ2NTZoNDQ4di01NmMwLTc0LjItMTQ5LjgtMTEyLTIyNC0xMTJ6IiBmaWxsPSIjODJhZWZmIi8+PC9zdmc+"
/>
</ion-avatar>
<ion-label>With Icon and Avatar</ion-label>
<ion-icon name="close-circle"></ion-icon>
</ion-chip>
</div>
</div>
<h2>Small</h2>
<div class="grid">
<div class="grid-item">
<ion-chip size="small">
<ion-label>Default</ion-label>
</ion-chip>
</div>
<div class="grid-item">
<ion-chip size="small">
<ion-icon name="checkmark-circle"></ion-icon>
<ion-label>With Icon</ion-label>
</ion-chip>
</div>
<div class="grid-item">
<ion-chip size="small">
<ion-avatar>
<img
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MTIgNTEyIj48cGF0aCBmaWxsPSIjYzVkYmZmIiBkPSJNMCAwaDUxMnY1MTJIMHoiLz48cGF0aCBkPSJNMjU2IDMwNGM2MS42IDAgMTEyLTUwLjQgMTEyLTExMlMzMTcuNiA4MCAyNTYgODBzLTExMiA1MC40LTExMiAxMTIgNTAuNCAxMTIgMTEyIDExMnptMCA0MGMtNzQuMiAwLTIyNCAzNy44LTIyNCAxMTJ2NTZoNDQ4di01NmMwLTc0LjItMTQ5LjgtMTEyLTIyNC0xMTJ6IiBmaWxsPSIjODJhZWZmIi8+PC9zdmc+"
/>
</ion-avatar>
<ion-label>With Avatar</ion-label>
</ion-chip>
</div>
<div class="grid-item">
<ion-chip size="small">
<ion-avatar>
<img
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MTIgNTEyIj48cGF0aCBmaWxsPSIjYzVkYmZmIiBkPSJNMCAwaDUxMnY1MTJIMHoiLz48cGF0aCBkPSJNMjU2IDMwNGM2MS42IDAgMTEyLTUwLjQgMTEyLTExMlMzMTcuNiA4MCAyNTYgODBzLTExMiA1MC40LTExMiAxMTIgNTAuNCAxMTIgMTEyIDExMnptMCA0MGMtNzQuMiAwLTIyNCAzNy44LTIyNCAxMTJ2NTZoNDQ4di01NmMwLTc0LjItMTQ5LjgtMTEyLTIyNC0xMTJ6IiBmaWxsPSIjODJhZWZmIi8+PC9zdmc+"
/>
</ion-avatar>
<ion-label>With Icon and Avatar</ion-label>
<ion-icon name="close-circle"></ion-icon>
</ion-chip>
</div>
</div>
<h2>Large</h2>
<div class="grid">
<div class="grid-item">
<ion-chip size="large">
<ion-label>Default</ion-label>
</ion-chip>
</div>
<div class="grid-item">
<ion-chip size="large">
<ion-icon name="checkmark-circle"></ion-icon>
<ion-label>With Icon</ion-label>
</ion-chip>
</div>
<div class="grid-item">
<ion-chip size="large">
<ion-avatar>
<img
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MTIgNTEyIj48cGF0aCBmaWxsPSIjYzVkYmZmIiBkPSJNMCAwaDUxMnY1MTJIMHoiLz48cGF0aCBkPSJNMjU2IDMwNGM2MS42IDAgMTEyLTUwLjQgMTEyLTExMlMzMTcuNiA4MCAyNTYgODBzLTExMiA1MC40LTExMiAxMTIgNTAuNCAxMTIgMTEyIDExMnptMCA0MGMtNzQuMiAwLTIyNCAzNy44LTIyNCAxMTJ2NTZoNDQ4di01NmMwLTc0LjItMTQ5LjgtMTEyLTIyNC0xMTJ6IiBmaWxsPSIjODJhZWZmIi8+PC9zdmc+"
/>
</ion-avatar>
<ion-label>With Avatar</ion-label>
</ion-chip>
</div>
<div class="grid-item">
<ion-chip size="large">
<ion-avatar>
<img
src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MTIgNTEyIj48cGF0aCBmaWxsPSIjYzVkYmZmIiBkPSJNMCAwaDUxMnY1MTJIMHoiLz48cGF0aCBkPSJNMjU2IDMwNGM2MS42IDAgMTEyLTUwLjQgMTEyLTExMlMzMTcuNiA4MCAyNTYgODBzLTExMiA1MC40LTExMiAxMTIgNTAuNCAxMTIgMTEyIDExMnptMCA0MGMtNzQuMiAwLTIyNCAzNy44LTIyNCAxMTJ2NTZoNDQ4di01NmMwLTc0LjItMTQ5LjgtMTEyLTIyNC0xMTJ6IiBmaWxsPSIjODJhZWZmIi8+PC9zdmc+"
/>
</ion-avatar>
<ion-label>With Icon and Avatar</ion-label>
<ion-icon name="close-circle"></ion-icon>
</ion-chip>
</div>
</div>
</ion-content>
</ion-app>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -549,14 +549,14 @@ setting the `checked` property.
@ProxyCmp({
inputs: ['color', 'disabled', 'mode', 'outline', 'shape', 'theme']
inputs: ['color', 'disabled', 'mode', 'outline', 'shape', 'size', 'theme']
})
@Component({
selector: 'ion-chip',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['color', 'disabled', 'mode', 'outline', 'shape', 'theme'],
inputs: ['color', 'disabled', 'mode', 'outline', 'shape', 'size', 'theme'],
})
export class IonChip {
protected el: HTMLElement;

View File

@ -612,14 +612,14 @@ export declare interface IonCardTitle extends Components.IonCardTitle {}
@ProxyCmp({
defineCustomElementFn: defineIonChip,
inputs: ['color', 'disabled', 'mode', 'outline', 'shape', 'theme']
inputs: ['color', 'disabled', 'mode', 'outline', 'shape', 'size', 'theme']
})
@Component({
selector: 'ion-chip',
changeDetection: ChangeDetectionStrategy.OnPush,
template: '<ng-content></ng-content>',
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
inputs: ['color', 'disabled', 'mode', 'outline', 'shape', 'theme'],
inputs: ['color', 'disabled', 'mode', 'outline', 'shape', 'size', 'theme'],
standalone: true
})
export class IonChip {

View File

@ -231,7 +231,8 @@ export const IonChip = /*@__PURE__*/ defineContainer<JSX.IonChip>('ion-chip', de
'color',
'outline',
'disabled',
'shape'
'shape',
'size'
]);