feat(input): add styles for ionic theme for fill=solid (#30417)
Issue number: Internal --------- ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> - add fill solid to ionic theme input; - move input.outline.scss to input.ionic.scss; - add fill solid to states page; - remove highlight styles for ionic theme; - add tests for ionic solid input; ## Does this introduce a breaking change? - [ ] Yes - [x] No <!-- If this introduces a breaking change: 1. Describe the impact and migration path for existing applications below. 2. Update the BREAKING.md file with the breaking change. 3. Add "BREAKING CHANGE: [...]" to the commit description when merging. See https://github.com/ionic-team/ionic-framework/blob/main/docs/CONTRIBUTING.md#footer for more information. --> ## Other information <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. --> - fill: https://ionic-framework-git-rou-11889-ionic1.vercel.app/src/components/input/test/fill?ionic:theme=ionic - states: https://ionic-framework-git-rou-11889-ionic1.vercel.app/src/components/input/test/states?ionic:theme=ionic --------- Co-authored-by: ionitron <hi@ionicframework.com>
@@ -1,142 +1,6 @@
|
||||
@use "../../themes/ionic/ionic.globals.scss" as globals;
|
||||
|
||||
// Input Fill: Outline (Ionic Theme)
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
:host(.input-fill-outline) {
|
||||
--border-radius: #{globals.$ion-border-radius-100};
|
||||
--padding-start: #{globals.$ion-space-300};
|
||||
--padding-end: #{globals.$ion-space-300};
|
||||
}
|
||||
|
||||
:host(.input-fill-outline.input-size-large) {
|
||||
--padding-start: #{globals.$ion-space-400};
|
||||
--padding-end: #{globals.$ion-space-400};
|
||||
}
|
||||
|
||||
:host(.input-fill-outline.input-size-xlarge) {
|
||||
--padding-start: #{globals.$ion-space-500};
|
||||
--padding-end: #{globals.$ion-space-500};
|
||||
}
|
||||
|
||||
/**
|
||||
* The bottom content should never have
|
||||
* a border with the outline style.
|
||||
*/
|
||||
:host(.input-fill-outline) .input-bottom {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
:host(.input-fill-outline) .input-wrapper {
|
||||
/**
|
||||
* For the ionic theme, the padding needs to sit on the
|
||||
* native wrapper instead, so that it sits within the
|
||||
* outline container but does not always affect the
|
||||
* label text.
|
||||
*/
|
||||
@include globals.padding(0);
|
||||
|
||||
/**
|
||||
* Outline inputs do not have a bottom border.
|
||||
* Instead, they have a border that wraps the
|
||||
* input + label.
|
||||
*/
|
||||
border-bottom: none;
|
||||
|
||||
/**
|
||||
* Do not show a background on the input wrapper as
|
||||
* this includes the label, instead we apply the
|
||||
* background to the native wrapper.
|
||||
*/
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
:host(.input-fill-outline.input-label-placement-stacked) .label-text-wrapper {
|
||||
@include globals.transform-origin(start, top);
|
||||
|
||||
/**
|
||||
* Label text should not extend
|
||||
* beyond the bounds of the input.
|
||||
*/
|
||||
max-width: calc(100% - var(--padding-start) - var(--padding-end));
|
||||
}
|
||||
|
||||
:host(.input-fill-outline) .label-text-wrapper {
|
||||
/**
|
||||
* The label should appear on top of an outline
|
||||
* container that overlaps it so it is always clickable.
|
||||
*/
|
||||
position: relative;
|
||||
}
|
||||
|
||||
:host(.input-fill-outline) .native-wrapper {
|
||||
@include globals.border-radius(inherit);
|
||||
@include globals.padding(var(--padding-top), var(--padding-end), var(--padding-bottom), var(--padding-start));
|
||||
|
||||
min-height: globals.$ion-scale-1000;
|
||||
|
||||
/**
|
||||
* Apply the background to the native input
|
||||
* wrapper to only style the input.
|
||||
*/
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
// Input Fill: Outline, Outline Container
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
:host(.input-fill-outline) .input-outline {
|
||||
@include globals.position(0, 0, 0, 0);
|
||||
@include globals.border-radius(var(--border-radius));
|
||||
|
||||
position: absolute;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
pointer-events: none;
|
||||
|
||||
border: var(--border-width) var(--border-style) var(--border-color);
|
||||
}
|
||||
|
||||
// Input Fill: Outline, Label Placement: Stacked
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// This makes the label sit above the input.
|
||||
:host(.label-floating.input-fill-outline.input-label-placement-stacked) .label-text-wrapper {
|
||||
@include globals.margin(0);
|
||||
@include globals.padding(globals.$ion-space-100, null);
|
||||
}
|
||||
|
||||
// Start/End Slots
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
:host(.input-fill-outline) ::slotted([slot="start"]) {
|
||||
margin-inline-end: globals.$ion-space-200;
|
||||
}
|
||||
|
||||
:host(.input-fill-outline) ::slotted([slot="end"]) {
|
||||
margin-inline-start: globals.$ion-space-200;
|
||||
}
|
||||
|
||||
// Input Shapes
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.input-fill-outline.input-shape-soft) {
|
||||
--border-radius: #{globals.$ion-border-radius-200};
|
||||
}
|
||||
|
||||
:host(.input-fill-outline.input-shape-round) {
|
||||
--border-radius: #{globals.$ion-border-radius-400};
|
||||
}
|
||||
|
||||
:host(.input-fill-outline.input-shape-rectangular) {
|
||||
--border-radius: #{globals.$ion-border-radius-0};
|
||||
}
|
||||
|
||||
// Input Focus
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
:host(.input-fill-outline.has-focus) {
|
||||
--border-width: #{globals.$ion-border-size-050};
|
||||
--background: #{globals.$ion-primitives-base-white};
|
||||
--border-color: #{globals.$ion-primitives-neutral-500};
|
||||
}
|
||||
|
||||
@@ -1,26 +1,128 @@
|
||||
@use "../../themes/ionic/ionic.globals.scss" as globals;
|
||||
@use "./input.common";
|
||||
@forward "./input.ionic.outline.scss";
|
||||
|
||||
@forward "./input.ionic.solid.scss";
|
||||
// Ionic Input
|
||||
// --------------------------------------------------
|
||||
|
||||
:host {
|
||||
--color: #{globals.$ion-primitives-neutral-1200};
|
||||
--border-width: #{globals.$ion-border-size-025};
|
||||
--border-color: #{globals.$ion-primitives-neutral-500};
|
||||
--highlight-color-valid: #{globals.$ion-semantics-success-900};
|
||||
--highlight-color-invalid: #{globals.$ion-semantics-danger-800};
|
||||
--highlight-color-invalid: #{globals.$ion-border-danger-default};
|
||||
--placeholder-color: #{globals.$ion-primitives-neutral-800};
|
||||
--placeholder-opacity: 1;
|
||||
--background: #{globals.$ion-primitives-base-white};
|
||||
|
||||
@include globals.typography(globals.$ion-body-md-regular);
|
||||
}
|
||||
|
||||
// Input Outline Container
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
.input-outline {
|
||||
@include globals.position(0, 0, 0, 0);
|
||||
@include globals.border-radius(var(--border-radius));
|
||||
|
||||
position: absolute;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
pointer-events: none;
|
||||
|
||||
border: var(--border-width) var(--border-style) var(--border-color);
|
||||
}
|
||||
|
||||
// Input Label Placement: Stacked
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// This makes the label sit above the input.
|
||||
:host(.label-floating.input-label-placement-stacked) .label-text-wrapper {
|
||||
@include globals.margin(0);
|
||||
@include globals.padding(globals.$ion-space-100, null);
|
||||
}
|
||||
|
||||
.input-wrapper {
|
||||
/**
|
||||
* For the ionic theme, the padding needs to sit on the
|
||||
* native wrapper instead, so that it sits within the
|
||||
* outline container but does not always affect the
|
||||
* label text.
|
||||
*/
|
||||
@include globals.padding(0);
|
||||
|
||||
/**
|
||||
* Outline inputs do not have a bottom border.
|
||||
* Instead, they have a border that wraps the
|
||||
* input + label.
|
||||
*/
|
||||
border-bottom: none;
|
||||
|
||||
/**
|
||||
* Do not show a background on the input wrapper as
|
||||
* this includes the label, instead we apply the
|
||||
* background to the native wrapper.
|
||||
*/
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.label-text-wrapper {
|
||||
/**
|
||||
* The label should appear on top of an outline
|
||||
* container that overlaps it so it is always clickable.
|
||||
*/
|
||||
position: relative;
|
||||
}
|
||||
|
||||
:host(.input-label-placement-stacked) .label-text-wrapper {
|
||||
@include globals.transform-origin(start, top);
|
||||
|
||||
/**
|
||||
* Label text should not extend
|
||||
* beyond the bounds of the input.
|
||||
*/
|
||||
max-width: calc(100% - var(--padding-start) - var(--padding-end));
|
||||
}
|
||||
|
||||
/**
|
||||
* The bottom content should never have
|
||||
* a border with the outline style.
|
||||
*/
|
||||
.input-bottom {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.native-wrapper {
|
||||
@include globals.border-radius(inherit);
|
||||
@include globals.padding(var(--padding-top), var(--padding-end), var(--padding-bottom), var(--padding-start));
|
||||
|
||||
min-height: globals.$ion-scale-1000;
|
||||
|
||||
/**
|
||||
* Apply the background to the native input
|
||||
* wrapper to only style the input.
|
||||
*/
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
// Ionic Input Sizes
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.input-size-medium) {
|
||||
--padding-start: #{globals.$ion-space-300};
|
||||
--padding-end: #{globals.$ion-space-300};
|
||||
}
|
||||
|
||||
:host(.input-size-large) {
|
||||
--padding-start: #{globals.$ion-space-400};
|
||||
--padding-end: #{globals.$ion-space-400};
|
||||
}
|
||||
|
||||
:host(.input-size-xlarge) {
|
||||
--padding-start: #{globals.$ion-space-500};
|
||||
--padding-end: #{globals.$ion-space-500};
|
||||
}
|
||||
|
||||
:host(.input-size-medium) .native-wrapper {
|
||||
min-height: globals.$ion-scale-1000;
|
||||
}
|
||||
@@ -33,10 +135,25 @@
|
||||
min-height: globals.$ion-scale-1400;
|
||||
}
|
||||
|
||||
// Input Shapes
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.input-shape-soft) {
|
||||
--border-radius: #{globals.$ion-soft-xl};
|
||||
}
|
||||
|
||||
:host(.input-shape-round) {
|
||||
--border-radius: #{globals.$ion-round-xl};
|
||||
}
|
||||
|
||||
:host(.input-shape-rectangular) {
|
||||
--border-radius: #{globals.$ion-rectangular-xl};
|
||||
}
|
||||
|
||||
// Ionic Input Password Toggle Sizes
|
||||
// --------------------------------------------------
|
||||
|
||||
:host ion-input-password-toggle {
|
||||
:host(.input-size-medium) ion-input-password-toggle {
|
||||
--size: #{globals.$ion-scale-1000};
|
||||
}
|
||||
|
||||
@@ -50,7 +167,8 @@
|
||||
|
||||
// Target area
|
||||
// --------------------------------------------------
|
||||
:host .native-wrapper::after {
|
||||
|
||||
.native-wrapper::after {
|
||||
@include globals.position(50%, 0, null, 0);
|
||||
|
||||
position: absolute;
|
||||
@@ -78,6 +196,17 @@
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
// Start/End Slots
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
::slotted([slot="start"]) {
|
||||
margin-inline-end: globals.$ion-space-200;
|
||||
}
|
||||
|
||||
::slotted([slot="end"]) {
|
||||
margin-inline-start: globals.$ion-space-200;
|
||||
}
|
||||
|
||||
// Input Clear Button
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
@@ -202,29 +331,12 @@
|
||||
--background: #{globals.$ion-primitives-neutral-100};
|
||||
}
|
||||
|
||||
// Input Highlight
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
.input-highlight {
|
||||
@include globals.position(null, null, -1px, 0);
|
||||
|
||||
position: absolute;
|
||||
|
||||
width: 100%;
|
||||
height: globals.$ion-border-size-050;
|
||||
|
||||
transform: scale(0);
|
||||
|
||||
transition: transform globals.$ion-transition-time-200;
|
||||
|
||||
background: var(--border-color);
|
||||
}
|
||||
|
||||
// Input Focus
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
:host(.has-focus) {
|
||||
--border-color: #{globals.$ion-border-focus-default};
|
||||
--border-width: #{globals.$ion-border-size-050};
|
||||
}
|
||||
|
||||
:host(.has-focus) .input-highlight {
|
||||
|
||||
51
core/src/components/input/input.ionic.solid.scss
Normal file
@@ -0,0 +1,51 @@
|
||||
@use "../../themes/ionic/ionic.globals.scss" as globals;
|
||||
// Input Fill: Solid
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
:host(.input-fill-solid) {
|
||||
--background: #{globals.$ion-bg-input-bold-default};
|
||||
--border-color: #{globals.$ion-bg-input-bold-default};
|
||||
}
|
||||
|
||||
/**
|
||||
* If the input has a validity state, the
|
||||
* border should reflect that as a color.
|
||||
*/
|
||||
:host(.input-fill-solid.has-focus.ion-valid) .native-wrapper,
|
||||
:host(.input-fill-solid.ion-touched.ion-invalid) .native-wrapper {
|
||||
--border-color: var(--highlight-color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Background and border should be
|
||||
* slightly darker on hover.
|
||||
*/
|
||||
@media (any-hover: hover) {
|
||||
:host(:hover) {
|
||||
--border-color: #{globals.$ion-border-focus-default};
|
||||
}
|
||||
}
|
||||
|
||||
// Input - Disabled
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
:host(.input-fill-solid.input-disabled) {
|
||||
--background: #{globals.$ion-bg-input-bold-disabled};
|
||||
--placeholder-color: #{globals.$ion-text-disabled};
|
||||
}
|
||||
|
||||
// Input - Readonly
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
:host(.input-fill-solid.input-readonly) {
|
||||
--background: #{globals.$ion-bg-input-bold-read-only};
|
||||
--border-color: #{globals.$ion-bg-input-bold-read-only};
|
||||
}
|
||||
|
||||
/**
|
||||
* Background and border should be
|
||||
* much darker on focus.
|
||||
*/
|
||||
:host(.input-fill-solid.has-focus) {
|
||||
--border-color: #{globals.$ion-border-focus-default};
|
||||
}
|
||||
@@ -847,7 +847,7 @@ export class Input implements ComponentInterface {
|
||||
const size = this.getSize();
|
||||
const shape = this.getShape();
|
||||
const inItem = hostContext('ion-item', this.el);
|
||||
const shouldRenderHighlight = (theme === 'md' || theme === 'ionic') && fill !== 'outline' && !inItem;
|
||||
const shouldRenderHighlight = theme === 'md' && fill !== 'outline' && !inItem;
|
||||
const labelPlacement = this.getLabelPlacement();
|
||||
|
||||
const hasValue = this.hasValue();
|
||||
@@ -909,7 +909,7 @@ export class Input implements ComponentInterface {
|
||||
* <label> element, ensuring that clicking the label text
|
||||
* focuses the input.
|
||||
*/
|
||||
theme === 'ionic' && fill === 'outline' && <div class="input-outline"></div>
|
||||
theme === 'ionic' && <div class="input-outline"></div>
|
||||
}
|
||||
<slot name="start"></slot>
|
||||
<input
|
||||
|
||||
@@ -88,6 +88,35 @@
|
||||
readonly="true"
|
||||
></ion-input>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>Solid</h2>
|
||||
|
||||
<ion-input
|
||||
fill="solid"
|
||||
label="Email"
|
||||
value="hi@ionic.io"
|
||||
helper-text="Enter an email"
|
||||
counter="true"
|
||||
maxlength="20"
|
||||
readonly="true"
|
||||
></ion-input>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>Solid: Color</h2>
|
||||
|
||||
<ion-input
|
||||
color="warning"
|
||||
fill="solid"
|
||||
label="Email"
|
||||
value="hi@ionic.io"
|
||||
helper-text="Enter an email"
|
||||
counter="true"
|
||||
maxlength="20"
|
||||
readonly="true"
|
||||
></ion-input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1>Disabled</h1>
|
||||
@@ -209,6 +238,67 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid">
|
||||
<div class="grid-item">
|
||||
<h2>Solid</h2>
|
||||
|
||||
<ion-input
|
||||
fill="solid"
|
||||
label="Email"
|
||||
value="hi@ionic.io"
|
||||
helper-text="Enter an email"
|
||||
counter="true"
|
||||
maxlength="20"
|
||||
disabled="true"
|
||||
></ion-input>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>Solid, Valid</h2>
|
||||
|
||||
<ion-input
|
||||
fill="solid"
|
||||
label="Email"
|
||||
value="hi@ionic.io"
|
||||
helper-text="Enter an email"
|
||||
counter="true"
|
||||
maxlength="20"
|
||||
class="ion-valid has-focus"
|
||||
disabled="true"
|
||||
></ion-input>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>Solid, Invalid</h2>
|
||||
|
||||
<ion-input
|
||||
fill="solid"
|
||||
label="Email"
|
||||
value="hi@ionic.io"
|
||||
error-text="Please enter a valid email"
|
||||
counter="true"
|
||||
maxlength="20"
|
||||
class="ion-touched ion-invalid"
|
||||
disabled="true"
|
||||
></ion-input>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>Solid, Color (ionic theme only)</h2>
|
||||
|
||||
<ion-input
|
||||
fill="solid"
|
||||
label="Email"
|
||||
value="hi@ionic.io"
|
||||
helper-text="Enter an email"
|
||||
counter="true"
|
||||
maxlength="20"
|
||||
disabled="true"
|
||||
color="warning"
|
||||
></ion-input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1>Focused</h1>
|
||||
<div class="grid">
|
||||
<div class="grid-item">
|
||||
@@ -222,6 +312,12 @@
|
||||
|
||||
<ion-input fill="outline" label="Email" value="hi@ionic.io" class="has-focus"></ion-input>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>Solid</h2>
|
||||
|
||||
<ion-input fill="solid" label="Email" value="hi@ionic.io" class="has-focus"></ion-input>
|
||||
</div>
|
||||
</div>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
|
||||
@@ -141,6 +141,62 @@ configs({ modes: ['ionic-md'], directions: ['ltr'] }).forEach(({ title, screensh
|
||||
await expect(container).toHaveScreenshot(screenshot(`input-disabled-outline`));
|
||||
});
|
||||
});
|
||||
test.describe(title('solid'), () => {
|
||||
test('should render disabled input correctly', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<div class="container">
|
||||
<ion-input
|
||||
fill="solid"
|
||||
label="Email"
|
||||
value="hi@ionic.io"
|
||||
helper-text="Enter an email"
|
||||
counter="true"
|
||||
maxlength="20"
|
||||
disabled="true"
|
||||
></ion-input>
|
||||
|
||||
<ion-input
|
||||
fill="solid"
|
||||
label="Email"
|
||||
value="hi@ionic.io"
|
||||
helper-text="Enter an email"
|
||||
counter="true"
|
||||
maxlength="20"
|
||||
class="ion-valid has-focus"
|
||||
disabled="true"
|
||||
></ion-input>
|
||||
|
||||
<ion-input
|
||||
fill="solid"
|
||||
label="Email"
|
||||
value="hi@ionic.io"
|
||||
error-text="Please enter a valid email"
|
||||
counter="true"
|
||||
maxlength="20"
|
||||
class="ion-touched ion-invalid"
|
||||
disabled="true"
|
||||
></ion-input>
|
||||
|
||||
<ion-input
|
||||
fill="solid"
|
||||
label="Email"
|
||||
value="hi@ionic.io"
|
||||
helper-text="Enter an email"
|
||||
counter="true"
|
||||
maxlength="20"
|
||||
disabled="true"
|
||||
color="warning"
|
||||
></ion-input>
|
||||
</div>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const container = page.locator('.container');
|
||||
await expect(container).toHaveScreenshot(screenshot(`input-disabled-solid`));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(title('focused'), () => {
|
||||
@@ -166,6 +222,16 @@ configs({ modes: ['ionic-md'], directions: ['ltr'] }).forEach(({ title, screensh
|
||||
maxlength="20"
|
||||
class="has-focus"
|
||||
></ion-input>
|
||||
|
||||
<ion-input
|
||||
fill="solid"
|
||||
label="Email"
|
||||
value="hi@ionic.io"
|
||||
helper-text="Enter an email"
|
||||
counter="true"
|
||||
maxlength="20"
|
||||
class="has-focus"
|
||||
></ion-input>
|
||||
</div>
|
||||
`,
|
||||
config
|
||||
@@ -223,6 +289,30 @@ configs({ modes: ['ionic-md'], directions: ['ltr'] }).forEach(({ title, screensh
|
||||
await expect(container).toHaveScreenshot(screenshot(`input-readonly-outline`));
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(title('solid'), () => {
|
||||
test('should render readonly input correctly', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<div class="container">
|
||||
<ion-input
|
||||
fill="solid"
|
||||
label="Email"
|
||||
value="hi@ionic.io"
|
||||
helper-text="Enter an email"
|
||||
counter="true"
|
||||
maxlength="20"
|
||||
readonly="true"
|
||||
></ion-input>
|
||||
</div>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const container = page.locator('.container');
|
||||
await expect(container).toHaveScreenshot(screenshot(`input-readonly-solid`));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 4.8 KiB |