mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 12:29:55 +08:00
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:
@ -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
|
||||
@ -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 |
|
||||
|
||||
|
||||
----------------------------------------------
|
||||
|
@ -0,0 +1 @@
|
||||
export type SegmentButtonLayout = 'icon-top' | 'icon-start' | 'icon-end' | 'icon-bottom' | 'icon-hide' | 'label-hide';
|
85
core/src/components/segment-button/segment-button.ios.scss
Normal file
85
core/src/components/segment-button/segment-button.ios.scss
Normal file
@ -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);
|
||||
}
|
@ -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;
|
112
core/src/components/segment-button/segment-button.md.scss
Normal file
112
core/src/components/segment-button/segment-button.md.scss
Normal file
@ -0,0 +1,112 @@
|
||||
@import "./segment-button";
|
||||
@import "./segment-button.md.vars";
|
||||
|
||||
// Material Design Segment Button
|
||||
// --------------------------------------------------
|
||||
|
||||
:host {
|
||||
--padding-top: #{$segment-button-md-padding-top};
|
||||
--padding-end: #{$segment-button-md-padding-end};
|
||||
--padding-bottom: #{$segment-button-md-padding-bottom};
|
||||
--padding-start: #{$segment-button-md-padding-start};
|
||||
--transition: #{$segment-button-md-transition};
|
||||
--background: #{$segment-button-md-background};
|
||||
--background-hover: #{$segment-button-md-background-hover};
|
||||
--background-activated: #{$segment-button-md-background-activated};
|
||||
--color: #{$segment-button-md-text-color};
|
||||
--color-activated: var(--color);
|
||||
--color-checked: #{$segment-button-md-text-color-activated};
|
||||
--color-checked-disabled: var(--color-checked);
|
||||
--indicator-color: transparent;
|
||||
--indicator-color-checked: var(--color-checked);
|
||||
--ripple-color: var(--color-checked);
|
||||
|
||||
min-width: $segment-button-md-min-width;
|
||||
|
||||
max-width: $segment-button-md-max-width;
|
||||
min-height: $segment-button-md-min-height;
|
||||
|
||||
font-size: $segment-button-md-font-size;
|
||||
font-weight: $segment-button-md-font-weight;
|
||||
|
||||
letter-spacing: $segment-button-md-letter-spacing;
|
||||
|
||||
line-height: $segment-button-md-line-height;
|
||||
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
// Segment Button: Checked
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.activated),
|
||||
:host(.segment-button-checked) {
|
||||
--border-color: #{$segment-button-md-border-bottom-color-activated};
|
||||
|
||||
opacity: $segment-button-md-opacity-activated;
|
||||
}
|
||||
|
||||
// Segment Button: Disabled
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.segment-button-disabled) {
|
||||
opacity: $segment-button-md-opacity-disabled;
|
||||
}
|
||||
|
||||
// Segment Button: Icon
|
||||
// --------------------------------------------------
|
||||
|
||||
::slotted(ion-icon) {
|
||||
@include margin(12px, null, 12px, null);
|
||||
|
||||
font-size: $segment-button-md-icon-size;
|
||||
}
|
||||
|
||||
// Segment Button: Label
|
||||
// --------------------------------------------------
|
||||
|
||||
::slotted(ion-label) {
|
||||
@include margin(12px, null, 12px, null);
|
||||
}
|
||||
|
||||
// Segment Button: Layout
|
||||
// --------------------------------------------------
|
||||
|
||||
// Layout: icon top / icon bottom
|
||||
:host(.segment-button-layout-icon-top) ::slotted(ion-label),
|
||||
:host(.segment-button-layout-icon-bottom) ::slotted(ion-icon) {
|
||||
@include margin(0, null, null, null);
|
||||
}
|
||||
|
||||
:host(.segment-button-layout-icon-top) ::slotted(ion-icon),
|
||||
:host(.segment-button-layout-icon-bottom) ::slotted(ion-label) {
|
||||
@include margin(null, null, 0, null);
|
||||
}
|
||||
|
||||
// Layout: icon start
|
||||
:host(.segment-button-layout-icon-start) ::slotted(ion-label) {
|
||||
@include margin-horizontal(8px, 0);
|
||||
}
|
||||
|
||||
// Layout: icon end
|
||||
:host(.segment-button-layout-icon-end) ::slotted(ion-label) {
|
||||
@include margin-horizontal(0, 8px);
|
||||
}
|
||||
|
||||
|
||||
// Segment: Checked & Activated
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.segment-button-checked.activated) {
|
||||
color: var(--color-checked);
|
||||
}
|
||||
|
||||
|
||||
// Segment Button: Hover
|
||||
// --------------------------------------------------
|
||||
|
||||
@media (any-hover: hover) {
|
||||
:host(:hover) {
|
||||
background: var(--background-hover);
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
@import "../../themes/ionic.globals.md";
|
||||
|
||||
// Material Design Segment Button
|
||||
// --------------------------------------------------
|
||||
|
||||
/// @prop - Opacity of the segment button
|
||||
$segment-button-md-opacity: .6 !default;
|
||||
|
||||
/// @prop - Text color of the segment button
|
||||
$segment-button-md-text-color: rgba(var(--ion-text-color-rgb, $text-color-rgb), $segment-button-md-opacity) !default;
|
||||
|
||||
/// @prop - Background of the segment button
|
||||
$segment-button-md-background: none !default;
|
||||
|
||||
/// @prop - Background of the hovered segment button
|
||||
$segment-button-md-background-hover: ion-color(primary, base, .04) !default;
|
||||
|
||||
/// @prop - Background of the activated segment button
|
||||
$segment-button-md-background-activated: ion-color(primary, base, .16) !default;
|
||||
|
||||
/// @prop - Width of the bottom border on the segment button
|
||||
$segment-button-md-border-bottom-width: 2px !default;
|
||||
|
||||
/// @prop - Color of the bottom border on the segment button
|
||||
$segment-button-md-border-bottom-color: transparent !default;
|
||||
|
||||
/// @prop - Text color of the activated segment button
|
||||
$segment-button-md-text-color-activated: ion-color(primary, base) !default;
|
||||
|
||||
/// @prop - Border color of the activated segment button
|
||||
$segment-button-md-border-bottom-color-activated: ion-color(primary, base) !default;
|
||||
|
||||
/// @prop - Opacity of the activated segment button
|
||||
$segment-button-md-opacity-activated: 1 !default;
|
||||
|
||||
/// @prop - Opacity of the disabled segment button
|
||||
$segment-button-md-opacity-disabled: .3 !default;
|
||||
|
||||
/// @prop - Padding top of the segment button
|
||||
$segment-button-md-padding-top: 0 !default;
|
||||
|
||||
/// @prop - Padding end of the segment button
|
||||
$segment-button-md-padding-end: 16px !default;
|
||||
|
||||
/// @prop - Padding bottom of the segment button
|
||||
$segment-button-md-padding-bottom: $segment-button-md-padding-top !default;
|
||||
|
||||
/// @prop - Padding start of the segment button
|
||||
$segment-button-md-padding-start: $segment-button-md-padding-end !default;
|
||||
|
||||
/// @prop - Minimum height of the segment button
|
||||
$segment-button-md-min-height: 48px !default;
|
||||
|
||||
/// @prop - Minimum width of the segment button
|
||||
$segment-button-md-min-width: 90px !default;
|
||||
|
||||
/// @prop - Maximum width of the segment button
|
||||
$segment-button-md-max-width: 360px !default;
|
||||
|
||||
/// @prop - Line height of the segment button
|
||||
$segment-button-md-line-height: 40px !default;
|
||||
|
||||
/// @prop - Font size of the segment button
|
||||
$segment-button-md-font-size: 14px !default;
|
||||
|
||||
/// @prop - Letter spacing of the segment button
|
||||
$segment-button-md-letter-spacing: .06em !default;
|
||||
|
||||
/// @prop - Font weight of the segment button
|
||||
$segment-button-md-font-weight: 500 !default;
|
||||
|
||||
/// @prop - Transition of the segment button
|
||||
$segment-button-md-transition: color .15s linear 0s, opacity .15s linear 0s !default;
|
||||
|
||||
/// @prop - Size of an icon in the segment button
|
||||
$segment-button-md-icon-size: 24px !default;
|
||||
|
||||
/// @prop - Line height of an icon in the segment button
|
||||
$segment-button-md-icon-line-height: $segment-button-md-line-height !default;
|
@ -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);
|
||||
}
|
||||
|
@ -1,13 +1,16 @@
|
||||
import { Component, ComponentInterface, Element, Event, EventEmitter, Prop, Watch } from '@stencil/core';
|
||||
|
||||
import { Color, Mode } from '../../interface';
|
||||
import { Color, Mode, SegmentButtonLayout } from '../../interface';
|
||||
import { createColorClasses } from '../../utils/theme';
|
||||
|
||||
let ids = 0;
|
||||
|
||||
@Component({
|
||||
tag: 'ion-segment-button',
|
||||
styleUrl: 'segment-button.scss',
|
||||
styleUrls: {
|
||||
ios: 'segment-button.ios.scss',
|
||||
md: 'segment-button.md.scss'
|
||||
},
|
||||
shadow: true
|
||||
})
|
||||
export class SegmentButton implements ComponentInterface {
|
||||
@ -36,6 +39,11 @@ export class SegmentButton implements ComponentInterface {
|
||||
*/
|
||||
@Prop() disabled = false;
|
||||
|
||||
/**
|
||||
* Set the layout of the text and icon in the segment.
|
||||
*/
|
||||
@Prop() layout!: SegmentButtonLayout;
|
||||
|
||||
/**
|
||||
* The value of the segment button.
|
||||
*/
|
||||
@ -53,14 +61,19 @@ export class SegmentButton implements ComponentInterface {
|
||||
}
|
||||
}
|
||||
|
||||
private onClick = () => {
|
||||
this.checked = true;
|
||||
}
|
||||
|
||||
hostData() {
|
||||
const { disabled, checked, color } = this;
|
||||
return {
|
||||
'ion-activatable': true,
|
||||
'ion-activatable': 'instant',
|
||||
class: {
|
||||
...createColorClasses(color),
|
||||
'segment-button-disabled': disabled,
|
||||
'segment-button-checked': checked,
|
||||
[`segment-button-layout-${this.layout}`]: true
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -72,11 +85,12 @@ export class SegmentButton implements ComponentInterface {
|
||||
aria-pressed={this.checked ? 'true' : null}
|
||||
class="button-native"
|
||||
disabled={this.disabled}
|
||||
onClick={() => this.checked = true}
|
||||
onClick={this.onClick}
|
||||
>
|
||||
<slot></slot>
|
||||
{this.mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
</button>
|
||||
</button>,
|
||||
<div class="segment-button-indicator"></div>
|
||||
];
|
||||
}
|
||||
}
|
||||
|
1
core/src/components/segment-button/segment-interface.ts
Normal file
1
core/src/components/segment-button/segment-interface.ts
Normal file
@ -0,0 +1 @@
|
||||
export type SegmentButtonLayout = 'icon-top' | 'icon-start' | 'icon-end' | 'icon-bottom' | 'icon-hide' | 'label-hide';
|
@ -2,23 +2,23 @@
|
||||
<!-- Segment buttons with text and click listeners -->
|
||||
<ion-segment>
|
||||
<ion-segment-button (ionSelect)="segmentButtonClicked($event)">
|
||||
Friends
|
||||
<ion-label>Friends</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button (ionSelect)="segmentButtonClicked($event)">
|
||||
Enemies
|
||||
<ion-label>Enemies</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
<!-- Segment buttons with the first checked and the last disabled -->
|
||||
<ion-segment>
|
||||
<ion-segment-button checked>
|
||||
Paid
|
||||
<ion-label>Paid</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button>
|
||||
Free
|
||||
<ion-label>Free</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button disabled>
|
||||
Top
|
||||
<ion-label>Top</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
@ -35,13 +35,103 @@
|
||||
<!-- Segment with a value that checks the last button -->
|
||||
<ion-segment value="shared">
|
||||
<ion-segment-button value="bookmarks">
|
||||
Bookmarks
|
||||
<ion-label>Bookmarks</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button value="reading">
|
||||
Reading List
|
||||
<ion-label>Reading List</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button value="shared">
|
||||
Shared Links
|
||||
<ion-label>Shared Links</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
<!-- Label only -->
|
||||
<ion-segment>
|
||||
<ion-segment-button checked>
|
||||
<ion-label>Item One</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button>
|
||||
<ion-label>Item Two</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button>
|
||||
<ion-label>Item Three</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
<!-- Icon only -->
|
||||
<ion-segment>
|
||||
<ion-segment-button>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button checked>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button>
|
||||
<ion-icon name="pin"></ion-icon>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
<!-- Icon top -->
|
||||
<ion-segment>
|
||||
<ion-segment-button layout="icon-top">
|
||||
<ion-label>Item One</ion-label>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button checked layout="icon-top">
|
||||
<ion-label>Item Two</ion-label>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button layout="icon-top">
|
||||
<ion-label>Item Three</ion-label>
|
||||
<ion-icon name="pin"></ion-icon>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
<!-- Icon bottom -->
|
||||
<ion-segment>
|
||||
<ion-segment-button checked layout="icon-bottom">
|
||||
<ion-icon name="call"></ion-icon>
|
||||
<ion-label>Item One</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button layout="icon-bottom">
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
<ion-label>Item Two</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button layout="icon-bottom">
|
||||
<ion-icon name="pin"></ion-icon>
|
||||
<ion-label>Item Three</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
<!-- Icon start -->
|
||||
<ion-segment>
|
||||
<ion-segment-button checked layout="icon-start">
|
||||
<ion-label>Item One</ion-label>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button layout="icon-start">
|
||||
<ion-label>Item Two</ion-label>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button layout="icon-start">
|
||||
<ion-label>Item Three</ion-label>
|
||||
<ion-icon name="pin"></ion-icon>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
<!-- Icon end -->
|
||||
<ion-segment>
|
||||
<ion-segment-button checked layout="icon-end">
|
||||
<ion-icon name="call"></ion-icon>
|
||||
<ion-label>Item One</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button disabled layout="icon-end">
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
<ion-label>Item Two</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button layout="icon-end">
|
||||
<ion-icon name="pin"></ion-icon>
|
||||
<ion-label>Item Three</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
```
|
||||
|
@ -2,23 +2,23 @@
|
||||
<!-- Segment buttons with text -->
|
||||
<ion-segment>
|
||||
<ion-segment-button>
|
||||
Friends
|
||||
<ion-label>Friends</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button>
|
||||
Enemies
|
||||
<ion-label>Enemies</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
<!-- Segment buttons with the first checked and the last disabled -->
|
||||
<ion-segment>
|
||||
<ion-segment-button checked>
|
||||
Paid
|
||||
<ion-label>Paid</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button>
|
||||
Free
|
||||
<ion-label>Free</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button disabled>
|
||||
Top
|
||||
<ion-label>Top</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
@ -35,13 +35,103 @@
|
||||
<!-- Segment with a value that checks the last button -->
|
||||
<ion-segment value="shared">
|
||||
<ion-segment-button value="bookmarks">
|
||||
Bookmarks
|
||||
<ion-label>Bookmarks</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button value="reading">
|
||||
Reading List
|
||||
<ion-label>Reading List</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button value="shared">
|
||||
Shared Links
|
||||
<ion-label>Shared Links</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
<!-- Label only -->
|
||||
<ion-segment>
|
||||
<ion-segment-button checked>
|
||||
<ion-label>Item One</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button>
|
||||
<ion-label>Item Two</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button>
|
||||
<ion-label>Item Three</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
<!-- Icon only -->
|
||||
<ion-segment>
|
||||
<ion-segment-button>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button checked>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button>
|
||||
<ion-icon name="pin"></ion-icon>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
<!-- Icon top -->
|
||||
<ion-segment>
|
||||
<ion-segment-button layout="icon-top">
|
||||
<ion-label>Item One</ion-label>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button checked layout="icon-top">
|
||||
<ion-label>Item Two</ion-label>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button layout="icon-top">
|
||||
<ion-label>Item Three</ion-label>
|
||||
<ion-icon name="pin"></ion-icon>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
<!-- Icon bottom -->
|
||||
<ion-segment>
|
||||
<ion-segment-button checked layout="icon-bottom">
|
||||
<ion-icon name="call"></ion-icon>
|
||||
<ion-label>Item One</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button layout="icon-bottom">
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
<ion-label>Item Two</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button layout="icon-bottom">
|
||||
<ion-icon name="pin"></ion-icon>
|
||||
<ion-label>Item Three</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
<!-- Icon start -->
|
||||
<ion-segment>
|
||||
<ion-segment-button checked layout="icon-start">
|
||||
<ion-label>Item One</ion-label>
|
||||
<ion-icon name="call"></ion-icon>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button layout="icon-start">
|
||||
<ion-label>Item Two</ion-label>
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button layout="icon-start">
|
||||
<ion-label>Item Three</ion-label>
|
||||
<ion-icon name="pin"></ion-icon>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
|
||||
<!-- Icon end -->
|
||||
<ion-segment>
|
||||
<ion-segment-button checked layout="icon-end">
|
||||
<ion-icon name="call"></ion-icon>
|
||||
<ion-label>Item One</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button disabled layout="icon-end">
|
||||
<ion-icon name="heart"></ion-icon>
|
||||
<ion-label>Item Two</ion-label>
|
||||
</ion-segment-button>
|
||||
<ion-segment-button layout="icon-end">
|
||||
<ion-icon name="pin"></ion-icon>
|
||||
<ion-label>Item Three</ion-label>
|
||||
</ion-segment-button>
|
||||
</ion-segment>
|
||||
```
|
||||
|
Reference in New Issue
Block a user