feat(textarea): add styles for textarea solid fill (#30685)
Issue number: internal --------- <!-- Please do not submit updates to dependencies unless it fixes an issue. --> <!-- Please try to limit your pull request to one type (bugfix, feature, etc). Submit multiple pull requests if needed. --> ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> - highlight should only appear on md; - fix some textarea ionic css vars usage; - create sheet for ionic.solid; ## 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-12225-ionic1.vercel.app/src/components/textarea/test/fill?ionic:theme=ionic) [color](https://ionic-framework-git-rou-12225-ionic1.vercel.app/src/components/textarea/test/color?ionic:theme=ionic) [states](https://ionic-framework-git-rou-12225-ionic1.vercel.app/src/components/textarea/test/states?ionic:theme=ionic) --------- Co-authored-by: ionitron <hi@ionicframework.com> Co-authored-by: Brandy Smith <brandyscarney@users.noreply.github.com>
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 5.3 KiB |
@ -151,6 +151,31 @@ configs({ modes: ['ionic-md'], directions: ['ltr'] }).forEach(({ title, screensh
|
||||
await expect(container).toHaveScreenshot(screenshot(`textarea-readonly-no-fill`));
|
||||
});
|
||||
});
|
||||
|
||||
test.describe(title('solid'), () => {
|
||||
test('should render readonly invalid textarea correctly', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<div class="container">
|
||||
<ion-textarea
|
||||
label="Email"
|
||||
label-placement="stacked"
|
||||
value="hi@ionic.io"
|
||||
helper-text="Enter an email"
|
||||
counter="true"
|
||||
maxlength="20"
|
||||
class="ion-touched ion-invalid"
|
||||
readonly="true"
|
||||
></ion-textarea>
|
||||
</div>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const container = page.locator('.container');
|
||||
await expect(container).toHaveScreenshot(screenshot(`textarea-readonly-solid-invalid`));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
@ -60,9 +60,18 @@
|
||||
margin-top: globals.$ion-space-100;
|
||||
}
|
||||
|
||||
// Input Focus
|
||||
// Focus
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
:host(.textarea-fill-outline.has-focus) {
|
||||
--border-width: #{globals.$ion-border-size-050};
|
||||
:host(.textarea-fill-outline.has-focus.ion-valid),
|
||||
:host(.textarea-fill-outline.ion-touched.ion-invalid) {
|
||||
--border-color: var(--highlight-color);
|
||||
}
|
||||
|
||||
// Ionic Textarea - Readonly
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
:host(.textarea-fill-outline.textarea-readonly) {
|
||||
--border-color: #{globals.$ion-border-input-default};
|
||||
--border-width: #{globals.$ion-border-size-025};
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
@use "../../themes/ionic/ionic.globals.scss" as globals;
|
||||
@use "./textarea.common";
|
||||
@use "./textarea.ionic.outline.scss" as outline;
|
||||
@use "./textarea.ionic.solid.scss" as solid;
|
||||
|
||||
// Ionic Textarea
|
||||
// --------------------------------------------------
|
||||
@ -122,7 +123,7 @@
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
ion-icon {
|
||||
color: globals.$ion-primitives-neutral-800;
|
||||
--color: globals.$ion-icon-subtlest;
|
||||
|
||||
font-size: globals.$ion-scale-400;
|
||||
}
|
||||
@ -177,6 +178,7 @@ ion-icon {
|
||||
|
||||
:host(.has-focus) {
|
||||
--border-color: #{globals.$ion-border-focus-default};
|
||||
--border-width: #{globals.$ion-border-size-050};
|
||||
}
|
||||
|
||||
:host(.has-focus) .textarea-highlight {
|
||||
@ -188,7 +190,7 @@ ion-icon {
|
||||
|
||||
@media (any-hover: hover) {
|
||||
:host(:hover) {
|
||||
--border-color: #{globals.$ion-primitives-neutral-600};
|
||||
--border-color: #{globals.$ion-border-focus-default};
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,10 +198,10 @@ ion-icon {
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
:host(.textarea-disabled) {
|
||||
--color: #{globals.$ion-primitives-neutral-500};
|
||||
--background: #{globals.$ion-primitives-neutral-100};
|
||||
--border-color: #{globals.$ion-primitives-neutral-300};
|
||||
--placeholder-color: #{globals.$ion-primitives-neutral-500};
|
||||
--color: #{globals.$ion-text-disabled};
|
||||
--background: #{globals.$ion-bg-input-disabled};
|
||||
--border-color: #{globals.$ion-border-disabled};
|
||||
--placeholder-color: #{globals.$ion-text-disabled};
|
||||
}
|
||||
|
||||
:host(.textarea-disabled:not(.ion-valid)) .textarea-bottom .helper-text,
|
||||
@ -229,7 +231,7 @@ ion-icon {
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
:host(.textarea-readonly) {
|
||||
--background: #{globals.$ion-primitives-neutral-100};
|
||||
--background: #{globals.$ion-bg-input-read-only};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
62
core/src/components/textarea/textarea.ionic.solid.scss
Normal file
@ -0,0 +1,62 @@
|
||||
@use "../../themes/ionic/ionic.globals.scss" as globals;
|
||||
|
||||
// Ionic Textarea Fill: Solid
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
:host(.textarea-fill-solid) {
|
||||
--border-color: #{globals.$ion-bg-input-bold-default};
|
||||
--border-width: #{globals.$ion-border-size-050};
|
||||
--background: #{globals.$ion-bg-input-bold-default};
|
||||
}
|
||||
|
||||
:host(.textarea-fill-solid) .textarea-wrapper {
|
||||
border-bottom: none;
|
||||
|
||||
background: none;
|
||||
}
|
||||
|
||||
:host(.textarea-fill-solid) .textarea-wrapper-inner {
|
||||
@include globals.border-radius(var(--border-radius));
|
||||
position: relative;
|
||||
|
||||
border: var(--border-width) var(--border-style) var(--border-color);
|
||||
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
:host(.textarea-fill-solid) .textarea-bottom {
|
||||
--border-width: #{globals.$ion-scale-0};
|
||||
}
|
||||
|
||||
// Focus
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
:host(.textarea-fill-solid.has-focus) {
|
||||
--border-color: #{globals.$ion-border-focus-default};
|
||||
}
|
||||
|
||||
:host(.textarea-fill-solid.has-focus.ion-valid),
|
||||
:host(.textarea-fill-solid.ion-touched.ion-invalid) {
|
||||
--border-width: #{globals.$ion-border-size-050};
|
||||
--border-color: var(--highlight-color);
|
||||
}
|
||||
|
||||
// Ionic Textarea - Readonly
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
:host(.textarea-fill-solid.textarea-readonly) {
|
||||
--background: #{globals.$ion-bg-input-bold-read-only};
|
||||
--border-color: #{globals.$ion-bg-input-bold-read-only};
|
||||
}
|
||||
|
||||
:host(.textarea-fill-solid.textarea-readonly.ion-invalid) {
|
||||
--border-color: rgba(#{globals.$ion-semantics-danger-base-rgb}, 0.6);
|
||||
}
|
||||
|
||||
// Textarea - Disabled
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
:host(.textarea-fill-solid.textarea-disabled) {
|
||||
--background: #{globals.$ion-bg-input-bold-disabled};
|
||||
--border-color: #{globals.$ion-bg-input-bold-disabled};
|
||||
}
|
||||
@ -776,7 +776,7 @@ export class Textarea implements ComponentInterface {
|
||||
const shape = this.getShape();
|
||||
const value = this.getValue();
|
||||
const inItem = hostContext('ion-item', this.el);
|
||||
const shouldRenderHighlight = (theme === 'md' || theme === 'ionic') && fill !== 'outline' && !inItem;
|
||||
const shouldRenderHighlight = theme === 'md' && fill !== 'outline' && !inItem;
|
||||
|
||||
const hasValue = this.hasValue();
|
||||
const hasStartEndSlots = el.querySelector('[slot="start"], [slot="end"]') !== null;
|
||||
|
||||