Skip to content
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

New theme: Corner layout #40

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
69e2847
feat(theme): add corner theme
vandangnhathung Nov 18, 2024
39e9d3f
feat(theme): update "corner" theme, style & turn off preventScroll
vandangnhathung Nov 19, 2024
fa5c1b1
style(close-button): make the button be sticky with fixed position
vandangnhathung Dec 26, 2024
7754a46
refactor(close-button): move easy-popup-master-corner div into easy p…
vandangnhathung Dec 26, 2024
7719cb6
refactor(close-button): refactor CSS
vandangnhathung Dec 26, 2024
1966be8
refactor(close-button): refactor CSS
vandangnhathung Dec 26, 2024
495ffec
refactor: add comment and avoid returning all the function
vandangnhathung Dec 26, 2024
ef0153b
refactor: use isCornerTheme as global variable
vandangnhathung Dec 26, 2024
bdef612
refactor(corner-theme): show warning if user input wrong position value
vandangnhathung Dec 26, 2024
00f39f4
refactor(corner-theme): use CLASSES.cornerMaster instead of CLASSES.m…
vandangnhathung Dec 26, 2024
a9725cc
refactor(corner-theme): return default position value if the position…
vandangnhathung Dec 26, 2024
685ae4c
refactor(corner-theme): rename global variable
vandangnhathung Dec 26, 2024
dbe4d73
refactor(corner-theme): refactor js
vandangnhathung Dec 26, 2024
f1cb189
refactor(corner-theme): add comment
vandangnhathung Dec 26, 2024
ffe697f
refactor(corner-theme): add comment
vandangnhathung Dec 26, 2024
a6c8f7e
refactor(corner-theme): rename "position" to "cornerPosition"
vandangnhathung Dec 26, 2024
69aa105
feat(html): update structure html
phucbm Dec 26, 2024
796424a
feat(html): allow click outside to close
phucbm Dec 26, 2024
31adad1
refactor(corner-theme): clean up css (not done yet)
vandangnhathung Dec 26, 2024
92a894e
refactor: convert css to scss
vandangnhathung Dec 30, 2024
e21c929
refactor: refactor scss
vandangnhathung Dec 30, 2024
310d87b
refactor: refactor scss
vandangnhathung Dec 30, 2024
8bf7168
refactor(html): add comment, rename var
phucbm Dec 31, 2024
e4a0198
refactor(corner-theme): revise code
vandangnhathung Jan 14, 2025
580c238
refactor(corner-theme): add cornerFade layout
vandangnhathung Jan 14, 2025
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
71 changes: 66 additions & 5 deletions dev/md/layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

Layout could be customized with these provided options.

| Description | Option | Buttons |
|--|--|--|
| Use custom layout on mobile | `hasMobileLayout: true` | [View popup](#popup-mobile) |
| Display popup on the right side | `theme: "right-side"` | [View popup](#popup-right-side) |
| Change the close button text | `closeButtonInnerText: "CLOSE"` | [View popup](#popup-custom-close) |
| Description | Option | Buttons |
|---------------------------------|---------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Use custom layout on mobile | `hasMobileLayout: true` | [View popup](#popup-mobile) |
| Display popup on the right side | `theme: "right-side"` | [View popup](#popup-right-side) |
| Change the close button text | `closeButtonInnerText: "CLOSE"` | [View popup](#popup-custom-close) |
| Display the popup in the corner | `theme: "corner"` | [Bottom right](#popup-corner-bottom-right) - [Bottom left](#popup-corner-bottom-left) - [Top right](#popup-corner-top-right) - [Top left](#popup-corner-top-left) |

<div data-easy-popup='{"id": "popup-mobile", "hasMobileLayout": "true"}'>
<!-- Popup content -->
Expand Down Expand Up @@ -75,6 +76,66 @@ nostra lorem libero curabitur.
</p>
</div>

<div data-easy-popup='{"id": "popup-corner-bottom-right", "theme": "corner" }'>
<!-- Popup content -->
<h2>Ac lectus interdum auctor praesent quis</h2>
<p>Elementum sollicitudin pharetra nascetur purus risus bibendum arcu fermentum vestibulum diam consequat. Senectus nam
sodales ridiculus torquent et natoque commodo placerat adipiscing. Elementum donec faucibus nulla viverra letius porta
sit. Tempor finibus si mi dictum molestie id pede hac proin curae. Vestibulum tortor parturient interdum litora
adipiscing morbi lobortis bibendum aliquet platea sed. Velit fames ultricies tincidunt netus lectus lacinia nullam
congue cubilia cursus.</p>
</div>

<div data-easy-popup='{"id": "popup-corner-bottom-left", "theme": "corner", "cornerPosition":"bottom left " }'>
<!-- Popup content -->
<h2>Ac lectus interdum auctor praesent quis</h2>
<p>Elementum sollicitudin pharetra nascetur purus risus bibendum arcu fermentum vestibulum diam consequat. Senectus nam
sodales ridiculus torquent et natoque commodo placerat adipiscing. Elementum donec faucibus nulla viverra letius porta
sit. Tempor finibus si mi dictum molestie id pede hac proin curae. Vestibulum tortor parturient interdum litora
adipiscing morbi lobortis bibendum aliquet platea sed. Velit fames ultricies tincidunt netus lectus lacinia nullam
congue cubilia cursus.</p>
</div>

<div data-easy-popup='{"id": "popup-corner-top-right", "theme": "corner", "cornerPosition":"top right" }'>
<!-- Popup content -->
<h2>Ac lectus interdum auctor praesent quis</h2>
<p>Elementum sollicitudin pharetra nascetur purus risus bibendum arcu fermentum vestibulum diam consequat. Senectus nam
sodales ridiculus torquent et natoque commodo placerat adipiscing. Elementum donec faucibus nulla viverra letius porta
sit. Tempor finibus si mi dictum molestie id pede hac proin curae. Vestibulum tortor parturient interdum litora
adipiscing morbi lobortis bibendum aliquet platea sed. Velit fames ultricies tincidunt netus lectus lacinia nullam
congue cubilia cursus.</p>
</div>

<div data-easy-popup='{"id": "popup-corner-top-left", "theme": "corner", "cornerPosition":"top left","closeButtonInnerText": "CLOSE" }'>
<!-- Popup content -->
<h2>Ac lectus interdum auctor praesent quis</h2>
<p>Elementum sollicitudin pharetra nascetur purus risus bibendum arcu fermentum vestibulum diam consequat. Senectus nam
sodales ridiculus torquent et natoque commodo placerat adipiscing. Elementum donec faucibus nulla viverra letius porta
sit. Tempor finibus si mi dictum molestie id pede hac proin curae. Vestibulum tortor parturient interdum litora
adipiscing morbi lobortis bibendum aliquet platea sed. Velit fames ultricies tincidunt netus lectus lacinia nullam
congue cubilia cursus.</p>
<p>Elementum sollicitudin pharetra nascetur purus risus bibendum arcu fermentum vestibulum diam consequat. Senectus nam
sodales ridiculus torquent et natoque commodo placerat adipiscing. Elementum donec faucibus nulla viverra letius porta
sit. Tempor finibus si mi dictum molestie id pede hac proin curae. Vestibulum tortor parturient interdum litora
adipiscing morbi lobortis bibendum aliquet platea sed. Velit fames ultricies tincidunt netus lectus lacinia nullam
congue cubilia cursus.</p>
<p>Elementum sollicitudin pharetra nascetur purus risus bibendum arcu fermentum vestibulum diam consequat. Senectus nam
sodales ridiculus torquent et natoque commodo placerat adipiscing. Elementum donec faucibus nulla viverra letius porta
sit. Tempor finibus si mi dictum molestie id pede hac proin curae. Vestibulum tortor parturient interdum litora
adipiscing morbi lobortis bibendum aliquet platea sed. Velit fames ultricies tincidunt netus lectus lacinia nullam
congue cubilia cursus.</p>
<p>Elementum sollicitudin pharetra nascetur purus risus bibendum arcu fermentum vestibulum diam consequat. Senectus nam
sodales ridiculus torquent et natoque commodo placerat adipiscing. Elementum donec faucibus nulla viverra letius porta
sit. Tempor finibus si mi dictum molestie id pede hac proin curae. Vestibulum tortor parturient interdum litora
adipiscing morbi lobortis bibendum aliquet platea sed. Velit fames ultricies tincidunt netus lectus lacinia nullam
congue cubilia cursus.</p>
<p>Elementum sollicitudin pharetra nascetur purus risus bibendum arcu fermentum vestibulum diam consequat. Senectus nam
sodales ridiculus torquent et natoque commodo placerat adipiscing. Elementum donec faucibus nulla viverra letius porta
sit. Tempor finibus si mi dictum molestie id pede hac proin curae. Vestibulum tortor parturient interdum litora
adipiscing morbi lobortis bibendum aliquet platea sed. Velit fames ultricies tincidunt netus lectus lacinia nullam
congue cubilia cursus.</p>
</div>

<div data-easy-popup='{"id": "popup-custom-close", "closeButtonInnerText": "CLOSE"}'>
<!-- Popup content -->
<h2>Ac lectus interdum auctor praesent quis</h2>
Expand Down
3 changes: 2 additions & 1 deletion dev/md/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
| Attribute | Type | Default | Description |
|------------------------|------------------------|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `id` | string | Auto-generated ID | Set an ID for this popup |
| `theme` | string | `default` | Other layouts: `right-side` |
| `theme` | string | `default` | Other layouts: `right-side`, `corner` |
| `cornerPosition` | string | `bottom right` | Requires `theme: "corner"`. Allowed values: `top left`, `top right`, `bottom left`, `bottom right` |
| `hasMobileLayout` | boolean | `false` | Enable mobile layout (`theme` options will not work when mobile layout is active) |
| `mobileBreakpoint` | number | `768` | Activate mobile layout when the screen size is <=768px |
| `closeButtonInnerText` | string | `svg/icon` | Custom `innerText` of the close button |
Expand Down
10 changes: 10 additions & 0 deletions src/_index.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ class Popup{

/** ------ **/

/** THEMES **/

// corner theme
this.isCornerTheme = this.options.theme === 'corner';


/** COOKIE **/

// cookie
Expand Down Expand Up @@ -137,6 +143,10 @@ class Popup{

// prevent scroll > on
if(this.options.preventScroll){

// "corner" theme will not prevent scroll
if(this.isCornerTheme) return;

if(this.lenis.enabled()){
// prevent with Lenis
this.root.classList.add(CLASSES.preventScrollLenis);
Expand Down
1 change: 1 addition & 0 deletions src/_style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
@import "./css/close-button";
@import "./css/theme-right-side";
@import "./css/layout-mobile";
@import "./css/corner-layout";


/* prevent scroll */
Expand Down
7 changes: 6 additions & 1 deletion src/configs.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const CLASSES = {
hasCustomClose: 'ep-has-custom-close-button',
preventScroll: 'ep-prevent-scroll',
preventScrollLenis: 'ep-prevent-scroll-lenis',
cornerMaster: 'easy-popup-master-corner',
};
/**
* Attributes
Expand Down Expand Up @@ -50,6 +51,8 @@ export const DEFAULTS = {

// theme
theme: 'default', // right-side
cornerPosition: 'bottom right', // position of the popup, e.g. 'top left', 'top right', 'bottom left', 'bottom right'
cornerFade: false, // fade effect

keyboard: true, // option for closing the popup by keyboard (ESC)

Expand All @@ -64,4 +67,6 @@ export const DEFAULTS = {
preventScroll: true, // prevent page scroll when popup is open
scrollbarWidth: undefined, // px, set the scrollbar width manually to avoid page jumping when open a popup, only works for preventScroll:true
}
export const CLOSE_SVG = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>';
export const CLOSE_SVG = '<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>';

export const CORNER_POSITIONS = ['top left', 'top right', 'bottom left', 'bottom right'];
100 changes: 100 additions & 0 deletions src/css/corner-layout.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Base styles
html.easy-popup-open {
&:has(.easy-popup-master-corner.open) {
.easy-popup-master {
opacity: 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to hide .easy-popup-master here?

visibility: hidden;
}
}
}

.easy-popup-master-corner {
transition: opacity 0.4s ease, transform 0.4s ease;
transform: translateX(0);
position: fixed;
bottom: 0;
right: 0;
max-width: 450px;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please note that we are using the library for multiple purposes. So make it as flexible as you can, the max-width here needs to havea CSS variable for better control.

opacity: 1;
visibility: visible;
top: unset;
left: unset;
height: unset;
width: unset;
display: block;

&:not(.open) {
pointer-events: none;
}

.ep-close-button {
position: fixed;
transform: translate(0);
--ep-close-color: #000;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you override this variable here? CSS override should use the same selector when possible.

}

.easy-popup-overflow {
overflow: unset;
}

.easy-popup-container {
padding: 0;

.easy-popup-inner {
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
border-radius: var(--ep-radius);
overflow: hidden;
max-height: calc(100vh - (var(--ep-corner-offset) * 2));
overflow-y: auto;
}
}

// Position variants
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do some positions have all top left bottom right properties, while some do not?

&.top-left {
top: var(--ep-corner-offset);
left: var(--ep-corner-offset);
bottom: unset;
right: unset;
}

&.top-right {
top: var(--ep-corner-offset);
right: var(--ep-corner-offset);
bottom: unset;
}

&.bottom-left {
bottom: var(--ep-corner-offset);
left: var(--ep-corner-offset);
right: unset;
}

&.bottom-right {
bottom: var(--ep-corner-offset);
right: var(--ep-corner-offset);
}

@media only screen and (max-width: 768px) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this breakpoint be consistent with the mobile layout here

@media only screen and (max-width: 1023px) {
?

--ep-corner-offset: 0px;
--ep-padding: 15px;
padding: var(--ep-padding);

.ep-close-button {
top: var(--ep-padding);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know the purpose of --ep-padding? Just because they need the same value, doesn't mean they should share the same variable.

right: var(--ep-padding);
}

.easy-popup-container .easy-popup-inner {
max-height: calc(100vh - (var(--ep-padding) * 2));
}
}

// Slide animations
&[class*="right"]:not(.open) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[class*="right"] and [class*="right"] are very risky and less accurate selectors. You should create class is-slide-rlt and is-slide-ltr for this case.

transform: translateX(100%);
}

&[class*="left"]:not(.open) {
transform: translateX(-100%);
}
}
17 changes: 10 additions & 7 deletions src/css/master.scss
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
/* master */
html:not(.easy-popup-open) .easy-popup-master {
opacity: 0;
visibility: hidden;
}

.easy-popup-master {
:root {
--ep-bg: rgba(0, 0, 0, .4);
--ep-padding: clamp(20px, 2vw, 40px);
--ep-max-width: 915px;
--ep-radius: 10px;
--ep-close-width: 40px;
--ep-close-color: #fff;
--ep-close-color-hover: #ef1616;
--ep-corner-offset: 20px;

--ep-popup-bg: #fff;
}

/* master */
html:not(.easy-popup-open) .easy-popup-master {
opacity: 0;
visibility: hidden;
}

.easy-popup-master {
position: fixed;
top: 0;
left: 0;
Expand Down
17 changes: 15 additions & 2 deletions src/html.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ export function generateHTML(context){
// check flag
if(context.el.classList.contains(CLASSES.processed)) return;

/** HTML **/
// relocate HTML to body tag
if(!context.masterContainer){
context.masterContainer = document.createElement('div');
context.masterContainer.classList.add(CLASSES.master);

document.querySelector('body').appendChild(context.masterContainer);
}
document.querySelector('body').appendChild(context.masterContainer);
context.masterContainer.appendChild(context.el);

// inner
context.inner = wrapElement(context.el);
Expand All @@ -37,6 +38,18 @@ export function generateHTML(context){
}
context.outer.setAttribute(ATTRS.id, context.id);


if(context.isCornerTheme){
// corner theme
context.outer.classList.add(CLASSES.cornerMaster);
document.querySelector('body').appendChild(context.outer);
}else{
// normal theme
context.masterContainer.appendChild(context.outer);
}


/** Init **/
initOutsideClick(context);
initKeyboard(context);
initTheme(context);
Expand Down
21 changes: 20 additions & 1 deletion src/layouts.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {MatchMediaScreen} from "match-media-screen";
import {ATTRS, CLASSES, CLOSE_SVG} from "./configs";
import {ATTRS, CLASSES, CLOSE_SVG, CORNER_POSITIONS, DEFAULTS} from "./configs";

/**
* Set up mobile layout
Expand Down Expand Up @@ -57,6 +57,25 @@ function setTheme(context, removeTheme = false){

// set theme
context.outer.setAttribute(ATTRS.theme, context.options.theme);

// add theme position class
if(context.isCornerTheme){
let inputPosition = context.options.cornerPosition.trim();
const isExistPosition = CORNER_POSITIONS.includes(inputPosition);

// throw warning and set default value if the position is not valid
if(!isExistPosition){
console.warn(`"${inputPosition}" is not a valid position for corner theme. Must be one of these: ${CORNER_POSITIONS.join(", ")}. Default position is used: ${DEFAULTS.cornerPosition}.`);
inputPosition = DEFAULTS.cornerPosition;
}

// update position value for instance
context.options.cornerPosition = inputPosition;

// add position class
const positionClass = inputPosition.split(" ").join("-");
context.outer.classList.add(positionClass);
}
}


Expand Down