Skip to content

Commit

Permalink
feat(segment): adds scrollable and layout props and updates to follow…
Browse files Browse the repository at this point in the history
… 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.
  • Loading branch information
brandyscarney authored Nov 15, 2018
1 parent 6d59446 commit 256745c
Show file tree
Hide file tree
Showing 36 changed files with 1,697 additions and 630 deletions.
22 changes: 19 additions & 3 deletions angular/BREAKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ A list of the breaking changes introduced to each component in Ionic Angular v4.
- [Range](#range)
- [Refresher](#refresher)
- [Scroll](#scroll)
- [Segment](#segment)
- [Segment Button](#segment-button)
- [Select](#select)
- [Spinner](#spinner)
- [Tabs](#tabs)
Expand Down Expand Up @@ -1170,9 +1170,25 @@ div.scrollable {
```


## Segment
## Segment Button

The markup hasn't changed for Segments, but now writing `<ion-segment-button>` will render a native button element inside of it.
Segment Button text is now required to be wrapped in an `ion-label`.

*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>
```


## Select
Expand Down
11 changes: 6 additions & 5 deletions angular/src/directives/proxies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -685,27 +685,28 @@ export class Searchbar {
}

export declare interface Segment extends StencilComponents<'IonSegment'> {}
@Component({ selector: 'ion-segment', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'disabled', 'value'] })
@Component({ selector: 'ion-segment', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'disabled', 'scrollable', 'value'] })
export class Segment {
ionChange: EventEmitter<CustomEvent>;
ionStyle: EventEmitter<CustomEvent>;

constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
const el = r.nativeElement;
proxyInputs(this, el, ['color', 'mode', 'disabled', 'value']);
proxyOutputs(this, el, ['ionChange']);
proxyInputs(this, el, ['color', 'mode', 'disabled', 'scrollable', 'value']);
proxyOutputs(this, el, ['ionChange', 'ionStyle']);
}
}

export declare interface SegmentButton extends StencilComponents<'IonSegmentButton'> {}
@Component({ selector: 'ion-segment-button', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'checked', 'disabled', 'value'] })
@Component({ selector: 'ion-segment-button', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: '<ng-content></ng-content>', inputs: ['color', 'mode', 'checked', 'disabled', 'layout', 'value'] })
export class SegmentButton {
ionSelect: EventEmitter<CustomEvent>;

constructor(c: ChangeDetectorRef, r: ElementRef) {
c.detach();
const el = r.nativeElement;
proxyInputs(this, el, ['color', 'mode', 'checked', 'disabled', 'value']);
proxyInputs(this, el, ['color', 'mode', 'checked', 'disabled', 'layout', 'value']);
proxyOutputs(this, el, ['ionSelect']);
}
}
Expand Down
21 changes: 21 additions & 0 deletions core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import {
RouteWrite,
ScrollBaseDetail,
ScrollDetail,
SegmentButtonLayout,
SelectInputChangeEvent,
SelectInterface,
SelectPopoverOption,
Expand Down Expand Up @@ -3845,6 +3846,10 @@ export namespace Components {
*/
'disabled': boolean;
/**
* Set the layout of the text and icon in the segment.
*/
'layout': SegmentButtonLayout;
/**
* The mode determines which platform styles to use.
*/
'mode': Mode;
Expand All @@ -3867,6 +3872,10 @@ export namespace Components {
*/
'disabled'?: boolean;
/**
* Set the layout of the text and icon in the segment.
*/
'layout': SegmentButtonLayout;
/**
* The mode determines which platform styles to use.
*/
'mode'?: Mode;
Expand Down Expand Up @@ -3894,6 +3903,10 @@ export namespace Components {
*/
'mode': Mode;
/**
* If `true`, the segment buttons will overflow and the user can swipe to see them.
*/
'scrollable': boolean;
/**
* the value of the segment.
*/
'value'?: string | null;
Expand All @@ -3916,6 +3929,14 @@ export namespace Components {
*/
'onIonChange'?: (event: CustomEvent<TextInputChangeEvent>) => void;
/**
* Emitted when the styles change.
*/
'onIonStyle'?: (event: CustomEvent<StyleEvent>) => void;
/**
* If `true`, the segment buttons will overflow and the user can swipe to see them.
*/
'scrollable'?: boolean;
/**
* the value of the segment.
*/
'value'?: string | null;
Expand Down
58 changes: 34 additions & 24 deletions core/src/components/segment-button/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ Segment buttons are groups of related buttons inside of a [Segment](../../segmen

## Properties

| Property | Attribute | Description | Type | Default |
| ---------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | --------------------- |
| `checked` | `checked` | If `true`, the segment button is selected. | `boolean` | `false` |
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` | `undefined` |
| `disabled` | `disabled` | If `true`, the user cannot interact with the segment button. | `boolean` | `false` |
| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` |
| `value` | `value` | The value of the segment button. | `string` | `'ion-sb-' + (ids++)` |
| Property | Attribute | Description | Type | Default |
| ---------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | --------------------- |
| `checked` | `checked` | If `true`, the segment button is selected. | `boolean` | `false` |
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` | `undefined` |
| `disabled` | `disabled` | If `true`, the user cannot interact with the segment button. | `boolean` | `false` |
| `layout` | `layout` | Set the layout of the text and icon in the segment. | `"icon-bottom" \| "icon-end" \| "icon-hide" \| "icon-start" \| "icon-top" \| "label-hide"` | `undefined` |
| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` |
| `value` | `value` | The value of the segment button. | `string` | `'ion-sb-' + (ids++)` |


## Events
Expand All @@ -26,23 +27,32 @@ Segment buttons are groups of related buttons inside of a [Segment](../../segmen

## CSS Custom Properties

| Name | Description |
| -------------------- | ---------------------------- |
| `--border-radius` | Radius of the button border |
| `--border-style` | Style of the button border |
| `--border-width` | Width of the button border |
| `--btn-background` | Background of the button |
| `--btn-border-color` | Color of the button border |
| `--icon-size` | Size of the button icon |
| `--margin-bottom` | Bottom margin of the button |
| `--margin-end` | End margin of the button |
| `--margin-start` | Start margin of the button |
| `--margin-top` | Top margin of the button |
| `--padding-bottom` | Bottom padding of the button |
| `--padding-end` | End padding of the button |
| `--padding-start` | Start padding of the button |
| `--padding-top` | Top padding of the button |
| `--transition` | Transition of the button |
| Name | Description |
| --------------------------- | ------------------------------------------------------------------- |
| `--background` | Background of the segment button |
| `--background-activated` | Background of the activated (pressed) segment button |
| `--background-checked` | Background of the checked segment button |
| `--background-hover` | Background of the segment button on hover |
| `--border-color` | Color of the segment button border |
| `--border-radius` | Radius of the segment button border |
| `--border-style` | Style of the segment button border |
| `--border-width` | Width of the segment button border |
| `--color` | Color of the segment button |
| `--color-activated` | Color of the activated (pressed) segment button |
| `--color-checked` | Color of the checked segment button |
| `--color-checked-disabled` | Color of the checked & disabled segment button |
| `--color-disabled` | Color of the disabled segment button |
| `--indicator-color` | Color of the indicator (highlight) under the segment button |
| `--indicator-color-checked` | Color of the indicator (highlight) under the checked segment button |
| `--margin-bottom` | Bottom margin of the segment button |
| `--margin-end` | End margin of the segment button |
| `--margin-start` | Start margin of the segment button |
| `--margin-top` | Top margin of the segment button |
| `--padding-bottom` | Bottom padding of the segment button |
| `--padding-end` | End padding of the segment button |
| `--padding-start` | Start padding of the segment button |
| `--padding-top` | Top padding of the segment button |
| `--transition` | Transition of the segment button |


----------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type SegmentButtonLayout = 'icon-top' | 'icon-start' | 'icon-end' | 'icon-bottom' | 'icon-hide' | 'label-hide';
85 changes: 85 additions & 0 deletions core/src/components/segment-button/segment-button.ios.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
@import "./segment-button";
@import "./segment-button.ios.vars";

// iOS Segment Button
// --------------------------------------------------

:host {
--background: #{$segment-button-ios-background-color};
--background-hover: #{$segment-button-ios-background-color-hover};
--background-activated: #{$segment-button-ios-background-color-activated};
--background-checked: #{$segment-button-ios-background-color-checked};
--border-color: #{$segment-button-ios-border-color};
--color: #{$segment-button-ios-text-color};
--color-activated: var(--color);
--color-checked: #{ion-color(primary, contrast)};
--color-disabled: #{ion-color(primary, base, $segment-button-ios-opacity-disabled)};
--color-checked-disabled: #{ion-color(primary, contrast, $segment-button-ios-opacity-disabled)};
--border-radius: #{$segment-button-ios-border-radius};
--border-width: #{$segment-button-ios-border-width};
--border-style: solid;
--transition: #{$segment-button-ios-transition};

min-height: #{$segment-button-ios-height};

font-size: #{$segment-button-ios-font-size};

line-height: #{$segment-button-ios-line-height};
}


// Segment Button: Indicator
// --------------------------------------------------

.segment-button-indicator {
display: none;
}


// Segment Button: Icon
// --------------------------------------------------

::slotted(ion-icon) {
font-size: $segment-button-ios-icon-size;
}


// Segment Button: Layout
// --------------------------------------------------

// Layout: icon start
:host(.segment-button-layout-icon-start) ::slotted(ion-label) {
@include margin-horizontal(2px, 0);
}

// Layout: icon end
:host(.segment-button-layout-icon-end) ::slotted(ion-label) {
@include margin-horizontal(0, 2px);
}


// Segment Button: Hover
// --------------------------------------------------

@media (any-hover: hover) {
:host(:hover:not(.segment-button-checked)) {
background: var(--background-hover);
}
}


// Segment Button: Activated
// --------------------------------------------------

:host(.activated) {
background: var(--background-activated);
}


// Segment: Checked & Activated
// --------------------------------------------------

:host(.segment-button-checked.activated) {
background: var(--background-checked);
color: var(--color-checked);
}
73 changes: 73 additions & 0 deletions core/src/components/segment-button/segment-button.ios.vars.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
@import "../../themes/ionic.globals.ios";

// iOS Segment Button
// --------------------------------------------------

/// @prop - Background of the segment button
$segment-button-ios-background-color: transparent !default;

/// @prop - Background of the checked segment button
$segment-button-ios-background-color-checked: ion-color(primary, base) !default;

/// @prop - Opacity of the segment button on hover
$segment-button-ios-opacity-hover: .1 !default;

/// @prop - Opacity of the segment button when pressed
$segment-button-ios-opacity-activated: .16 !default;

/// @prop - Opacity of the disabled segment button
$segment-button-ios-opacity-disabled: .3 !default;

/// @prop - Background of the segment button on hover
$segment-button-ios-background-color-hover: ion-color(primary, base, $segment-button-ios-opacity-hover) !default;

/// @prop - Background of the activated segment button
$segment-button-ios-background-color-activated: ion-color(primary, base, $segment-button-ios-opacity-activated) !default;

/// @prop - Background of the disabled segment button
$segment-button-ios-background-color-disabled: ion-color(primary, base, $segment-button-ios-opacity-disabled) !default;

/// @prop - Text color of the segment button
$segment-button-ios-text-color: ion-color(primary, base) !default;

/// @prop - Border width of the segment button
$segment-button-ios-border-width: 1px !default;

/// @prop - Height of the segment button
$segment-button-ios-height: 24px !default;

/// @prop - Line height of the segment button
$segment-button-ios-line-height: 37px !default;

/// @prop - Font size of the segment button
$segment-button-ios-font-size: 13px !default;

/// @prop - Border radius of the segment button
$segment-button-ios-border-radius: 4px !default;

/// @prop - Border color of the segment button
$segment-button-ios-border-color: ion-color(primary, base) !default;

/// @prop - Size of an icon in the segment button
$segment-button-ios-icon-size: 26px !default;

/// @prop - Line height of an icon in the segment button
$segment-button-ios-icon-line-height: 28px !default;

/// @prop - Transition of the segment button
$segment-button-ios-transition: 100ms all linear !default;

/// @prop - Max width of the segment button in a toolbar
$segment-button-ios-toolbar-button-max-width: 100px !default;

/// @prop - Line height of the segment button in a toolbar
$segment-button-ios-toolbar-line-height: 22px !default;

/// @prop - Font size of the segment button in a toolbar
$segment-button-ios-toolbar-font-size: 12px !default;

/// @prop - Size of an icon in the segment button in a toolbar
$segment-button-ios-toolbar-icon-size: 22px !default;

/// @prop - Line height of an icon in the segment button in a toolbar
$segment-button-ios-toolbar-icon-line-height: 24px !default;
Loading

0 comments on commit 256745c

Please sign in to comment.