feat(segment): adds scrollable and layout props and updates to follow the spec (#16273)

Adds the ability to apply a layout to the segment button in order to better match the Material Design spec, updates the design and UI to match the spec more, and separates the segment button styles back into the proper directory.

- moves the segment button css back into segment-button directory
- updates the design to match the MD spec better
- adds layout property to match MD spec
- adds custom properties for better styling
- allows for overscroll / scrolling tabs via scrollable attribute
- changes the indicator to a div - will need to animate it
- updates e2e tests and add spec test

fixes #16232 fixes #16081
references #14853

BREAKING CHANGES

Segment Button now requires the text to be wrapped in an `ion-label` element for improved styling.

*Old usage:*

 ```html
<ion-segment-button>
  Item One
</ion-segment-button>
```
 *New usage:*

 ```html
<ion-segment-button>
  <ion-label>Item One</ion-label>
</ion-segment-button>
```

Note: this will not technically break your app, but the styles may look wrong.
This commit is contained in:
Brandy Carney
2018-11-15 12:22:35 -05:00
committed by GitHub
parent 6d5944613a
commit 256745cd1e
36 changed files with 1699 additions and 632 deletions

View File

@ -5,83 +5,221 @@
:host {
/**
* @prop --btn-background: Background of the button
* @prop --btn-border-color: Color of the button border
* @prop --border-radius: Radius of the button border
* @prop --border-style: Style of the button border
* @prop --border-width: Width of the button border
* @prop --icon-size: Size of the button icon
* @prop --margin-top: Top margin of the button
* @prop --margin-end: End margin of the button
* @prop --margin-bottom: Bottom margin of the button
* @prop --margin-start: Start margin of the button
* @prop --padding-top: Top padding of the button
* @prop --padding-end: End padding of the button
* @prop --padding-bottom: Bottom padding of the button
* @prop --padding-start: Start padding of the button
* @prop --transition: Transition of the button
* @prop --background: Background of the segment button
* @prop --background-hover: Background of the segment button on hover
* @prop --background-activated: Background of the activated (pressed) segment button
* @prop --background-checked: Background of the checked segment button
*
* @prop --color: Color of the segment button
* @prop --color-activated: Color of the activated (pressed) segment button
* @prop --color-checked: Color of the checked segment button
* @prop --color-disabled: Color of the disabled segment button
* @prop --color-checked-disabled: Color of the checked & disabled segment button
*
* @prop --border-radius: Radius of the segment button border
* @prop --border-color: Color of the segment button border
* @prop --border-style: Style of the segment button border
* @prop --border-width: Width of the segment button border
*
* @prop --margin-top: Top margin of the segment button
* @prop --margin-end: End margin of the segment button
* @prop --margin-bottom: Bottom margin of the segment button
* @prop --margin-start: Start margin of the segment button
*
* @prop --padding-top: Top padding of the segment button
* @prop --padding-end: End padding of the segment button
* @prop --padding-bottom: Bottom padding of the segment button
* @prop --padding-start: Start padding of the segment button
*
* @prop --transition: Transition of the segment button
*
* @prop --indicator-color: Color of the indicator (highlight) under the segment button
* @prop --indicator-color-checked: Color of the indicator (highlight) under the checked segment button
*
*/
--padding-start: 0;
--padding-end: 0;
--padding-top: 0;
--padding-bottom: 0;
--icon-size: 1em;
--btn-background: inherit;
--btn-border-color: inherit;
--indicator-color: transparent;
flex: 1;
flex: 1 0 auto;
flex-direction: column;
color: inherit;
height: 100%;
border-width: var(--border-width);
border-style: var(--border-style);
border-color: var(--border-color);
color: var(--color);
text-decoration: none;
text-overflow: ellipsis;
white-space: nowrap;
font-kerning: none;
overflow: hidden;
}
:host(:first-of-type) .button-native {
--padding-end: 0;
:host(:first-of-type) {
@include border-radius(var(--border-radius), 0, 0, var(--border-radius));
}
:host(:not(:first-of-type)) .button-native {
:host(:not(:first-of-type)) {
border-left-width: 0;
}
:host(:last-of-type) .button-native {
--padding-start: 0;
:host(:last-of-type) {
@include border-radius(0, var(--border-radius), var(--border-radius), 0);
}
.button-native {
@include border-radius(inherit);
@include text-inherit();
@include margin(var(--margin-top), var(--margin-end), var(--margin-bottom), var(--margin-start));
@include padding(var(--padding-top), var(--padding-end), var(--padding-bottom), var(--padding-start));
display: block;
display: flex;
position: relative;
flex-direction: inherit;
align-items: center;
justify-content: center;
width: 100%;
min-width: inherit;
max-width: inherit;
height: 100%;
min-height: inherit;
max-height: inherit;
transition: var(--transition);
border-width: var(--border-width);
border-style: var(--border-style);
border-color: var(--btn-border-color);
border: none;
outline: none;
background: var(--btn-background);
background: var(--background);
contain: content;
cursor: pointer;
overflow: hidden;
}
::slotted(ion-icon) {
font-size: var(--icon-size);
// Segment Button: Checked
// --------------------------------------------------
:host(.segment-button-checked) {
background: var(--background-checked);
color: var(--color-checked);
}
:host(.segment-button-checked) .segment-button-indicator {
background-color: var(--indicator-color-checked);
}
// Segment Button: Activated
// --------------------------------------------------
:host(.activated) {
color: var(--color-activated);
}
// Segment Button: Disabled
// --------------------------------------------------
:host(.segment-button-disabled) {
color: var(--color-disabled);
}
// Segment Button: Checked & Disabled
// --------------------------------------------------
:host(.segment-button-disabled.segment-button-checked) {
color: var(--color-checked-disabled);
}
// Segment Button: Indicator
// --------------------------------------------------
.segment-button-indicator {
align-self: flex-end;
width: 100%;
height: 2px;
background-color: var(--indicator-color);
opacity: 1;
}
// Segment Button Label
// --------------------------------------------------
::slotted(ion-label) {
display: block;
align-self: center;
line-height: 22px;
text-overflow: ellipsis;
white-space: nowrap;
box-sizing: border-box;
}
// Segment Button Layout
// --------------------------------------------------
// Layout: icon top
:host(.segment-button-layout-icon-top) ::slotted(ion-icon) {
order: -1;
}
// Layout: icon bottom
:host(.segment-button-layout-icon-bottom) ::slotted(ion-icon) {
order: 1;
}
// Layout: icon start / end
:host(.segment-button-layout-icon-start),
:host(.segment-button-layout-icon-end) {
flex-direction: row;
}
:host(.segment-button-layout-icon-start) ::slotted(ion-icon) {
order: -1;
}
:host(.segment-button-layout-icon-end) ::slotted(ion-icon) {
order: 1;
}
// Layout: icon hide
:host(.segment-button-layout-icon-hide) ::slotted(ion-icon) {
display: none;
}
// Layout: label hide
:host(.segment-button-layout-label-hide) ::slotted(ion-label) {
display: none;
}
// Segment Button Ripple
// --------------------------------------------------
ion-ripple-effect {
color: var(--ripple-color);
}