Skip to content

Commit

Permalink
Merge pull request #1758 from Kajabi/develop
Browse files Browse the repository at this point in the history
Next Version Bump
  • Loading branch information
ju-Skinner authored Jul 7, 2023
2 parents 41c55b5 + 04f6fc5 commit b4398c7
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 53 deletions.
45 changes: 45 additions & 0 deletions packages/sage-assets/lib/stylesheets/components/_loader.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ $-loader-bar-width: rem(300px);
$-loader-spinner-size: rem(48px);
$-loader-spinner-speed: 2s;
$-loader-spinner-path-speed: 1.5s;
$-loader-typing-size: rem(6px);
$-loader-lower-opacity: 0.4;

.sage-loader {
&:not(.visually-hidden) {
Expand Down Expand Up @@ -164,3 +166,46 @@ $-loader-spinner-path-speed: 1.5s;
stroke-dashoffset: -124;
}
}

// TYPING LOADER
.sage-loader__typing {
display: flex;
align-items: center;
gap: sage-spacing(2xs);
position: relative;
margin: 0 auto;
padding: rem(15px) rem(20px);
background-color: sage-color(grey, 200);
will-change: transform;
border-radius: sage-border(radius-large);
box-shadow: sage-shadow(sm);

span {
height: $-loader-typing-size;
width: $-loader-typing-size;
background-color: sage-color(grey, 500);
border-radius: sage-border(radius-round);
opacity: $-loader-lower-opacity;

@for $i from 1 through 3 {
&:nth-of-type(#{$i}) {
animation: 1s typing infinite ($i * 0.3333s);
}
}
}
}

@keyframes typing {
0%,
25% {
transform: scale(1);
}
50% {
transform: scale(1.2);
opacity: 1;
}
100% {
transform: scale(1);
}
}

6 changes: 5 additions & 1 deletion packages/sage-assets/lib/stylesheets/components/_modal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ $-modal-inner-size: sage-container(md);
opacity: 1;
}

&.sage-modal--is-closing {
transition: opacity 0.15s ease-in-out;
opacity: 0;
}

&.sage-modal--fullscreen {
padding: 0;
}
Expand Down Expand Up @@ -95,7 +100,6 @@ $-modal-inner-size: sage-container(md);
@media (max-width: sage-breakpoint(md-min)) {
max-width: var(--sage-drawer-mobile-size);
}

}

.sage-drawer.sage-drawer--compact & {
Expand Down
4 changes: 4 additions & 0 deletions packages/sage-react/lib/Drawer/Drawer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const Drawer = ({
footer,
onExpandChange,
id,
isClosing,
onExit,
showClose,
size,
Expand Down Expand Up @@ -67,6 +68,7 @@ export const Drawer = ({
className={classNames}
disableBackgroundDismiss={disableBackgroundDismiss}
id={id}
isClosing={isClosing}
onExit={onExit}
styles={{ ...localStyles }}
style={{
Expand Down Expand Up @@ -121,6 +123,7 @@ Drawer.defaultProps = {
expanded: false,
expandedSize: null,
footer: null,
isClosing: false,
onExit: (val) => val,
onExpandChange: (expanded) => expanded,
showClose: true,
Expand All @@ -140,6 +143,7 @@ Drawer.propTypes = {
expandedSize: PropTypes.string,
footer: PropTypes.node,
id: PropTypes.string.isRequired,
isClosing: PropTypes.bool,
onExit: PropTypes.func,
onExpandChange: PropTypes.func,
showClose: PropTypes.bool,
Expand Down
14 changes: 12 additions & 2 deletions packages/sage-react/lib/Drawer/Drawer.story.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import { Drawer } from './Drawer';
import { SageClassnames, SageTokens } from '../configs';
import { Button } from '../Button';
Expand Down Expand Up @@ -96,6 +96,7 @@ export const WiredExample = () => {
const [drawerContents, setDrawerContents] = React.useState(null);
const [drawerActive, setDrawerActive] = React.useState(true);
const [drawerExpanded, setDrawerExpanded] = React.useState(false);
const [isClosing, setIsClosing] = useState(false);

const drawerCustomHeader = (
<Button
Expand Down Expand Up @@ -129,6 +130,14 @@ export const WiredExample = () => {
</>
);

const onExit = () => {
setIsClosing(true);
setTimeout(() => {
setDrawerActive(false);
setIsClosing(false);
}, 1000);
};

const respondToDrawerExpandChange = (status) => {
switch (status) {
case Drawer.END_EXPAND:
Expand Down Expand Up @@ -164,7 +173,8 @@ export const WiredExample = () => {
<Drawer
active={drawerActive}
expanded={drawerExpanded}
onExit={() => setDrawerActive(false)}
isClosing={isClosing}
onExit={onExit}
onExpandChange={respondToDrawerExpandChange}
customHeader={drawerCustomHeader}
disableBackgroundDismiss={!drawerExpanded}
Expand Down
84 changes: 36 additions & 48 deletions packages/sage-react/lib/Dropdown/Dropdown.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,21 +55,11 @@ export const Dropdown = ({
}
};

const setPanelCoords = () => {
const rect = wrapperRef.current.getBoundingClientRect();

updateCoords({
top: rect.bottom + topBoxOffset,
left: align !== 'right'
? rect.left + inlineBoxOffset
: 'intitial',
right: align === 'right'
? window.innerWidth - rect.right + inlineBoxOffset
: 'intitial',
});
const setPanelCoords = (coords) => {
updateCoords(coords);
};

const onUpdate = useCallback(debounce(() => setPanelCoords(), 20), []); // eslint-disable-line
const onUpdate = useCallback(debounce(() => positionElement(), 0), []); // eslint-disable-line

// NOTE: getHeight and positionElement must be kept in alignment
// with packages/sage-system/lib/dropdown.js since we don't
Expand All @@ -86,77 +76,75 @@ export const Dropdown = ({
return height - borderBottomWidth - borderTopWidth - paddingTop - paddingBottom;
};

const positionElement = (el) => {
const positionElement = () => {
let direction = null;

const el = wrapperRef.current;
// Elements
const button = el;
const panel = el.lastElementChild;
const win = panel.ownerDocument.defaultView;
const docEl = window.document.documentElement;

panel.style.top = ''; // resets the style

// Dimensions
const buttonDimensions = button.getBoundingClientRect();
const panelDimensions = panel.getBoundingClientRect();

const panelNewLoc = {
top: (buttonDimensions.height / 2) + panelDimensions.height
};

const viewport = {
top: docEl.scrollTop,
bottom: window.pageYOffset + docEl.clientHeight,
};

const offset = {
top: panelDimensions.top + win.pageYOffset,
left: panelDimensions.left + win.pageXOffset,
bottom: (panelDimensions.top + win.pageYOffset)
};

const panelHeight = getHeight(panel);
const enoughSpaceAbove = viewport.top < (offset.top + panelHeight);
const enoughSpaceBelow = viewport.bottom > (offset.bottom + panelHeight);
const enoughSpaceAbove = panelHeight + buttonDimensions.bottom > window.innerHeight;
const enoughSpaceBelow = panelHeight + buttonDimensions.bottom < window.innerHeight;

if (!enoughSpaceBelow && enoughSpaceAbove) {
direction = 'above';
} else if (!enoughSpaceAbove && enoughSpaceBelow) {
direction = 'below';
}
const rect = wrapperRef.current.getBoundingClientRect();
const coords = {
top: buttonDimensions.bottom + topBoxOffset,
left: align !== 'right'
? rect.left + inlineBoxOffset
: 'initial',
right: align === 'right' && isPinned
? window.innerWidth - rect.right + inlineBoxOffset
: 'initial',
};

if (!isPinned) {
coords.top = null;
coords.left = 'initial';
}

if (direction === 'above') {
panel.style.top = `-${panelNewLoc.top}px`;
coords.top = ((buttonDimensions.height / 4) + panelDimensions.height) * -1;
coords.left = 'initial';
if (isPinned) {
coords.top = (buttonDimensions.top - panelDimensions.height);
coords.right = window.innerWidth - buttonDimensions.right + inlineBoxOffset;
}
}

setPanelCoords(coords);
};

useEffect(() => {
if (!wrapperRef) {
return false;
}

if (isActive && isPinned) {
setPanelCoords();
window.addEventListener('scroll', onUpdate);
window.addEventListener('resize', onUpdate);
} else {
positionElement(wrapperRef.current);
window.removeEventListener('scroll', onUpdate);
window.removeEventListener('resize', onUpdate);
}
positionElement();

window.addEventListener('scroll', onUpdate);
window.addEventListener('resize', onUpdate);

return () => {
window.removeEventListener('scroll', onUpdate);
window.removeEventListener('resize', onUpdate);
};
}, [wrapperRef, isActive, isPinned, onUpdate]);
}, [wrapperRef, isActive, isPinned, onUpdate]); // eslint-disable-line

useEffect(() => {
if (panelStateToken) {
setActive(!isActive);
}
}, [panelStateToken]);
}, [panelStateToken]); // eslint-disable-line

const a11yAttrs = {
'aria-expanded': isActive,
Expand Down
7 changes: 7 additions & 0 deletions packages/sage-react/lib/Loader/Loader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ export const Loader = ({
{(type === LOADER_TYPES.SUCCESS) && (
<svg className="sage-loader__success" width="48" height="48" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="24" cy="24" r="21" fill="#0072EF" /><path fillRule="evenodd" clipRule="evenodd" d="M34.707 17.293a1 1 0 0 1 0 1.414l-13 13a1 1 0 0 1-1.414 0l-7-7a1 1 0 0 1 1.414-1.414L21 29.586l12.293-12.293a1 1 0 0 1 1.414 0Z" fill="#fff" /></svg>
)}
{(type === LOADER_TYPES.TYPING) && (
<div className="sage-loader__typing">
<span />
<span />
<span />
</div>
)}
{label ? (
<p className="sage-loader__text t-sage-body-small">{label}</p>
) : (
Expand Down
1 change: 1 addition & 0 deletions packages/sage-react/lib/Loader/configs.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export const LOADER_TYPES = {
SPINNER: 'spinner',
SPINNER_IN_BUTTON: 'spinner-in-button',
SUCCESS: 'success',
TYPING: 'typing',
};
4 changes: 4 additions & 0 deletions packages/sage-react/lib/Modal/Modal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const Modal = ({
disableBackgroundDismiss,
fullScreen,
id,
isClosing,
large,
onExit,
size,
Expand All @@ -30,6 +31,7 @@ export const Modal = ({
className,
{
'sage-modal--active': active,
'sage-modal--is-closing': isClosing,
'sage-modal--scrollable': allowScroll,
'sage-modal--large': large,
'sage-modal--fullscreen': fullScreen,
Expand Down Expand Up @@ -120,6 +122,7 @@ Modal.defaultProps = {
fullScreen: false,
large: false,
id: null,
isClosing: false,
disableBackgroundBlur: false,
disableBackgroundDismiss: false,
onExit: (val) => val,
Expand All @@ -142,6 +145,7 @@ Modal.propTypes = {
disableBackgroundDismiss: PropTypes.bool,
fullScreen: PropTypes.bool,
id: PropTypes.string,
isClosing: PropTypes.bool,
large: PropTypes.bool,
onExit: PropTypes.func,
size: PropTypes.oneOf(Object.values(Modal.SIZES))
Expand Down
10 changes: 8 additions & 2 deletions packages/sage-react/lib/Modal/Modal.story.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,14 @@ Default.decorators = [

export const Wired = (args) => {
const [active, setActive] = useState(false);
const [isClosing, setIsClosing] = useState(false);

const onExit = () => {
setActive(false);
setIsClosing(true);
setTimeout(() => {
setActive(false);
setIsClosing(false);
}, 1000);
};

return (
Expand All @@ -204,7 +209,8 @@ export const Wired = (args) => {
<Modal
{...args}
active={active}
animation={{ direction: Modal.ANIMATION_DIRECTIONS.BOTTOM }}
isClosing={isClosing}
animation={false}
onExit={onExit}
>
<DefaultBody onExit={onExit} />
Expand Down
32 changes: 32 additions & 0 deletions packages/sage-react/lib/Modal/ModalTransition.story.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Meta } from "@storybook/addon-docs";

<Meta title="Sage/Modal/Transition Notes" />

## Transition Notes
The modal provides a fadeout transition. The developer can opt in by adding the following items to the `<Modal />`.

### useState
Add useState to the import list
`import { useState } from 'react';`

### isClosing
Add isClosing={true} to the Modal to enable the closing transition timer.

```
<Modal isClosing={true} />
```

### onExit
Create an `onExit` below and pass to the Modal's `onExit` prop. Create a `setTimeout` function. `1500` is the recommended value for the closing transiton.

```
const onExit = () => {
setIsClosing(true);
setTimeout(() => {
setOpen(false);
setIsClosing(false);
}, 1500);
};
<Modal onExit={onExit}/>
```

0 comments on commit b4398c7

Please sign in to comment.