Skip to content

Commit

Permalink
feat(documentation, styles): Update textarea styles and add floating …
Browse files Browse the repository at this point in the history
…label small variant (#2857)

I updated the styles to be as close to figma as possible, but since some
paddings in figma don't match any post-size, there will be some
differences.

---------

Co-authored-by: Oliver Schürch <[email protected]>
  • Loading branch information
davidritter-dotcom and oliverschuerch authored Jun 12, 2024
1 parent 1e166d5 commit 48352e8
Show file tree
Hide file tree
Showing 15 changed files with 232 additions and 64 deletions.
6 changes: 6 additions & 0 deletions .changeset/few-news-switch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@swisspost/design-system-documentation': major
'@swisspost/design-system-styles': major
---

Added a small variant for the textarea with floating label
8 changes: 1 addition & 7 deletions packages/documentation/cypress/e2e/components/textarea.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,7 @@ describe('Textarea', () => {
});

it('Has no detectable a11y violations on load for all variants', () => {
cy.checkA11y('#root-inner', {
rules: {
'color-contrast': {
enabled: false,
},
},
});
cy.checkA11y('#root-inner');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ function renderCheckbox(args: Args, context: StoryContext) {

const containerClasses = mapClasses({
'form-check': true,
[args.size]: args.size && args.size !== 'null',
[args.size]: args.size,
'form-check-inline': args.inline,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ But note that the `<textarea>` element must come first, so we can ensure the cor

<div className="alert alert-warning">
<h4 className="alert-heading">We're deprecating the regular and medium sizes for text input, textarea and select.</h4>
<p className="mt-0">This will make it easier to select the appropriate size variant: small for internal applications, large for external applications.<br />`.form-control-rg` and `.form-control-md` are deprecated and will be removed in the next major version.</p>
<p className="mt-0">This will make it easier to select the appropriate size variant: small for internal applications, large for external applications.<br />
`.form-control-rg` and `.form-control-md` are deprecated and will be removed in the next major version.</p>
</div>

The size can be changed by simply adding one of four classes:
Expand All @@ -51,14 +52,13 @@ The size can be changed by simply adding one of four classes:
- Large: `.form-control-lg`

<div className="alert alert-info">
<h4 className="alert-heading">Do not apply size classes on floating-label elements</h4>
<div className="mt-0">
It is not intended to apply the size classes to `textarea` elements that are nested in a
`.form-floating` container.
</div>
Regular and medium size classes are not available on floating-label elements
</div>

<Canvas of={TextareaStories.Size} />
<div className="hide-col-default">
<Controls of={TextareaStories.Size} />
</div>

### Validation

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { MetaComponent } from '@root/types';
import type { Args, StoryContext, StoryObj } from '@storybook/web-components';
import { html, nothing } from 'lit';
import { mapClasses } from '@/utils';
import { MetaComponent } from '@root/types';

const VALIDATION_STATE_MAP: Record<string, undefined | boolean> = {
'null': undefined,
Expand All @@ -26,8 +26,8 @@ const meta: MetaComponent = {
floatingLabel: false,
hiddenLabel: false,
value: undefined,
size: 'null',
rows: 4,
size: 'form-control-lg',
sizeFloatingLabel: 'form-control-lg',
hint: 'Hintus textus elare volare cantare hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.',
disabled: false,
validation: 'null',
Expand Down Expand Up @@ -99,13 +99,32 @@ const meta: MetaComponent = {
category: 'General',
},
},
sizeFloatingLabel: {
name: 'Size',
description: "Sets the size of the component's appearance.",
if: {
arg: 'floatingLabel',
truthy: true,
},
control: {
type: 'select',
labels: {
'form-control-sm': 'Small',
'form-control-lg': 'Large',
},
},
options: ['form-control-sm', 'form-control-lg'],
table: {
category: 'General',
},
},
rows: {
name: 'Rows',
description:
'Attribute to set the initial height, in lines of text, of the `textarea` element.',
control: {
type: 'number',
min: 3,
min: 2,
max: 10,
step: 1,
},
Expand Down Expand Up @@ -160,9 +179,11 @@ type Story = StoryObj;
function renderTextarea(args: Args, context: StoryContext) {
const classes = mapClasses({
'form-control': true,
[args.size]: args.size && args.size !== 'null',
[args.validation]: args.validation && args.validation !== 'null',
[args.size]: !args.floatingLabel,
[args.sizeFloatingLabel]: args.floatingLabel,
[args.validation]: args.validation,
});
console.log(classes);
const useAriaLabel = !args.floatingLabel && args.hiddenLabel;
const label = !useAriaLabel
? html` <label for=${context.id} class="form-label">${args.label}</label> `
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,10 @@ function renderTable(args: Args) {
<table
class="${mapClasses({
table: true,
[args.borderStyle]: args.borderStyle && args.borderStyle !== 'null',
[args.borderStyle]: args.borderStyle,
[variants]: variants && variants !== '',
[cationTop]: cationTop !== 'null',
[args.alignment]: args.alignment && args.alignment !== 'null',
[args.alignment]: args.alignment,
})}"
>
<caption class="${args.captionPlacement === 'hidden' ? 'visually-hidden' : ''}">
Expand Down
1 change: 1 addition & 0 deletions packages/documentation/src/utils/map-classes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ export function mapClasses(classObject: Record<string, boolean>): string {
return Object.entries(classObject)
.filter(([_newClass, shouldAddClass]) => shouldAddClass)
.map(([newClass]) => newClass)
.filter(c => c !== 'null')
.join(' ');
}
83 changes: 73 additions & 10 deletions packages/styles/src/components/floating-label.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
@use './../mixins/forms' as forms-mx;
@use './../mixins/utilities' as utilities-mx;

@use './../functions/sizing';

@use './../variables/type';
@use './../variables/spacing';
@use './../variables/components/forms';
Expand Down Expand Up @@ -215,24 +217,28 @@
}

> textarea.form-control {
padding-top: forms.$input-padding-y-lg * 2;
padding-bottom: forms.$input-padding-y-lg;
padding-top: forms.$form-floating-textarea-padding-t !important;
padding-bottom: spacing.$size-mini;
padding-right: spacing.$size-large;
min-height: (forms.$form-floating-label-font-size * forms.$input-line-height-lg) +
forms.$form-floating-textarea-padding-t + spacing.$size-mini +
sizing.px-to-rem(forms.$input-border-width * 2);
height: auto;

~ label {
padding-bottom: 0;
width: calc(100% - (#{forms.$input-border-width * 2}));
max-width: none;
height: unset;
padding-top: spacing.$size-regular;
}

&:focus,
&:not(:placeholder-shown) {
padding-top: forms.$input-padding-y-lg * 2;
padding-bottom: forms.$input-padding-y-lg;
padding-bottom: spacing.$size-mini;

~ label {
padding-top: forms.$input-padding-y-lg * forms.$form-floating-label-scale;
padding-top: spacing.$size-mini;
width: calc(
(100% * #{forms.$form-floating-label-upscale}) - #{forms.$form-floating-label-translate-x *
forms.$form-floating-label-upscale * 2} - #{forms.$input-border-width * forms.$form-floating-label-upscale *
Expand All @@ -243,11 +249,46 @@
}
}

&.form-control-sm {
padding-top: forms.$form-floating-textarea-padding-t-sm !important;
padding-right: spacing.$size-large;
font-size: forms.$form-floating-label-font-size-placeholder-sm;
min-height: (
forms.$form-floating-label-font-size-placeholder-sm * forms.$input-line-height-sm
) + forms.$form-floating-textarea-padding-t-sm + spacing.$size-mini +
sizing.px-to-rem(forms.$input-border-width * 2);
height: auto;

~ label {
font-size: forms.$form-floating-label-font-size-placeholder-sm;
padding-left: spacing.$size-regular;
padding-top: spacing.$size-regular;
padding-right: spacing.$size-large;
}

&:focus,
&:not(:placeholder-shown) {
padding-bottom: spacing.$size-mini;

~ label {
transform: scale(forms.$form-floating-label-scale-sm);
padding-top: spacing.$size-mini;
width: calc(
(100% * #{forms.$form-floating-label-upscale-sm}) - #{forms.$form-floating-label-translate-x-sm *
forms.$form-floating-label-upscale-sm * 2} - #{forms.$input-border-width * forms.$form-floating-label-upscale-sm *
2} - #{forms.$form-floating-padding-x-sm * forms.$form-floating-label-upscale-sm}
);
max-width: none;
background: forms.$input-bg;
}
}
}

&:is(.is-valid, .is-invalid) {
~ label {
width: calc(
100% - (#{forms.$input-border-width * 2}) - #{forms.$form-floating-padding-x} - #{form-validation.$form-feedback-icon-offset} -
#{form-validation.$form-feedback-icon-size}
100% - (#{forms.$input-border-width * 2}) - #{form-validation.$form-feedback-icon-offset} -
#{forms.$form-bg-size}
);
}

Expand All @@ -257,11 +298,33 @@
width: calc(
(100% * #{forms.$form-floating-label-upscale}) - #{forms.$form-floating-label-translate-x *
forms.$form-floating-label-upscale * 2} - #{forms.$input-border-width * forms.$form-floating-label-upscale *
2} - #{forms.$form-floating-padding-x * forms.$form-floating-label-upscale} - #{form-validation.$form-feedback-icon-offset *
forms.$form-floating-label-upscale} - #{form-validation.$form-feedback-icon-size *
forms.$form-floating-label-upscale}
2} - #{form-validation.$form-feedback-icon-offset * forms.$form-floating-label-upscale} -
#{form-validation.$form-feedback-icon-size * forms.$form-floating-label-upscale}
);
}
}

&.form-control-sm {
~ label {
width: calc(
100% - (#{forms.$input-border-width * 2}) - #{form-validation.$form-feedback-icon-offset} -
#{forms.$form-bg-size-sm}
);
}

&:focus,
&:not(:placeholder-shown) {
padding-right: spacing.$size-bigger-big;

~ label {
width: calc(
(100% * #{forms.$form-floating-label-upscale-sm}) - #{forms.$form-floating-label-translate-x *
forms.$form-floating-label-upscale-sm * 2} - #{forms.$input-border-width * forms.$form-floating-label-upscale-sm *
2} - #{form-validation.$form-feedback-icon-offset *
forms.$form-floating-label-upscale-sm} - #{forms.$form-bg-size-sm * forms.$form-floating-label-upscale-sm}
);
}
}
}
}
}
Expand Down
15 changes: 10 additions & 5 deletions packages/styles/src/components/form-textarea.scss
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
@use './../variables/spacing';
@use './../variables/components/forms';
@use './../functions/sizing';

textarea {
&.form-control {
textarea.form-control {
&::-webkit-resizer {
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 15 15' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='#{forms.$input-border-color}' d='M0 12H3V15H0V12Z'/%3E%3Cpath fill='#{forms.$input-border-color}' d='M6 12H9V15H6V12Z'/%3E%3Cpath fill='#{forms.$input-border-color}' d='M6 6H9V9H6V6Z'/%3E%3Cpath fill='#{forms.$input-border-color}' d='M12 6H15V9H12V6Z'/%3E%3Cpath fill='#{forms.$input-border-color}' d='M12 0H15V3H12V0Z'/%3E%3Cpath fill='#{forms.$input-border-color}' d='M12 12H15V15H12V12Z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-size: 75%;
}

&[disabled] {
&::-webkit-resizer {
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 15 15' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='#{forms.$input-border-color}' d='M0 12H3V15H0V12Z'/%3E%3Cpath fill='#{forms.$input-border-color}' d='M6 12H9V15H6V12Z'/%3E%3Cpath fill='#{forms.$input-border-color}' d='M6 6H9V9H6V6Z'/%3E%3Cpath fill='#{forms.$input-border-color}' d='M12 6H15V9H12V6Z'/%3E%3Cpath fill='#{forms.$input-border-color}' d='M12 0H15V3H12V0Z'/%3E%3Cpath fill='#{forms.$input-border-color}' d='M12 12H15V15H12V12Z'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-size: 75%;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 15 15' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='#{forms.$input-disabled-border-color}' d='M0 12H3V15H0V12Z'/%3E%3Cpath fill='#{forms.$input-disabled-border-color}' d='M6 12H9V15H6V12Z'/%3E%3Cpath fill='#{forms.$input-disabled-border-color}' d='M6 6H9V9H6V6Z'/%3E%3Cpath fill='#{forms.$input-disabled-border-color}' d='M12 6H15V9H12V6Z'/%3E%3Cpath fill='#{forms.$input-disabled-border-color}' d='M12 0H15V3H12V0Z'/%3E%3Cpath fill='#{forms.$input-disabled-border-color}' d='M12 12H15V15H12V12Z'/%3E%3C/svg%3E");
}
}
}
35 changes: 29 additions & 6 deletions packages/styles/src/components/form-validation.scss
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,30 @@
.form-control,
.form-select {
&.is-invalid {
border-color: form-validation.$form-feedback-invalid-color;

&:focus {
&:not(:disabled) {
border-color: form-validation.$form-feedback-invalid-color;

&:focus {
border-color: form-validation.$form-feedback-invalid-color;
}
}

&.form-control-sm ~ .invalid-feedback {
padding: form-validation.$form-feedback-padding-y-sm form-validation.$form-feedback-padding-x;
}
}

&.is-valid {
border-color: var(--post-success);
&:not(:disabled) {
border-color: var(--post-success);

&:focus {
border-color: var(--post-success);
}
}

&:focus {
border-color: form-validation.$form-feedback-valid-color;
&.form-control-sm ~ .valid-feedback {
padding: form-validation.$form-feedback-padding-y-sm form-validation.$form-feedback-padding-x;
}
}

Expand All @@ -135,6 +147,17 @@
}
}

textarea.form-control {
&.is-invalid,
&.is-valid {
background-position: right spacing.$size-micro top spacing.$size-mini;

&.form-control-sm {
background-position: right spacing.$size-micro top spacing.$size-mini;
}
}
}

.form-control:not([type='file']) {
&.is-invalid {
background-image: b.escape-svg(form-validation.$form-feedback-icon-invalid);
Expand Down
Loading

0 comments on commit 48352e8

Please sign in to comment.