-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
[WIP] Improve current console #639
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
Conversation
Still work in progress. Need more style work and tests |
Some screenshots of the improved console. There are currently two issues that I cannot figure out:
@catarak Can you plz take a look? l am not good at designing styles 🤔 |
So excited about this, great work! |
@catarak if I understand the scope of this correctly, we want to harmonize the particular values used in the console, like in the following examples derived from
with core colors from
I'd be happy to take a crack at this from a design perspective and post an update in a few days or so if that timeframe works. I'd be interested to know if there's any opposition to using Sass functions to darken and/or lighten the core colors for one or both of the themes? I think that approach might produce more pleasing results within a theme for the console which effectively has a different background color than the editor overall. I'm also thinking some check into the syntax highlighting colors for appropriate parallels might be worth doing. I don't see |
@machinic l removed the |
@shinytang6 — perfect, thanks for the info! |
@shinytang6 the theming is done using a SCSS mixin called .preview-console__log {
@include themify() {
color: getThemifyVariable('secondary-text-color');
}
} this is the magic that generates the different styles necessary to create themes. in order to define a color variable, it needs to be added to every single theme in the @machinic it would be awesome to get your input on the console theming! i think the approach of lightening or darkening from the core syntax theme could be nice, to distinguish from the code editor. though maybe that's overthinking it, and it could be as simple as differentiating the background color? |
Yes I have noticed that. But in this case I need to pass styles to the console-feed library instead of defining it in |
Oh I see! This library expects you to define the styles in a JS object. That's annoying! I've never tried this before, but apparently, with webpack, you can use I'll think about alternative options too! |
Thanks, I will investigate! |
@catarak — cool. The reason I'd advocate for using some Sass function to adjust either the Lightness or the Saturation in the console related base colors for the themes is less about distinguishing the console from the code editor (those two spaces should have different backgrounds already) and more about how the colors interact with a dark or light background in general. Here's an example, these aren't the current error, warning colors in the editor right now — it's an attempt to mitigate some of what I'm talking about without making an adjustment for one theme or another (though a bit more accommodating it still fails, imo): When we did the syntax colors we dialed in specific sets of hex values for each theme for this reason, too. I thought that it might be a nice reprieve from that approach to lean into what we can get out of Sass. (I'm thinking about this more as well.) |
@catarak After some trials, l think it's difficult to export different styles based on the theme class dynamically in scss because webpack bundle all the files into a static file before running. Re-rendering is working now by adding some tricky code |
@machinic okay, got it! @shinytang6 glad you got it (somewhat) working! we can do some investigation of applying styles to the logs. |
@@ -48,8 +85,23 @@ class Console extends React.Component { | |||
); | |||
} | |||
return ( | |||
<div key={consoleEvent.id} className={`preview-console__${method}`}> | |||
{Object.keys(args).map(key => <span key={`${consoleEvent.id}-${key}`}>{args[key]}</span>)} | |||
<div key={consoleEvent.id} className={`preview-console__${method} theme-with-${theme}-background`}> |
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 theory, you shouldn't have to include the theme class name here since it's already assigned to the <body>
.
const { arguments: args, method, times } = consoleEvent; | ||
const { theme } = this.props; | ||
Object.assign(consoleEvent, { 'data': this.formatData(args) }); | ||
|
||
if (Object.keys(args).length === 0) { | ||
return ( | ||
<div key={consoleEvent.id} className="preview-console__undefined"> |
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.
instead of the console method being the "element" part of the BEM (Block Element Modifier) syntax, i think it makes more sense for it to be the "modifier" part.
also, when using modifiers in BEM, you also need an original/base class too. therefore, the class name of every message should be .preview-console__message .preview-console__message--${method}
. this will also make it easier to write the theming SCSS.
} | ||
} | ||
|
||
.theme-with-dark-background, .theme-with-contrast-background { |
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.
if, as above, you change the class of the console messages to .preview-console__message--${method}
, then you can change this to
.preview-console__message {
@include themify() {
color: getThemifyVariable('console-bg-color');
}
}
And then you need to add this variable to the $theme
map in _variables.scss
.
color: $black; | ||
} | ||
|
||
.theme-with-light-background { |
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.
if you make the change on line 62 you can delete this.
@include themify(){ | ||
color: getThemifyVariable('secondary-text-color'); | ||
} | ||
.preview-console__log, .preview-console__info{ |
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.
Since now all of the console messages have the same class in common (.preview-console__message
), you don't have to repeat these styles a bunch of times. You can do
.preview-console__message {
flex: 1 0 auto;
position: relative;
}
} | ||
|
||
.preview-console__logged-times { | ||
font-size: 10px; |
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.
This project doesn't use pixel measurements but uses REM's! Therefore this should be
font-size: #{10 / $base-font-size}rem;
font-size: 10px; | ||
font-weight: bold; | ||
margin: 2px 0 0 6px; | ||
border-radius: 100px; |
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.
Does this work if it's 100%?
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.
It looks better using px
.preview-console__logged-times { | ||
font-size: 10px; | ||
font-weight: bold; | ||
margin: 2px 0 0 6px; |
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.
This should also be in REMs instead of pixels.
font-weight: bold; | ||
margin: 2px 0 0 6px; | ||
border-radius: 100px; | ||
padding: 1px 4px; |
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.
Again, REMs and not pixels.
border-radius: 100px; | ||
padding: 1px 4px; | ||
z-index: 100; | ||
float: left; |
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 don't like to use float
because it's annoying. You should be able to change this to left: 0
and i think you'll get the same effect.
@shinytang6 let me know if you have any questions about my requested changes! If you're not familiar with BEM (Block Element Modifier) I'd recommend taking a look at this: http://getbem.com/naming/. Or if you're confused about any of the SCSS syntax, the SASS documentation is really good and I'd recommend taking a look at it. |
@@ -2,13 +2,49 @@ import PropTypes from 'prop-types'; | |||
import React from 'react'; | |||
import InlineSVG from 'react-inlinesvg'; | |||
import classNames from 'classnames'; | |||
import { Console as ConsoleFeed } from 'console-feed'; | |||
import { getConsoleFeedLightStyle, getConsoleFeedDarkStyle, getConsoleFeedContrastStyle } from '../../../utils/consoleUtils'; |
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.
Could these variables be renamed to CONSOLE_FEED_LIGHT_STYLES
, CONSOLE_DARK_LIGHT_STYLES
, and CONSOLE_FEED_CONTRAST_STYLES
? It's confusing that they are prefixed by get
and are not functions.
this.props.stopSketch(); | ||
this.props.expandConsole(); | ||
} | ||
}); | ||
}); | ||
for (let i = 0; i < messageEvent.data.length;) { |
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 can see what's going on here but this is a pretty dense block of code here. is there any way to clean this up a bit? break it out into its own separate function or functions? or maybe this could be done in the messageEvent.data.forEach
loop above? You can use Array.prototype.every
instead of Array.prototype.forEach
break out of the loop early.
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.
Yes, the code here is a bit redundant,l will try to clean it up
@catarak @shinytang6 — this doesn't feel 100% dialed-in to me yet but I think it's the right direction and I wanted to give you something that will work for now, that also continues the dialogue and that can accept a tweak later if need be. This would entail:
Here's the recipe I used to prepare the Red, Orange, Blue, and Info Gray, flipping the chaining will result in different, undesirable values:
You can see there's a better, more re-usable You should go from Light to Dark ready:
I'm going to be traveling for a couple of days but will try to keep an eye on this thread too. |
Thanks for that @machinic ! I tried to change the background color of the |
@shinytang6 i dug into the |
@shinytang6 @catarak Glad to hear we can make these moves. I'm most interested in working out colors that are both appropriate and systematic for each theme to form a coherent design whole — whatever is the most sensible implementation for icons and for the text strings I'm all for. 👍🏻 |
@machinic That would be awesome. Thank you very much! I am preparing the icons according to your suggestion. l think they will be out soon |
This is coming along great! I noticed a couple of things:
|
position: absolute; | ||
|
||
.preview-console__message--info &, .preview-console__message--log & { | ||
background-color: $lightsteelblue; |
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'd prefer for these color variables to be descriptive names: $console-warn-color and so on. you can still keep the other variables as it's nice to documentation what approximately the hex values are, i.e.
$console-warn-color: $orange;
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.
For now, l just put them inside the $theme
, l will modify them if a new design is out :)
var args = Array.from(arguments); | ||
var toString = Object.prototype.toString; |
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.
to do deep copying, could you use the lodash
method?
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 think we may not be able to do this because the code here will be run directly in the browser and cannot use the third-party libraries, right?
ReactDOM.unmountComponentAtNode(this.iframeElement.contentDocument.body); | ||
} | ||
|
||
handleConsoleEvent(messageEvent) { | ||
if (Array.isArray(messageEvent.data)) { | ||
messageEvent.data.forEach((message) => { |
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 think this loop could be merged with the second one—put everything in an every
loop by piecing out the body of the forEach
and putting it in the every
loop, and return false
if there's an infinite loop.
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 👍
messageEvent.data.forEach((message) => { | ||
const args = message.arguments; | ||
messageEvent.data.every((message, index, arr) => { | ||
const { arguments: args } = message; | ||
Object.keys(args).forEach((key) => { | ||
if (typeof args[key] === 'string' && args[key].includes('Exiting potential infinite loop')) { | ||
this.props.stopSketch(); |
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.
if this is true, you'll probably want to return false, right? maybe you could have some variable outside of the forEach loop, and if it gets set because there is an infinite loop, you could exit from the every
loop early.
thanks for making all of these changes! i'm going to test this a little and make sure it's all working but this looks great. |
Have you tried using methods like var methods = [
'debug', 'clear', 'error', 'info', 'log', 'warn', 'command', 'result', 'table', 'time', 'assert', 'count', 'timeEnd'
]; and that seems for fix it. However, I also tried the following test, from the console.count('Counting numbers')
console.time('Render time')
console.log(
`Console %cformatting https://example.com/linkified`,
'color: red'
)
console.log(
'Functions',
function a() {
console.log(1)
},
[function myFunc() {}]
)
console.table([1, 2, 3])
console.log(
1,
2,
'Mixed types',
{ an: 'object' },
[[[['Recursive types', new Promise(() => {})]]]],
'https://t.com'
)
console.log('Promise object', new Promise(() => {}))
console.log('HTML element', document.body)
console.log('Nested', {
promise: new Promise(() => {}),
html: document.body
})
console.log('Falsey types', false, '', 0, null, undefined)
console.warn('This is a warning', 'message')
console.info('This is an info', 'message')
console.debug('This is a debug', 'message')
try {
nonExistentFunc()
} catch (e) {
console.error(e)
}
console.timeEnd('Render time') and some of these aren't working, specifically console.log('Promise object', new Promise(() => {}))
console.log('HTML element', document.body)
console.log('Nested', {
promise: new Promise(() => {}),
html: document.body
})
try {
nonExistentFunc()
} catch (e) {
console.error(e)
} the error i'm seeing for all of these is the same, which is Uncaught DataCloneError: Failed to execute 'postMessage' on 'Window': #<Promise> could not be cloned. but replace "Promise" with whatever is trying to be logged to the console. This brings up a question for me, which is do we need this function |
Hi @catarak
The reason for this error is that trying to pass an object with methods to window.postMessage. Previous implementation of that is simply Updated: The content of I also considered this question when I first explored this library. But l thought that there would be more adjustments to the code structure to implement it and l wondered if we need to support all these methods and these types of console information? But I can try if we decide to do that. |
I think that if we use the |
@catarak I had some troubles when I tried to use
in l tried to dynamically add some script to iframe using So it seems that the console info of srcdoc cannot be obtained from |
@shinytang6 that's really annoying. i'm gonna do a little research and see what comes up. |
i was looking at how CodeSandbox handles this, and it appears that I'm not totally clear on how this doesn't catch errors that are in the |
@catarak l explored Codesandbox a little and found that its frame runs on an URL of another port so that the window.console can capture the info, it is actually a parent document runs on a different server site. And l just found react-frame-component, l thought this component may help? At least it can hook the iframe, see https://codesandbox.io/s/ry596ko5qq. l will try to send another PR in this week and hope l can work it out :) |
That sounds good, try |
closing this, as #656 starts over and takes this in a different direction. |
Before your pull request is reviewed and merged, please ensure that:
npm run lint
Fixes #123
Thank you!
Ref #7