Skip to content

Commit

Permalink
feat(select): update popover interface to match MD spec on desktop, a…
Browse files Browse the repository at this point in the history
…llow multiple values in popover interface (#23474)

resolves #23657
resolves #15500
resolves #12310
  • Loading branch information
brandyscarney authored Jul 20, 2021
1 parent be219a2 commit 2c07a15
Show file tree
Hide file tree
Showing 28 changed files with 889 additions and 92 deletions.
25 changes: 17 additions & 8 deletions core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ export namespace Components {
"translucent": boolean;
}
interface IonApp {
"setFocus": (elements: HTMLElement[]) => Promise<void>;
}
interface IonAvatar {
}
Expand Down Expand Up @@ -2358,19 +2359,23 @@ export namespace Components {
}
interface IonSelectPopover {
/**
* Header text for the popover
* The header text of the popover
*/
"header"?: string;
/**
* Text for popover body
* The text content of the popover body
*/
"message"?: string;
/**
* Array of options for the popover
* If true, the select accepts multiple values
*/
"multiple"?: boolean;
/**
* An array of options for the popover
*/
"options": SelectPopoverOption[];
/**
* Subheader text for the popover
* The subheader text of the popover
*/
"subHeader"?: string;
}
Expand Down Expand Up @@ -5946,19 +5951,23 @@ declare namespace LocalJSX {
}
interface IonSelectPopover {
/**
* Header text for the popover
* The header text of the popover
*/
"header"?: string;
/**
* Text for popover body
* The text content of the popover body
*/
"message"?: string;
/**
* Array of options for the popover
* If true, the select accepts multiple values
*/
"multiple"?: boolean;
/**
* An array of options for the popover
*/
"options"?: SelectPopoverOption[];
/**
* Subheader text for the popover
* The subheader text of the popover
*/
"subHeader"?: string;
}
Expand Down
23 changes: 21 additions & 2 deletions core/src/components/app/app.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Build, Component, ComponentInterface, Element, Host, h } from '@stencil/core';
import { Build, Component, ComponentInterface, Element, Host, Method, h } from '@stencil/core';

import { config } from '../../global/config';
import { getIonMode } from '../../global/ionic-global';
Expand All @@ -9,6 +9,8 @@ import { isPlatform } from '../../utils/platform';
styleUrl: 'app.scss',
})
export class App implements ComponentInterface {
private focusVisible?: any;

@Element() el!: HTMLElement;

componentDidLoad() {
Expand All @@ -33,11 +35,28 @@ export class App implements ComponentInterface {
if (typeof (window as any) !== 'undefined') {
import('../../utils/keyboard/keyboard').then(module => module.startKeyboardAssist(window));
}
import('../../utils/focus-visible').then(module => module.startFocusVisible());
import('../../utils/focus-visible').then(module => this.focusVisible = module.startFocusVisible());
});
}
}

/**
* @internal
* Used to set focus on an element that uses `ion-focusable`.
* Do not use this if focusing the element as a result of a keyboard
* event as the focus utility should handle this for us. This method
* should be used when we want to programmatically focus an element as
* a result of another user action. (Ex: We focus the first element
* inside of a popover when the user presents it, but the popover is not always
* presented as a result of keyboard action.)
*/
@Method()
async setFocus(elements: HTMLElement[]) {
if (this.focusVisible) {
this.focusVisible.setFocus(elements);
}
}

render() {
const mode = getIonMode(this);
return (
Expand Down
13 changes: 13 additions & 0 deletions core/src/components/checkbox/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,19 @@ export default defineComponent({
| `--transition` | Transition of the checkbox icon |


## Dependencies

### Used by

- ion-select-popover

### Graph
```mermaid
graph TD;
ion-select-popover --> ion-checkbox
style ion-checkbox fill:#f9f,stroke:#333,stroke-width:4px
```

----------------------------------------------

*Built with [StencilJS](https://stenciljs.com/)*
2 changes: 1 addition & 1 deletion core/src/components/datetime/datetime.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ export class Datetime implements ComponentInterface {
}

connectedCallback() {
this.clearFocusVisible = startFocusVisible(this.el);
this.clearFocusVisible = startFocusVisible(this.el).destroy;
}

disconnectedCallback() {
Expand Down
1 change: 1 addition & 0 deletions core/src/components/item/item.ios.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
--highlight-color-valid: #{$item-ios-input-highlight-color-valid};
--highlight-color-invalid: #{$item-ios-input-highlight-color-invalid};
--bottom-padding-start: 0px;

font-size: $item-ios-font-size;
}

Expand Down
38 changes: 26 additions & 12 deletions core/src/components/item/item.md.scss
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
transition: none;
}

:host(.item-fill-outline.ion-focused) .item-native,
:host(.item-fill-outline.item-has-focus) .item-native {
border-color: transparent;
}
Expand Down Expand Up @@ -308,6 +309,8 @@
--padding-start: 0;
}

:host(.ion-focused:not(.ion-color)) ::slotted(.label-stacked),
:host(.ion-focused:not(.ion-color)) ::slotted(.label-floating),
:host(.item-has-focus:not(.ion-color)) ::slotted(.label-stacked),
:host(.item-has-focus:not(.ion-color)) ::slotted(.label-floating) {
color: $label-md-text-color-focused;
Expand Down Expand Up @@ -347,24 +350,31 @@
--border-color: #{$item-md-input-fill-border-color};
}

:host(.item-fill-solid) .item-native:hover {
--background: var(--background-hover);
--border-color: #{$item-md-input-fill-border-color-hover};
}

:host(.item-fill-solid.ion-focused) .item-native,
:host(.item-fill-solid.item-has-focus) .item-native {
--background: var(--background-focused);

border-bottom-color: var(--highlight-color-focused);
}

:host(.item-fill-solid.item-shape-round) {
@include border-radius(16px, 16px, 0, 0);
}

@media (any-hover: hover) {
:host(.item-fill-solid:hover) .item-native {
--background: var(--background-hover);
--border-color: #{$item-md-input-fill-border-color-hover};
}
}

// Material Design Item: Fill Outline
// --------------------------------------------------

:host(.item-fill-outline) {
--ripple-color: transparent;
--background-focused: transparent;
--background-hover: transparent;
--border-color: #{$item-md-input-fill-border-color};
--border-width: #{$item-md-border-bottom-width};

Expand All @@ -379,10 +389,6 @@
@include border-radius(4px);
}

:host(.item-fill-outline) .item-native:hover {
--border-color: #{$item-md-input-fill-border-color-hover};
}

:host(.item-fill-outline.item-shape-round) .item-native {
--inner-padding-start: 16px;

Expand All @@ -393,14 +399,22 @@
@include padding-horizontal(32px, null);
}


:host(.item-fill-outline.item-label-floating.ion-focused) .item-native ::slotted(ion-input:not(:first-child)),
:host(.item-fill-outline.item-label-floating.ion-focused) .item-native ::slotted(ion-textarea:not(:first-child)),
:host(.item-fill-outline.item-label-floating.item-has-focus) .item-native ::slotted(ion-input:not(:first-child)),
:host(.item-fill-outline.item-label-floating.item-has-focus) .item-native ::slotted(ion-textarea:not(:first-child)),
:host(.item-fill-outline.item-label-floating.item-has-value) .item-native ::slotted(ion-input:not(:first-child)),
:host(.item-fill-outline.item-label-floating.item-has-focus) .item-native ::slotted(ion-textarea:not(:first-child)),
:host(.item-fill-outline.item-label-floating.item-has-value) .item-native ::slotted(ion-textarea:not(:first-child)) {
transform: translateY(-25%);
}

@media (any-hover: hover) {
:host(.item-fill-outline:hover) .item-native {
--border-color: #{$item-md-input-fill-border-color-hover};
}
}


// Material Design Item: Invalid
// --------------------------------------------------

Expand All @@ -416,4 +430,4 @@
:host(.item-fill-solid.ion-invalid:not(.ion-color)) .item-native,
:host(.item-fill-solid.ion-invalid:not(.ion-color)) .item-highlight {
border-color: var(--highlight-color-invalid);
}
}
22 changes: 18 additions & 4 deletions core/src/components/item/item.scss
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@
// --------------------------------------------------

@media (any-hover: hover) {
:host(.ion-activatable:hover) .item-native {
:host(.ion-activatable:not(.ion-focused):hover) .item-native {
color: var(--color-hover);

&::after {
Expand All @@ -164,7 +164,7 @@
}
}

:host(.ion-color.ion-activatable:hover) .item-native {
:host(.ion-color.ion-activatable:not(.ion-focused):hover) .item-native {
color: #{current-color(contrast)};

&::after {
Expand All @@ -173,6 +173,7 @@
}
}


// Item: Disabled
// --------------------------------------------------

Expand Down Expand Up @@ -308,7 +309,11 @@ button, a {
z-index: 1;
}

// Setting pointer-events to none allows the label
// to be clicked to open the select interface
::slotted(ion-label) {
pointer-events: none;

flex: 1;
}

Expand Down Expand Up @@ -359,7 +364,7 @@ button, a {
width: 100%;

height: 100%;

transform: scaleX(0);

transition: transform 200ms, border-bottom-width 200ms;
Expand All @@ -370,6 +375,8 @@ button, a {
pointer-events: none;
}

:host(.ion-focused) .item-highlight,
:host(.ion-focused) .item-inner-highlight,
:host(.item-has-focus) .item-highlight,
:host(.item-has-focus) .item-inner-highlight {
transform: scaleX(1);
Expand All @@ -378,22 +385,27 @@ button, a {
border-color: var(--highlight-background);
}

:host(.ion-focused) .item-highlight,
:host(.item-has-focus) .item-highlight {
border-width: var(--full-highlight-height);

opacity: var(--show-full-highlight);
}

:host(.ion-focused) .item-inner-highlight,
:host(.item-has-focus) .item-inner-highlight {
border-bottom-width: var(--inset-highlight-height);

opacity: var(--show-inset-highlight);
}

:host(.ion-focused.item-fill-solid) .item-highlight,
:host(.item-has-focus.item-fill-solid) .item-highlight {
border-width: calc(var(--full-highlight-height) - 1px);
}

:host(.ion-focused) .item-inner-highlight,
:host(.ion-focused:not(.item-fill-outline)) .item-highlight,
:host(.item-has-focus) .item-inner-highlight,
:host(.item-has-focus:not(.item-fill-outline)) .item-highlight {
border-top: none;
Expand All @@ -405,6 +417,7 @@ button, a {
// Item Input Focused
// --------------------------------------------------

:host(.item-interactive.ion-focused),
:host(.item-interactive.item-has-focus),
:host(.item-interactive.ion-touched.ion-invalid) {
// If the item has a full border and highlight is enabled, show the full item highlight
Expand All @@ -417,6 +430,7 @@ button, a {
// Item Input Focus
// --------------------------------------------------

:host(.item-interactive.ion-focused),
:host(.item-interactive.item-has-focus) {
--highlight-background: var(--highlight-color-focused);
}
Expand Down Expand Up @@ -553,4 +567,4 @@ ion-ripple-effect {
display: none;

color: var(--highlight-color-invalid);
}
}
Loading

0 comments on commit 2c07a15

Please sign in to comment.