Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ feat(form): horizontal layout for label and controls #1169

Merged
merged 22 commits into from
Dec 5, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .changeset/slow-parrots-argue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
'@baloise/design-system-components': minor
---

Introduce 'horizontal' prop for aligning label and input side by side in Field component, with message displayed below.

```html
<bal-field horizontal>
<bal-field-label>Firstname</bal-field-label>
<bal-field-control>
<bal-input placeholder="Basic"></bal-input>
</bal-field-control>
<bal-field-message color="hint">Field Message</bal-field-message>
</bal-field>
```
1 change: 0 additions & 1 deletion CHANGELOG_NEXT.md
Original file line number Diff line number Diff line change
@@ -617,7 +617,6 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
## 10.15.2 (2022-07-05)



## [10.21.2](https://github.com/baloise/design-system/compare/v10.21.1...v10.21.2) (2022-09-16)

**Note:** Version bump only for package root
1 change: 0 additions & 1 deletion CHANGELOG_v12.md
Original file line number Diff line number Diff line change
@@ -549,4 +549,3 @@ Follow the migration guide [Migration from 10.x to 11.x](https://design.baloise.
- Rebranded components
- New breakpoint high-definition
- bal-input pattern

2 changes: 1 addition & 1 deletion docs/.storybook/addons/version/register.js
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ addons.register('my/toolbar', () => {
// match: ({ viewMode }) => !!(viewMode && viewMode.match(/^(story|docs)$/)),
render: ({ active }) => {
return (
<a className="my-version" href='?path=/docs/changelog--page'>
<a className="my-version" href='?path=/docs/changelog--documentation'>
<span className="my-version__label">Latest:</span>
{version}
</a>
7 changes: 7 additions & 0 deletions docs/stories/components/bal-field/bal-field.mdx
Original file line number Diff line number Diff line change
@@ -30,6 +30,13 @@ import * as FieldStories from './bal-field.stories'

{/* ------------------------------------------------------ */}

<StoryHeading of={FieldStories.Horizontal}></StoryHeading>

Limit the use of the horizontal layout to forms exclusively within internal applications that adopt the [compact theme](?path=/docs/development-theming--documentation#compact-theme).

<Canvas of={FieldStories.Horizontal} />

{/* ------------------------------------------------------ */}
## Component API

import api from './api.md?raw'
19 changes: 19 additions & 0 deletions docs/stories/components/bal-field/bal-field.stories.ts
Original file line number Diff line number Diff line change
@@ -169,3 +169,22 @@ export const WithGrid = Story({
</bal-card>`,
),
})

export const Horizontal = Story({
args: {
placeholder: 'Enter your email address',
},
...withRender(
({ ...args }) => `<bal-field horizontal>
<bal-field-label
>Email address</bal-field-label
>
<bal-field-control>
<bal-input ${props(args)}></bal-input>
</bal-field-control>
<bal-field-message color="hint"
>Enter a valid email address.</bal-field-message
>
</bal-field>`,
),
})
18 changes: 18 additions & 0 deletions docs/stories/components/bal-field/theming.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
## Theming

The component can be customization by changing the CSS variables.

<a class="sb-unstyled button is-primary" href="../?path=/docs/development-theming--page">Go to theming guide</a>

<!-- START: human documentation -->



<!-- END: human documentation -->

### Variables​

| Variable |
| ------------------------------------ |
| `--bal-field-label-horizontal-width` |
| `--bal-field-label-column-gap` |
21 changes: 18 additions & 3 deletions docs/stories/development/00-guides/05-theming.stories.mdx
Original file line number Diff line number Diff line change
@@ -34,7 +34,22 @@ CSS Variables enable a value to be stored in a single location and referenced in
They also facilitate dynamic CSS modification at runtime, a task that previously necessitated a CSS preprocessor.
Thanks to CSS variables, it is simpler than ever to replace Baloise Design System components to align with a brand or theme.

## Global Theming
## Compact theme

The compact theme features a narrower layout with a reduced font size (14px instead of 16px). Additionally, spaces such as margins and paddings are adjusted to align with mobile dimensions, ensuring a more compact appearance.

To activate the compact theme, import the theme-compact stylesheet into the root App component or a global stylesheet.

It is recommended to import the theme-compact file at the end of your stylesheet, after the other imports from the Design System.

<Code
language="js"
code={`
@import '@baloise/design-system-css/css/theme-compact';
`}
/>

## Custom theme

In an application, CSS variables can be established globally within the `:root` selector.

@@ -48,7 +63,7 @@ In an application, CSS variables can be established globally within the `:root`
`}
/>

## Component Theming
### By Component

To assign a CSS variable for a specific component, incorporate the variable within its selector.

@@ -74,7 +89,7 @@ Change the background on an badge with the .my-badge class
`}
/>

## Variables set via JavaScript​
### By JavaScript​

Using [setProperty()](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration/setProperty) in JavaScript, CSS variables can also be altered:

8 changes: 8 additions & 0 deletions packages/components/src/components.d.ts
Original file line number Diff line number Diff line change
@@ -966,6 +966,10 @@ export namespace Components {
* If `true`, the element is not mutable, focusable, or even submitted with the form. The user can neither edit nor focus on the control, nor its form control descendants.
*/
"disabled"?: boolean;
/**
* If true, label and input are aligned horizontally within the field component, with the message positioned in a new line below.
*/
"horizontal"?: boolean;
/**
* If `true` the component gets a invalid red style.
*/
@@ -6061,6 +6065,10 @@ declare namespace LocalJSX {
* If `true`, the element is not mutable, focusable, or even submitted with the form. The user can neither edit nor focus on the control, nor its form control descendants.
*/
"disabled"?: boolean;
/**
* If true, label and input are aligned horizontally within the field component, with the message positioned in a new line below.
*/
"horizontal"?: boolean;
/**
* If `true` the component gets a invalid red style.
*/
34 changes: 34 additions & 0 deletions packages/components/src/components/bal-field/bal-field.sass
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@import '@baloise/design-system-css/sass/mixins'
@import './bal-field.vars'

+blocks(field, field-label, field-control, field-message, field-hint)
display: block
@@ -43,3 +44,36 @@

.bal-field-control + .bal-field-message
margin-top: -1.5rem !important

.bal-field--horizontal
display: flex
flex-wrap: wrap
column-gap: var(--bal-field-label-column-gap)
align-items: center

.bal-field-label
display: flex
align-items: center
min-width: var(--bal-field-label-horizontal-width)
max-width: var(--bal-field-label-horizontal-width)
justify-content: end
margin-bottom: 0

.bal-field-control
flex: 1
padding-bottom: 0
align-self: flex-end

.bal-field-message
flex-basis: 100%
margin-top: 0 !important
margin-left: calc(var(--bal-field-label-horizontal-width) + var(--bal-field-label-column-gap))

.bal-field-hint
margin-left: 0

.bal-hint
top: 0

.bal-field-hint ~ .bal-field-message
margin-left: calc(var(--bal-field-label-horizontal-width) + (var(--bal-field-label-column-gap) * 2) + 1.125rem)
6 changes: 6 additions & 0 deletions packages/components/src/components/bal-field/bal-field.tsx
Original file line number Diff line number Diff line change
@@ -43,6 +43,11 @@ export class Field implements ComponentInterface, BalMutationObserver {
this.updateProps([...this.inputElements, 'bal-field-label'], 'required')
}

/**
* If true, label and input are aligned horizontally within the field component, with the message positioned in a new line below.
*/
@Prop() horizontal?: boolean = false

/**
* If `true` the component gets a invalid red style.
*/
@@ -196,6 +201,7 @@ export class Field implements ComponentInterface, BalMutationObserver {
'bal-field': true,
'field': true,
'bal-field--invalid': this.invalid === true,
'bal-field--horizontal': this.horizontal === true,
}}
>
<slot></slot>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* @prop --bal-field-label-horizontal-width: Width of the label
* @prop --bal-field-label-column-gap: Gap between the label and the input
*/

:root
//
// label
--bal-field-label-horizontal-width: 33.3333%
--bal-field-label-column-gap: .5rem
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />

<script type="module" src="/build/design-system-components.esm.js"></script>
<script nomodule src="/build/design-system-components.js"></script>
<link rel="stylesheet" href="/assets/theme-compact.css" />
</head>

<body>
<bal-doc-app>
<main class="container py-medium">
<section data-testid="horizontal">
<bal-field horizontal>
<bal-field-label>Firstname</bal-field-label>
<bal-field-control>
<bal-input placeholder="Basic"></bal-input>
</bal-field-control>
<bal-field-message color="hint">Field Message</bal-field-message>
</bal-field>
</section>
<br />
<section data-testid="horizontal-long-label">
<bal-field horizontal>
<bal-field-label
>Firstname (The name given to you at birth or the name you commonly use in official documents, such as
your legal first name. Please ensure accuracy for administrative purposes.)</bal-field-label
>
<bal-field-control>
<bal-input placeholder="Basic"></bal-input>
</bal-field-control>
<bal-field-message color="danger"
>Error: The provided input for the Field component failed validation. Please ensure that your entry
adheres to the specified format and requirements.</bal-field-message
>
</bal-field>
</section>
<br />
<section data-testid="horizontal-with-hint">
<bal-field expanded="true" class="mt-x-large" horizontal>
<bal-field-label>Firstname</bal-field-label>
<bal-field-hint subject="Spider-Man">
Spider-Man is a fictional superhero created by writer-editor Stan Lee and writer-artist Steve Ditko.
</bal-field-hint>
<bal-field-control>
<bal-input id="bal-input-1" name="firstName" placeholder="Enter your firstname"></bal-input>
</bal-field-control>
<bal-field-message color="danger">Required Field</bal-field-message>
</bal-field>
</section>
</main>
</bal-doc-app>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -81,6 +81,44 @@
<bal-field-message color="hint">Field Message</bal-field-message>
</bal-field>
</section>
<section data-testid="horizontal">
<bal-field horizontal>
<bal-field-label>Firstname</bal-field-label>
<bal-field-control>
<bal-input placeholder="Basic"></bal-input>
</bal-field-control>
<bal-field-message color="hint">Field Message</bal-field-message>
</bal-field>
</section>
<br />
<section data-testid="horizontal-long-label">
<bal-field horizontal>
<bal-field-label
>Firstname (The name given to you at birth or the name you commonly use in official documents, such as
your legal first name. Please ensure accuracy for administrative purposes.)</bal-field-label
>
<bal-field-control>
<bal-input placeholder="Basic"></bal-input>
</bal-field-control>
<bal-field-message color="danger"
>Error: The provided input for the Field component failed validation. Please ensure that your entry
adheres to the specified format and requirements.</bal-field-message
>
</bal-field>
</section>
<br />
<section data-testid="horizontal-with-hint">
<bal-field expanded="true" class="mt-x-large" horizontal>
<bal-field-label>Firstname</bal-field-label>
<bal-field-hint subject="Spider-Man">
Spider-Man is a fictional superhero created by writer-editor Stan Lee and writer-artist Steve Ditko.
</bal-field-hint>
<bal-field-control>
<bal-input id="bal-input-1" name="firstName" placeholder="Enter your firstname"></bal-input>
</bal-field-control>
<bal-field-message color="danger">Required Field</bal-field-message>
</bal-field>
</section>
</main>
</bal-doc-app>
</body>
21 changes: 21 additions & 0 deletions test/cypress/e2e/visual/bal-field.visual.cy.ts
Original file line number Diff line number Diff line change
@@ -30,3 +30,24 @@ describe('bal-field', () => {
cy.getByTestId('label-long').compareSnapshot('label-long-mobile')
})
})

describe('bal-field-horizontal', () => {
beforeEach(() => cy.visit('/components/bal-field/test/bal-field-horizontal.visual.html').waitForDesignSystem())

it('basic component', () => {
cy.platform('desktop')
cy.getByTestId('horizontal').compareSnapshot('horizontal-desktop')
cy.getByTestId('horizontal-long-label').compareSnapshot('horizontal-long-label-desktop')
cy.getByTestId('horizontal-with-hint').compareSnapshot('horizontal-with-hint-desktop')

cy.platform('tablet')
cy.getByTestId('horizontal').compareSnapshot('horizontal-tablet')
cy.getByTestId('horizontal-long-label').compareSnapshot('horizontal-long-label-tablet')
cy.getByTestId('horizontal-with-hint').compareSnapshot('horizontal-with-hint-tablet')

cy.platform('mobile')
cy.getByTestId('horizontal').compareSnapshot('horizontal-mobile')
cy.getByTestId('horizontal-long-label').compareSnapshot('horizontal-long-label-mobile')
cy.getByTestId('horizontal-with-hint').compareSnapshot('horizontal-with-hint-mobile')
})
})
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.