Skip to content

feat(select): allow multiple selections in popover interface, ui updates #23474

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

Merged
merged 30 commits into from
Jul 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1f9a673
feat(select): allow multiple value select with popover interface
brandyscarney Oct 12, 2020
7e59743
fix(select-popover): allow number comparison
brandyscarney Oct 12, 2020
69161e4
chore: remove await
brandyscarney Oct 12, 2020
e619262
fix(select): update popover interface for MD spec
brandyscarney Oct 12, 2020
0f55bfa
chore: remove unused code, code cleanup
brandyscarney Oct 12, 2020
1bf4f72
Merge branch 'master' into feat-select-popover-multiple
brandyscarney Nov 30, 2020
341aa4d
Merge branch 'next' into feat-select-popover-multiple
brandyscarney Jun 21, 2021
a77c57b
fix(tap-click): call pointerUp to remove ripple when right clicking
brandyscarney Jun 29, 2021
ebda440
fix(select-popover): style updates and checking proper radio
brandyscarney Jun 29, 2021
8b29b98
fix(select): hide backdrop on md, set size to cover
brandyscarney Jun 29, 2021
3dddb6d
test(select): add spec test for new popover styles
brandyscarney Jun 29, 2021
20ef74f
test(select): test updates
brandyscarney Jun 30, 2021
eb6f93b
fix(item): move label and highlight item when focused with tab
brandyscarney Jun 30, 2021
70f14bb
fix(select): design updates to match spec and cover on popover
brandyscarney Jun 30, 2021
c544f70
Merge branch 'next' into feat-select-popover-multiple
brandyscarney Jun 30, 2021
630cf84
fix(select-popover): padding should be in md
brandyscarney Jun 30, 2021
2df47cb
fix(popover): ignore body padding when the size is cover
brandyscarney Jul 6, 2021
4eaf809
fix(select): highlight and rotate dropdown arrow for other labels
brandyscarney Jul 6, 2021
a11e698
Merge branch 'next' into feat-select-popover-multiple
brandyscarney Jul 6, 2021
f3df2f8
style: lint
brandyscarney Jul 6, 2021
afbadd6
fix margin with ios cover popover
liamdebeasi Jul 9, 2021
a161e8e
arrow rotation is now correct
liamdebeasi Jul 19, 2021
1b817de
fix alignment for other selects
liamdebeasi Jul 19, 2021
9663413
ensure select is adjusted for floating label
liamdebeasi Jul 19, 2021
34f045f
arrow is now positioned correctly with stacked labels
liamdebeasi Jul 19, 2021
e08a65f
lint
liamdebeasi Jul 19, 2021
9132706
improve arrow positioning logic
liamdebeasi Jul 19, 2021
8be9ae1
pass focus
liamdebeasi Jul 20, 2021
4c2739d
update test
liamdebeasi Jul 20, 2021
f47e203
improve readability
liamdebeasi Jul 20, 2021
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
25 changes: 17 additions & 8 deletions core/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ export namespace Components {
"translucent": boolean;
}
interface IonApp {
"setFocus": (elements: HTMLElement[]) => Promise<void>;
}
interface IonAvatar {
}
Expand Down Expand Up @@ -2349,19 +2350,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 @@ -5929,19 +5934,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 @@ -747,7 +747,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