-
Notifications
You must be signed in to change notification settings - Fork 0
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
Basic Mechanics #20
base: main
Are you sure you want to change the base?
Basic Mechanics #20
Conversation
Not a qualified reviewer for this kind of PR, but I assume it is about the comments in a grid column (in ACO displayed on the right of the text), isn't it? floatingCommentary or floatingAnnotations might be a bit more generic in that case than floatingApparatus (for ACO floatingApparatus is not a bad choice, though). |
From the fact, that svelte started yelling at you, you can gather, that the handleMarkClick-way is the wrong way to go ;-)
I have to side with svelte on this: the notes at least are clearly buttons, not just a div! A click on them changes the content of the site. One might even say that the spans are actually buttons, or at least anchors, because stuff happens when you click on them.
Why not use Floating UI svelte? https://next.skeleton.dev/docs/integrations/popover/svelte/
I dislike the current use of a mix of CSS and tailwind. You will have to set some styles in the CSS-Section of the svelte files, but this doesn't mean you have to stop using tailwind. Use the you can narrow down the global styles a lot if you select an element that is accessible in the code and then apply the and never use purely global styles in the style-section of a svelte file. like
This sent me a bit back into my rabbithole of where and when to fetch... But the answer might be simpler in this case: since this is local data, we can just import instead of fetch?! Why are those jsons in the static folder instead of in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
most importantly: your app doesn't work on dark-mode at the moment. you can force the light mode if you only want one mode (https://next.skeleton.dev/docs/guides/mode). but at the moment in dark mode your text basically vanishes.
another very general thing is, that I think you don't use the full potential of svelte when manipulating the DOM:
In most of your functions you are tediously selecting elements from the document. If you had a binding for your element, you could just pass it to the function.
you could build yourself an object with the id's of the notes as keys and the dom-nodes themselfes as values. With a simple bind:this={notes[id]} you would have a lasting reference to the DOM-node.
Of course it would be a little bit more complicated because you created a component for the note, but still very much doable. this would get rid of most of the document.querySelector
-calls in your functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea of the index is as follows:
(1) It allows me to import the functions as if the floatingApparatus were an external library, i.e. all functions directly from the parent folder, without explicitly naming the individual files.
(2) I like to visually group similar functions together and make some general comments on their usage, independent of the alphabetic order of their names. It's a bit like combining the benefits of single-file functions with grouping similar stuff.
However I understand, if it seems a bit overkill here... would you like to delete the index?
Btw. I found another huge advantage of single-file functions: they have independent file history!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In my VSCodium I don't see the second line handleNoteClick: undefined
. No clue where this comes from, especially, since the first box seems to know that the function returns void. So your intellisense does see the function.
src/lib/data/content.js
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as discussed, this is not necessary. just move the files here and then import them in the load-function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. However, I left the imports in content.js
which I plan to use as a central file for file imports. I find this easier than to update multiple load-functions if I want to switch APIs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I did move the .json files to the lib/data folder, which indeed is nice for import. However, I wanted to ask you how you differenciate between the static folder and a lib/data folder. I mean, the data is static, too... Do you only use it for media but not for structured data?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Floating UI Svelte can do this for you can do this for you
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, this is nice! I'll implement this in March, when I'll polish the design.
`notebox word-wrap absolute max-w-[700px] rounded-md border-4 bg-white p-3 transition-transform duration-500`, | ||
selectedNote.id === note.id && 'highlighted' | ||
]} | ||
style={`margin-top:${MARGIN_NOTEBOX}px; margin-bottom:${MARGIN_NOTEBOX}px`} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do you set this as a style and don't use tailwind?
is for some reason my-2
is not good enough and you need exactly 10 px and you reuse the 10px value often you can set custom styles
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tailwind-classnames composed out of fragments won't render due to treeshaking.
[Npx]
is just a personal habit, since I always forget which numbers are valid custom styles and which are not. There's no meaning. Note that I'll do styling in March, so here it just has to work.
|
||
<!-- svelte-ignore a11y_click_events_have_key_events --> | ||
<!-- svelte-ignore a11y_no_static_element_interactions --> | ||
<div |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
svelte is right here. this is a button and not just a div
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also want to get rid of the ignore statements. However, the notes cannot be buttons, since buttons are not permitted to have interactive content. Already now, there are anchor-tags inside the notes for the references. Also think of a nested button that (un)collapses a very long note.
I see two workarounds:
- adding aria-roles etc. to the parent div
- adding a full-sized invisible button as a sibling of the note-content.
I chose (1) . As I was trying (2) I ran into difficulties related to event-propagation and sizing of the box. It should work in theory, but it isn't optimal either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using regex to match tags in the content also feels inherently wrong. It might be smarter to create a custom dom and then use the standard way to traverse a DOM-tree. You can use a multitude of ways for that. I also remember there being a npm-package for using it in node-environments. might be a worth a look
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(On a sidenote: I actually did use insertAdjacentHTML()
in an older version to temporarily insert <span>
s that wrap text of selected notes. But then I realised, that I can just add classes to the existing spans.)
Ok, so you suggest to use DOM-manipulation in the conversion form Proto-HTML --> Text/LineNums/PageNums. Now, I see why this is semantically more straight forward. But from a performance point of view, do you think it is wise to create the full DOM tree three times, just to dump half of the nodes right away? My gut feeling says that regexp is less work for the client.
Note, that in the ProtoHTML everything is still contained and then with regexp I'm basically filtering out the parts that are needed for the respective columns, while keeping the <br />
-tags in all columns, which will guarantee alignment of the lines.
Of course we could pre-process the protoHTML for all three columns, and everything would be fine :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm... it would need texting as to what's more performant... both options are quite expensive so it might be worth a test.
Will be replaced by floatingUI Svelte later
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your detailed review @flicksolutions. I solved the easy tasks and asked some questions, as long as things are still fresh. Some bigger refactoring tasks I leave for March.
1/2 -- Clicklisteners/a11y: I started a discussion further below.
3 -- Popovers: I'll implement Floating UI Svelte in a later PR. Thanks.
4 -- Global CSS-Styles: I dislike the current tailwind/css mix as well and will use as much tailwind as possible inMarch.
5 -- Loading: I'm now using import
instead of fetch
.
|
||
<!-- svelte-ignore a11y_click_events_have_key_events --> | ||
<!-- svelte-ignore a11y_no_static_element_interactions --> | ||
<div |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also want to get rid of the ignore statements. However, the notes cannot be buttons, since buttons are not permitted to have interactive content. Already now, there are anchor-tags inside the notes for the references. Also think of a nested button that (un)collapses a very long note.
I see two workarounds:
- adding aria-roles etc. to the parent div
- adding a full-sized invisible button as a sibling of the note-content.
I chose (1) . As I was trying (2) I ran into difficulties related to event-propagation and sizing of the box. It should work in theory, but it isn't optimal either.
src/lib/data/content.js
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. However, I left the imports in content.js
which I plan to use as a central file for file imports. I find this easier than to update multiple load-functions if I want to switch APIs.
src/lib/data/content.js
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I did move the .json files to the lib/data folder, which indeed is nice for import. However, I wanted to ask you how you differenciate between the static folder and a lib/data folder. I mean, the data is static, too... Do you only use it for media but not for structured data?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, this is nice! I'll implement this in March, when I'll polish the design.
if (startId) { | ||
// Handle <note_start> tag | ||
openIds.push(startId); | ||
result += `<note_start note_id='${startId}'></note_start>`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for being picky on this. I changed it.
Small follow-up: What are your thoughts about <span type="start">
vs. <span class="note-start">
?
`notebox word-wrap absolute max-w-[700px] rounded-md border-4 bg-white p-3 transition-transform duration-500`, | ||
selectedNote.id === note.id && 'highlighted' | ||
]} | ||
style={`margin-top:${MARGIN_NOTEBOX}px; margin-bottom:${MARGIN_NOTEBOX}px`} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tailwind-classnames composed out of fragments won't render due to treeshaking.
[Npx]
is just a personal habit, since I always forget which numbers are valid custom styles and which are not. There's no meaning. Note that I'll do styling in March, so here it just has to work.
let idsAttribute = JSON.stringify(openIds); | ||
if (openIds.length > 0) { | ||
let multiIdsClass = openIds.length > 1 ? 'multiple-ids' : ''; | ||
result += `<span class='mark ${multiIdsClass}' note_ids=${idsAttribute}>${precedingText}</span>`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@flicksolutions How would you insert an onclick-handler here the svelte way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would add an action with use on the div wrapping the maintext in Text.svelte on line 6:
const addSpanHandlers: Action = (node) => {
// the node has been mounted in the DOM
$effect(() => {
// setup goes here
node.querySelector(`span`).forEach(n => n.addEventListener("click",eventhandler))
return () => {
// teardown goes here
node.querySelector(`span`).forEach(n => n.removeEventListener)
};
});
};
something along those lines
Oh yes, importantly, in this PR I did not focus much on styling, which is why I renamed it from "Groundwork" to "Basic Mechanics". Styling, dark mode etc. will be a seperate task for March. |
Also, I still have to type everything... but since this would require renaming all the files from .js to .ts, I think it's better to do this not during a PR?! |
jup, that's fine. Tell me, if you found a simple way to do this. I have a lot of projects I would like to convert to TS but I'm afraid of very tedious work... |
For this PR I refactored the single-file test-route from Tuesday aiming to simplify reuse of the floatingApparatus in other projects (open for other names). Below are some comments
Comments and Questions
handleNoteClick
is attached to every single note whereashandleMarkClick
is attached to the mainText-column relying on event-bubbling. What's your opinion on this? It also makes sense.<MultiMarkPopup>
, but I don't understand how to place its trigger...:global()
in the css-styles it does not see the DOM-elements inside the{@html}
. Another option would be to select for e.g.#container_text
, but how to do this using the ids inconstants.js
? Or would you prefer doing the conditional formatting with.highlighted
-classes in pure tailwind?metadata
). However, since I use local .json files and no server-API I get the following error: "Cannot use relative URL (/json/aco-text.json) with global fetch — useevent.fetch
instead: https://svelte.dev/docs/kit/web-standards#fetch-apis"