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

feat(fade-in-out): introducing new components #4608

Merged
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
caea15c
fix(megamenu): fixed uncentered arrow icon in safari
IgnacioBecerra Nov 24, 2020
e0827fd
Revert "fix(megamenu): fixed uncentered arrow icon in safari"
IgnacioBecerra Nov 24, 2020
d7c4f8b
Merge branch 'master' of https://github.com/carbon-design-system/carb…
IgnacioBecerra Nov 24, 2020
370161c
Merge branch 'master' of https://github.com/carbon-design-system/carb…
IgnacioBecerra Nov 25, 2020
7ac3c4e
Merge branch 'master' of https://github.com/carbon-design-system/carb…
IgnacioBecerra Nov 30, 2020
b3bf936
Merge branch 'master' of https://github.com/carbon-design-system/carb…
IgnacioBecerra Dec 1, 2020
f2f28e0
feat(scroll-into-view): introducing new utility
IgnacioBecerra Dec 3, 2020
d697a49
feat(scroll-into-view): adding and removing classes instead
IgnacioBecerra Dec 3, 2020
f2f6b40
feat(scroll-into-view): using prefixes
IgnacioBecerra Dec 3, 2020
65cd0cc
feat(scroll-into-view): updated dependencies
IgnacioBecerra Dec 3, 2020
348cff7
feat(scroll-into-view): dependency fix
IgnacioBecerra Dec 3, 2020
e55580c
feat(scroll-into-view): changed sass file location
IgnacioBecerra Dec 3, 2020
879fe94
fix(scroll-into-view): removed dependency
IgnacioBecerra Dec 3, 2020
a9d195d
Merge branch 'master' of https://github.com/carbon-design-system/carb…
IgnacioBecerra Dec 3, 2020
6e07260
feat(scroll-into-view): slight refactoring
IgnacioBecerra Dec 4, 2020
610ce46
feat(scroll-into-view): removed unneeded dependency
IgnacioBecerra Dec 4, 2020
0b34be4
Merge branch 'master' into scroll-fade-animation
jeffchew Dec 4, 2020
7c23d01
Merge branch 'master' into scroll-fade-animation
IgnacioBecerra Dec 4, 2020
ed05f92
feat(scroll-into-view): added story and fixed jsdoc
IgnacioBecerra Dec 4, 2020
461edc1
Merge branch 'scroll-fade-animation' of https://github.com/IgnacioBec…
IgnacioBecerra Dec 4, 2020
8264ddf
Merge branch 'master' into scroll-fade-animation
IgnacioBecerra Dec 4, 2020
40bbba9
chore(scroll-into-view): update screenshots
IgnacioBecerra Dec 4, 2020
077b0dd
Merge branch 'scroll-fade-animation' of https://github.com/IgnacioBec…
IgnacioBecerra Dec 4, 2020
e5eedd1
chore(snapshots): more snapshots!
IgnacioBecerra Dec 4, 2020
35eb572
feat(scroll-into-view): added web component story variation
IgnacioBecerra Dec 4, 2020
d62d6d4
Merge branch 'master' of https://github.com/carbon-design-system/carb…
IgnacioBecerra Dec 7, 2020
5392a08
Merge branch 'master' of https://github.com/carbon-design-system/carb…
IgnacioBecerra Dec 7, 2020
90a961a
Merge branch 'master' of https://github.com/carbon-design-system/carb…
IgnacioBecerra Dec 8, 2020
41fbdd5
Merge branch 'master' of https://github.com/carbon-design-system/carb…
IgnacioBecerra Dec 9, 2020
95f4af5
Merge branch 'master' of https://github.com/carbon-design-system/carb…
IgnacioBecerra Dec 10, 2020
72c1a97
feat(scroll-into-view): improved based on feedback
IgnacioBecerra Dec 15, 2020
a9a4511
Merge branch 'master' of https://github.com/IgnacioBecerra/ibm-dotcom…
IgnacioBecerra Dec 15, 2020
0425ce4
Merge branch 'master' into scroll-fade-animation
IgnacioBecerra Dec 15, 2020
54c0f5b
feat(scroll-into-view): added variation to web component dotcom shell
IgnacioBecerra Dec 15, 2020
2cffb6f
feat(scroll-into-view): replaced eventlistener for resize observer
IgnacioBecerra Dec 16, 2020
a82d128
Update packages/utilities/src/utilities/scrollIntoView/scrollIntoView.js
IgnacioBecerra Dec 16, 2020
794ec81
feat(scroll-into-view): update parameter to include future options
IgnacioBecerra Dec 16, 2020
67e7e32
Merge branch 'scroll-fade-animation' of https://github.com/IgnacioBec…
IgnacioBecerra Dec 16, 2020
93768f9
chore(scroll-into-view): update snapshots
IgnacioBecerra Dec 16, 2020
671764b
Merge branch 'master' of https://github.com/carbon-design-system/carb…
IgnacioBecerra Dec 16, 2020
8df2faf
Merge branch 'master' into scroll-fade-animation
IgnacioBecerra Dec 16, 2020
4671464
chore(scroll-into-view): updated snapshots again
IgnacioBecerra Dec 16, 2020
972fbc2
Update packages/utilities/src/utilities/scrollIntoView/scrollIntoView.js
IgnacioBecerra Dec 17, 2020
7cacbe7
feat(scroll-into-view): changed margin calculation and logo effect
IgnacioBecerra Dec 17, 2020
84b6fe4
fix(scroll-into-view): typecasting as htmlelement
IgnacioBecerra Dec 17, 2020
afa297e
feat(scroll-into-view): refactored code and stories
IgnacioBecerra Dec 17, 2020
1749f5c
chore(snapshots): updated snapshots
IgnacioBecerra Dec 17, 2020
20cc29f
feat(scroll-into-view): using css rules for staggered delays
IgnacioBecerra Dec 18, 2020
3f4450a
feat(fade-in-out): reimplemented into web and react components
IgnacioBecerra Jan 8, 2021
8379ff1
feat(fade-in-out): addressed changes in web component
IgnacioBecerra Jan 8, 2021
39bc570
feat(fade-in-out): addressed changes in react
IgnacioBecerra Jan 8, 2021
e7c06ad
chore(fade-in-out): ignore typescript warning
IgnacioBecerra Jan 8, 2021
e46286c
chore(fade-in-out): updated react snapshot
IgnacioBecerra Jan 8, 2021
43ce5aa
feat(fade-in-out): addressed feedback
IgnacioBecerra Jan 11, 2021
b4291d5
chore(fade-in-out): update snapshots
IgnacioBecerra Jan 12, 2021
79e7913
feat(fade-in-out): component wrapping
IgnacioBecerra Jan 12, 2021
86772a5
feat(fade-in-out): addressed feedback
IgnacioBecerra Jan 12, 2021
b38bd30
feat(fade-in-out): renamed closure variables
IgnacioBecerra Jan 12, 2021
a4683a2
chore(fade-in-out): separated into individual stories
IgnacioBecerra Jan 14, 2021
6a22d06
Merge branch 'master' into scroll-fade-animation
IgnacioBecerra Jan 14, 2021
beb0771
chore(fade-in-out): added missing semicolon
IgnacioBecerra Jan 14, 2021
0eb0cd1
chore(fade-in-out): moved scss to components, removed knobs
IgnacioBecerra Jan 14, 2021
c643950
Merge branch 'master' into scroll-fade-animation
IgnacioBecerra Jan 14, 2021
b367d52
chore(dotcom-shell): update with new images
IgnacioBecerra Jan 14, 2021
3e1acb0
fix(dotcom-shell): reintroduced heading
IgnacioBecerra Jan 14, 2021
a364613
Merge branch 'master' into scroll-fade-animation
IgnacioBecerra Jan 14, 2021
6604d52
chore(dotcom-shell): reintroduced link list heading
IgnacioBecerra Jan 14, 2021
399aa63
fix(dotcom-shell): updating content item horizontal eyebrow
IgnacioBecerra Jan 14, 2021
9b49564
Merge branch 'master' into scroll-fade-animation
kodiakhq[bot] Jan 14, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
Copy link
Member

Choose a reason for hiding this comment

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

Not sure if this file technically belongs in internal, maybe move to components since it is part of a component now. Be sure to update corresponding documentation too.

* Copyright IBM Corp. 2016, 2020
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

@import '../../globals/vars';
@import '../../globals/imports';

:root {
--#{$dds-prefix}--scroll-into-view-delay: 400ms;
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's make sure we're using Carbon's tokens.

Suggested change
--#{$dds-prefix}--scroll-into-view-delay: 400ms;
--#{$dds-prefix}--scroll-into-view-delay: $duration--slow-01;

}

.bx--fade-in {
transition-timing-function: carbon--motion(entrance, expressive);
transition-duration: var(--#{$dds-prefix}--scroll-into-view-delay);
opacity: 1;
}

.bx--fade-out {
transition-timing-function: carbon--motion(exit, expressive);
transition-duration: var(--#{$dds-prefix}--scroll-into-view-delay);
opacity: 0;
}
1 change: 1 addition & 0 deletions packages/utilities/src/utilities/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export * from './ipcinfoCookie';
export * from './markdownToHtml';
export * from './removeHtmlTagEntities';
export * from './sameHeight';
export * from './scrollIntoView';
export * from './serialize';
export * from './settings';
export * from './smoothScroll';
Expand Down
8 changes: 8 additions & 0 deletions packages/utilities/src/utilities/scrollIntoView/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Copyright IBM Corp. 2016, 2020
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

export { default as scrollIntoView } from './scrollIntoView';
76 changes: 76 additions & 0 deletions packages/utilities/src/utilities/scrollIntoView/scrollIntoView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* Copyright IBM Corp. 2016, 2020
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

/**
* Utility handles fade transition for selected elements.
*
* @example
* import '@carbon/ibmdotcom-styles/scss/internal/scroll-into-view/_scroll-into-view.scss';
* import { scrollIntoView } from '@carbon/ibmdotcom-utilities';
*
* As an example, the function can be called to target 'bx--content-block' as such:
*
* For default values of 400ms and continuous play:
* scrollIntoView('.bx--content-block')
*
* With 'one and done' option:
* scrollIntoView('.bx--content-block', false)
*
* For custom delay time, set within targeted class in the application's CSS code as such:
*
* .bx--content-block {
* --#{$dds-prefix}--scroll-into-view-delay: 3s;
Copy link
Contributor

Choose a reason for hiding this comment

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

The API here feels a little off to me. You have everything defined by the utility function above. Could the utility set the property?

// adopter
scrollIntoView('.bx--content-block', 3s);

// utiliity
function scrollIntoView(selector, delay = 0, iterations = false) {
   ...
   selector.style.setProperty('--dds--scroll-into-view-delay', delay);
   ...
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm yeah, I originally wrote it like this, but since we're trying to move away from inline styling, I moved forward with the other approach by having the adopters set the delay within their own classes. I think both approaches have their pros and cons, but I do agree it'd be easier for the adopter to set it through the API.

@asudoh I'm wondering if you have some thoughts about this?

Copy link
Contributor

Choose a reason for hiding this comment

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

@IgnacioBecerra is right, we are avoiding defining style by JavaScript unless it's absolutely necessary. If we use inline style there is no way for application style to override it.

Copy link
Contributor

Choose a reason for hiding this comment

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

@asudoh not sure I'm fully following that logic. What's a scenario that is "absolutely necessary"? The adopters would be the ones setting this, wouldn't they? This isn't stopping them from resetting it, does it? It seems odd to me they'd have to touch two separate files to get this working, and it uses two different sets of APIs. It also feels laborious to implement a proper delay that builds on top of itself using SCSS, and the logic that might be needed for the delay might be built out separately or duplicated. I don't know... Keep doing it if y'all are sure this is the right direction, but this doesn't jive in my brain.

Copy link
Contributor

Choose a reason for hiding this comment

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

@photodow Application may want to define the rule of scrolling delay enforced to everywhere in the application, or everywhere in a specific portion. However, if a JavaScript code defines inline style, such inline style wins all the time and thus there is no way (that is natural in CSS world) for setting it application wide.

Copy link
Contributor

@photodow photodow Dec 15, 2020

Choose a reason for hiding this comment

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

@asudoh yeah, I'm very familiar with how CSS specificity works in this scenario. I'm not bought into the user experience you're creating here at the moment. I also don't know if we want other parts of the CSS overriding this value. I personally feel like this would be a scenario where inline would make sense, but for the sake of progress I'll step aside, and we can see where this takes us. Thanks as always @asudoh!

Copy link
Contributor

@asudoh asudoh Dec 15, 2020

Choose a reason for hiding this comment

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

Thanks @photodow for your thoughts! Another option is using an enum (that corresponds to a set of CSS classes) rather than a direct number. The story-specific CSS rulesets will be moved to our styles package in this way.

* }
*
* @param {*} selector menu item selector id
* @param {boolean} iterations to define whether its continuous or not
*/

const viewportMargin =
'-' +
(
Math.round(document.documentElement.clientHeight / (100 / 12.5)) + 32
).toString() +
'px 0px';

const options = {
rootMargin: viewportMargin,
threshold: 0,
};

const scrollIntoView = (selector, iterations = true) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we set iterations default to false? I think I neglected to add a default value, so that's on me. I can update the functional specs to reflect that.

Copy link
Contributor

Choose a reason for hiding this comment

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

Mere question, but will this only allow for a string selector, or can it pass in a Node object?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Currently it's set to receive strings, mainly since it's wrapped around a listener that waits until the whole page is loaded before querying the element. If the adopters can make sure the element exists before calling the function we could make it so they can pass node objects instead.

window.addEventListener(
'load',
() => {
const elements = document.querySelectorAll(selector);
const observer = new IntersectionObserver(function handleIntersect(
entries
) {
entries.forEach(entry => {
if (entry.intersectionRatio > 0) {
entry.target.classList.remove('bx--fade-out');
entry.target.classList.add('bx--fade-in');
if (!iterations) {
observer.unobserve(entry.target);
}
} else {
entry.target.classList.remove('bx--fade-in');
entry.target.classList.add('bx--fade-out');
}
});
},
options);

elements.forEach(e => {
observer.observe(e);
});
},
false
);
};
Copy link
Contributor

@asudoh asudoh Dec 18, 2020

Choose a reason for hiding this comment

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

I now see one thing that slipped my mind... My apologies that I didn't notice thing earlier. We need to detach event listeners, IntersectionObserver and ResizeObserver when the target DOM nodes are removed. Such use case often happens with "routers" (e.g. React routers) when navigating to different "route" swaps DOM and thus the event listeners, etc. will be orphaned (and causes memory leaks, JavaScript errors, etc).

A quick way to solve this is adding something like below:

return {
  release() {
    _resizeObserver.disconnect();
    _innerObserver.disconnect();
    _rootObserver.disconnect();
    window.removeEventListener('load', handleOnLoad);
  },
};

Another way (that I'd prefer given scroll into view thing now effectively has a lifecycle as in componentDidUnmount()/detechedCallback()) is making it a component rather than a function. We can do it by one of the following:

CC @jeffchew

Copy link
Member

Choose a reason for hiding this comment

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

For performance purposes a component wrapper might make more sense for this. Perhaps we can build web component wrapper first, and would we be able to create the react wrapper of that or a pure react component would make more sense @asudoh @IgnacioBecerra ?

Copy link
Contributor

Choose a reason for hiding this comment

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

@jeffchew Web Component and a React wrapper on top of it makes sense to me - @IgnacioBecerra what do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jeffchew @asudoh Hm, just so I understand, would creating a Web Component for this would be something like:

// fade-component.ts
class DDSFadeComponent {
   // scroll-into-view code here + the disconnect thing
}

// dotcom-shell.stories.ts
let elementsToFade = "dds-content-block, dds-content-item, etc..."
let _iterations = true;
.
.
.
return html`
  <dds-fade-component elements="${elementstoFade}" iterations="${_iterations}"/>
  <dds-table-of-contents>
     // etc etc 
`

After typing it out like this I think I understand it better, but let me know if my understanding is wrong.

Copy link
Contributor

Choose a reason for hiding this comment

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

Great question @IgnacioBecerra! We have two choices:

  1. Wrap each element (or groups of elements) for fade in/out effect with <dds-fadeinout>
    • Pro
      • Idiomatic wrt what set of elements need fade in/out effect
      • Strict control of the lifecycle
    • Con:
      • Extra HTML elements
  2. Make each scrolling element <dds-fadeinout>
    • Pro
      • Less extra HTML elements
    • Con
      • Still need to specify target elements (via CSS selector)
      • Still have possibility of memory leaks (if the target elements have different lifecycle from <dds-fadeinput>)

Basically, if we tend to (or can) add fade in/out effect to "region"s or components rather than some indivisual (specific) elements, 1. works the best (e.g. are they only heading/copy elements that need fade in/out effect in content block?). Otherwise 2. works better.


export default scrollIntoView;