How to implement Medium-style commenting interface in VueJS - javascript

I really like the commenting interface employed by Medium, allowing users to highlight a portion of an article and comment on that specific part.
I would like to implement a similar commenting facility in a VueJS app.
I found this package which does something similar: http://aroc.github.io/side-comments-demo/, but I want to try to find something that has been updated more recently. Also, it requires jquery, which I don't currently use and I would like to avoid adding that dependency if possible.
I would love to know if anyone has seen anything that could help.

I have created a sample at https://codesandbox.io/s/medium-style-text-select-comment-box-h5o9r
Here I am adding the comments component to the root component such that it is available globally. On component mount() hook, I am attaching a mouseup method to the window object where any selections done are checked using
if (window.getSelection() && !window.getSelection().isCollapsed) {
//execute only with the getSelection() method is available
//and the current selection is not collapsed
}
Once we do have a selection, the position on the page is calculated using the selection position and its dimensions and the floating comments component is positioned accordingly.
We can get the selected text using
window.getSelection().toString();
I would advise you to go through the sandbox as there are a lot of things going on which are not in this answer.

Related

Create responsive drag and drop dashboard in React

I am trying to create a dashboard where users can drag and drop widgets within the dashboard to any position they'd like. I've seen other examples similar but they all seem to have predefined elements.
In my case, the user can create and remove elements on the dashboard and move them to any point on the board.
My question is, what would be the best way to create a dashboard like this that supports the dragging and dropping of an element anywhere on it. Also, how can I save this info?
Thanks in advance.
Are you looking for something like react-grid-layout?
In this demo you can see how the widgets' state could be encoded. This could be saved and retrieved upon page load.
You can use react-dnd library. Easy to implement and customise. Here is the repo link;
https://github.com/react-dnd/react-dnd/

How to create a badge component for custom components?

I am facing a really nasty issue, I need to create a badge component that it'll be places over a custom component.
This is my first attempt to create something similar in React, with HTML is way easier because you work directly with the DOM.
In this case instead I need to create a badge that will highlight a new component/feature, when you click on it a popup get's open with a bit of text that'll explains what the component is about, aka it's functionality. Telling you this because I need to listen for onClick and it's not possible to use pseudo-elements.
The base idea
<BadgeComponent position="top left">
<CustomComponent />
</BadgeComponent>
Since I can't use a pseudo-element that'll inherit all the element CSS properties this is my thinking:
do not change the CustomComponent because each time could be different
the BadgeComponent is a wrapper that creates a div with position:relative (so I can position the badge wherever I want)
BadgeComponent needs to be display: inline-block otherwise it'll change the overall layout
I need to take the CustomComponent box-model properties, remove from it and apply them to the BadgeComponent. This mostly because margins are messing with the BadgeComponent size and position the badge itself will be trickyer
Basically I need to take the CSS properties of the DOM element rendered from the child component.
The approach
So I've been experimenting with some code before came here and my first attempt has been to dinamically pass a ref to the child component of BadgeComponent with this snippet:
{React.Children.map(this.props.children, (element, idx) => {
if (idx > 0) return; // don't care if it has more childrens, at least for now.
return React.cloneElement(element, { ref: this.newFeature });
})}
I also thought to take the CustomComponent as a prop of BadgeComponent, like so:
<BadgeComponent position="top left" target={ CustomComponent }>
But I didn't (yet) followed this path because I thought that at the end of the day this.props.target it's basically the same of this.props.children and didn't earn anything doing so. Am I right?
I know that in React we have ref to get a reference to the DOM created from a component but in this case is not applicable because I am not applying the ref to the component that renders an HTML, I am applying it to CustomComponent that gets cloned and it doesn't pass to the DOM.
From my experiment everything works fine if I pass an HTML element, in the experimental code I have a div.box that gets the badge in the position that I want but as soon as I pass the Button I got the following error: Window.getComputedStyle: Argument 1 does not implement interface Element.
I am using window.getComputedStyle to get the CSS properties I care about.
My research
I've been looking all around the web and I've seen a nice implementation that, unfortunately, just works with styled components or styled defined inline in <style>. I am looking to not use NPM packages as this one because firstly I believe that it is possible to implement without reach for an additional package and second actually I do not like much the way that the sticky/badge get's implemented (with all respect obviously).
I don't know where to look anymore, I am not an expert JS/React developer (been WP theme developer for 10 years) so probably there is some basic concept that I missunderstand?
I've read about findDOMNode (looks will be deprecated soon) and forwardRef in the React ecosystem but I do not think that's the way to go, am I wrong?
I do not want the copy/paste code, well if you're so gentle to fork the codesandbox and share the solution will be great but I am trying to learn here: there is a way to get a reference of the rendered HTML element from any component?
Thinking that this is the missing part, if I can reach the DOM my code is already working 😊

How to apply 'Blink' feature in Ember Table?

in Ember Table, I need to change style of a cell with the change of particular cell content. I need to add color to cell with value update (that I have already done) and remove styles after 1 second (that I want to do).
I have called setTimeout when applying color and removed color within setTimeout. It does not work all the time. some cell colors are not removed.
(this gets worse when scrolling). I assume after 1 second, Ember cannot find the particular cell element.
I use and Ember table component and assigned a contentBinding and columnBinding. I added a template for the Ember.Table.TableCell component and added class names.
Added Main Function and modified Jsbin example below.
I can't guarantee that this will answer your question, but here are a bunch of things that jump out at me when reading this code. I think they are best formatted as an "answer".
You should avoid side-effects, like calling setTimeout, within a computed property. Computed properties in Ember are lazy, so they only update when their value is needed. Consider using an Observer, or just a function, in cases like this. This is almost certainly related to your problem.
Instead of setTimeout, use Ember.run.later or similar Ember functions. This will make sure your code respects the Ember run loop.
Your customColor computed property doesn't depend on previousColumnValue, even though it uses it. This is related to the side-effects discussion: you should try to re-architect your code if possible.
Other than that, you have a lot of the right ideas. I'm fairly sure this can be done with Ember Table - the AJAX example is an example of Ember Table cells dealing with asynchrony.
I recommend debugging by first trying to create a minimal example in JS Bin, using the Ember Table starter kit. This will also be useful if you'd like more help - it makes it easy for people like me to play with your setup until it works.

JQuery and ACE-Editor not playing well together

I am building some modules to teach intro coding concepts to some of my students
http://jsbin.com/pacaxoza/3/edit
When a user writes their own function, I want the editor which is highlighting each line as it goes to jump to the function when it is called so the user can see that their function is read when they call it. All of this is in the jsbin above (the canvas with animation based on the code is not in the jsbin for clarity reasons).
In Javascript mode Ace Editor surrounds any user defined functions in a span with class'ace_function'. I could not find an easy way to find and store values from user created functions in ace methods so instead I am using JQuery to find each span with the class 'ace_function'. I am using JQuery index to find what lines those functions are on, and then passing that info to ace methods to render.
The issue is if the editor is scrolled to the top, everything works fine, but if you scroll down any in the editor and hit submit, the editor's indexing seems to be off by a couple lines of code and everything breaks down.
Does anyone have suggestions for a better way to approach this problem, or what could be causing the erratic behavior?
Thanks
Ace uses virtual viewport and creates dom elements only for visible lines, so using jquery won't work.
You need to use Ace api instead, session.getLine(number)->string, session.getTokens(number)->[{type, value}, ...].
tokenIterator might be useful as well see https://github.com/ajaxorg/ace/blob/master/lib/ace/edit_session/bracket_match.js#L34 for an example

iOS-style formatting callout using Rangy

I'm looking at Rangy (http://code.google.com/p/rangy/) and it seems it has a bunch of DOM utilities but I don't understand them without examples. So I'm turning to SO with my ideas and hopefully you guys can show me how this can be done:
What I need to do with Rangy is use it to find the position and dimensions of the selection. I want to get the frame or Rect of the selection, whether relative to the document or parent element. Then I can position my callout accordingly.
I believe the demo that comes with Rangy already illustrates what you want. specifically http://rangy.googlecode.com/svn/trunk/demos/position.html inside showSelectionPosition function
Considering the fact that selection may be spread across multiple elements, it'd be best to use the coordinates of either startSelEl or endSelEl to anchor your callout to the beginning or end of a selection.
There is an embryonic, unreleased Rangy module I wrote for getting pixel coordinates of a selection or range. Unfortunately the difficulty of getting this working properly in all browsers and all situations has put me off completing it and I have essentially abandoned it. However, if you add a bit more detail about what you're trying to do I may be able to suggest something.

Categories

Resources