From 0d749923a84eef3568c9a2b2be89b1efa1c199aa Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Wed, 24 Nov 2021 11:43:32 -0500 Subject: [PATCH] docs(popover): add popover examples (#24267) resolves #24266 --- core/src/components/popover/readme.md | 653 +++++++++++++++--- core/src/components/popover/usage/angular.md | 98 +++ .../components/popover/usage/javascript.md | 78 +++ core/src/components/popover/usage/react.md | 155 ++++- core/src/components/popover/usage/stencil.md | 118 ++++ core/src/components/popover/usage/vue.md | 164 ++++- 6 files changed, 1085 insertions(+), 181 deletions(-) diff --git a/core/src/components/popover/readme.md b/core/src/components/popover/readme.md index e3bbe46717..fa6d5ce2db 100644 --- a/core/src/components/popover/readme.md +++ b/core/src/components/popover/readme.md @@ -37,53 +37,19 @@ If you need fine grained control over when the popover is presented and dismisse We typically recommend that you write your popovers inline as it streamlines the amount of code in your application. You should only use the `popoverController` for complex use cases where writing a popover inline is impractical. When using a controller, your popover is not created ahead of time, so properties such as `trigger` and `trigger-action` are not applicable here. In addition, nested popovers are not compatible with the controller approach because the popover is automatically added to the root of your application when the `create` method is called. -## Customization +## Styling -Popover uses scoped encapsulation, which means it will automatically scope its CSS by appending each of the styles with an additional class at runtime. Overriding scoped selectors in CSS requires a [higher specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity) selector. - -We recommend setting a custom class on the host element if writing a popover inline or supplying a class to the `cssClass` option if using the `popoverController` and using that to add custom styles to the host and inner elements. The `cssClass` option can also accept multiple classes separated by spaces. View the [Usage](#usage) section for an example of how to pass a class using `cssClass`. - -```css -/* DOES NOT WORK - not specific enough */ -.popover-content { - background: #222; -} - -/* Works - pass "my-custom-class" in cssClass to increase specificity */ -.my-custom-class .popover-content { - background: #222; -} -``` - -Any of the defined [CSS Custom Properties](#css-custom-properties) can be used to style the Popover without needing to target individual elements: - -```css -.my-custom-class { - --background: #222; -} -``` +Popovers are presented at the root of your application so they overlay your entire app. This behavior applies to both inline popovers and popovers presented from a controller. As a result, custom popover styles can not be scoped to a particular component as they will not apply to the popover. Instead, styles must be applied globally. For most developers, placing the custom styles in `global.css` is sufficient. > If you are building an Ionic Angular app, the styles need to be added to a global stylesheet file. Read [Style Placement](#style-placement) in the Angular section below for more information. + ## Triggers -A trigger for an `ion-popover` is the element that will open a popover when interacted with. The interaction behavior can be customized by setting the `trigger-action` property. The following example shows how to create a right click menu using `trigger` and `trigger-action`. Note that `trigger-action="context-menu"` will prevent your system's default context menu from opening. - -```html -Right click me! - - - - ... - - - -``` +A trigger for an `ion-popover` is the element that will open a popover when interacted with. The interaction behavior can be customized by setting the `trigger-action` property. Note that `trigger-action="context-menu"` will prevent your system's default context menu from opening. View the [Usage](#usage) section for an example of how to use triggers. > Triggers are not applicable when using the `popoverController` because the `ion-popover` is not created ahead of time. + ## Positioning ### Reference @@ -195,6 +161,104 @@ type PositionAlign = 'start' | 'center' | 'end'; ### Angular +### Inline Popover + +```html + + + + Popover Content + + + + + + + Popover Content + + + + +Click to open popover + + + Popover Content + + + + +Hover to open popover + + + Popover Content + + + + +Click to open popover + + + Popover Content + + + + +Click to open popover + + + Popover Content + + + + +Click to open popover + + + Popover Content + + + + +Click to open popover + + + Popover Content + + + + +Click to open popover + + + + + + Option 1 + + + Option 2 + + + Option 3 + + + + + + + Nested Option + + + + + + + + +``` + +### Popover Controller + ```typescript import { Component } from '@angular/core'; import { PopoverController } from '@ionic/angular'; @@ -231,6 +295,84 @@ In Angular, the CSS of a specific page is scoped only to elements of that page. ### Javascript +### Inline Popover + +```html + + + Popover Content + + + + + Popover Content + + + +Click to open popover + + Popover Content + + + +Hover to open popover + + Popover Content + + + +Click to open popover + + Popover Content + + + +Click to open popover + + Popover Content + + + +Click to open popover + + Popover Content + + + +Click to open popover + + Popover Content + + + +Click to open popover + + + + + Option 1 + + + Option 2 + + + Option 3 + + + + + + Nested Option + + + + + + +``` + +### Using JavaScript + ```javascript class PopoverExamplePage extends HTMLElement { constructor() { @@ -273,11 +415,128 @@ async function presentPopover(ev) { ### React +### Inline Popover + +```tsx +import React, { useState } from 'react'; +import { IonPopover, IonContent, IonItem, IonLabel, IonButton } from '@ionic/react'; + +export const PopoverExample: React.FC = () => { + return ( + <> + {/* Default */} + + Popover Content + + + {/* No Arrow */} + + Popover Content + + + {/* Use a trigger */} + Click to open popover + + Popover Content + + + {/* Hover over trigger to open */} + Hover to open popover + + Popover Content + + + {/* Show popover above trigger */} + Click to open popover + + Popover Content + + + {/* Align popover to end of trigger */} + Click to open popover + + Popover Content + + + {/* Make popover the same size as the trigger */} + Click to open popover + + Popover Content + + + {/* Make popover show relative to click coordinates rather than trigger */} + Click to open popover + + Popover Content + + + {/* Nested Popover */} + Click to open popover + + + + + Option 1 + + + Option 2 + + + Option 3 + + + + + + Nested Option + + + + + + + + ); +}; +``` + +### Inline Popover with State + +```tsx +import React, { useState } from 'react'; +import { IonPopover, IonButton } from '@ionic/react'; + +export const PopoverExample: React.FC = () => { + const [popoverState, setShowPopover] = useState({ showPopover: false, event: undefined }); + + return ( + <> + setShowPopover({ showPopover: false, event: undefined })} + > +

This is popover content

+
+ { + e.persist(); + setShowPopover({ showPopover: true, event: e }) + }} + > + Show Popover + + + ); +}; +``` + +### useIonPopover Hook + > `useIonPopover` requires being a descendant of ``. If you need to use a popover outside of an ``, consider using the component method instead. ```tsx -/* Using with useIonPopover Hook */ - import React from 'react'; import { IonButton, @@ -326,41 +585,127 @@ const PopoverExample: React.FC = () => { }; ``` -```tsx -/* Using with IonPopover Component */ - -import React, { useState } from 'react'; -import { IonPopover, IonButton } from '@ionic/react'; - -export const PopoverExample: React.FC = () => { - const [popoverState, setShowPopover] = useState({ showPopover: false, event: undefined }); - - return ( - <> - setShowPopover({ showPopover: false, event: undefined })} - > -

This is popover content

-
- { - e.persist(); - setShowPopover({ showPopover: true, event: e }) - }} - > - Show Popover - - - ); -}; -``` - ### Stencil +### Inline Popover + +```tsx +import { Component, h } from '@stencil/core'; + +@Component({ + tag: 'popover-example', + styleUrl: 'popover-example.css' +}) +export class PopoverExample { + render() { + return [ + + {/* Default */} + + Popover Content + + + {/* No Arrow */} + + Popover Content + + + {/* Use a trigger */} + Click to open popover + + Popover Content + + + {/* Hover over trigger to open */} + Hover to open popover + + Popover Content + + + {/* Show popover above trigger */} + Click to open popover + + Popover Content + + + {/* Align popover to end of trigger */} + Click to open popover + + Popover Content + + + {/* Make popover the same size as the trigger */} + Click to open popover + + Popover Content + + + {/* Make popover show relative to click coordinates rather than trigger */} + Click to open popover + + Popover Content + + + {/* Nested Popover */} + Click to open popover + + + + + Option 1 + + + Option 2 + + + Option 3 + + + + + + Nested Option + + + + + + + + ]; + } +} +``` + +```tsx +import { Component, h } from '@stencil/core'; + +@Component({ + tag: 'page-popover', + styleUrl: 'page-popover.css', +}) +export class PagePopover { + render() { + return [ + + + Documentation + + + Feedback + + + Settings + + + ]; + } +} +``` + +### Popover Controller + ```tsx import { Component, h } from '@stencil/core'; @@ -423,6 +768,132 @@ export class PagePopover { ### Vue +### Inline Popover + +```html + + + +``` + + +### Inline Popover with State + +```html + + + +``` + +### Popover Controller + ```html