-
Notifications
You must be signed in to change notification settings - Fork 53
docs(Examples): use sources to render dedicated examples, separate contexts #644
Conversation
5f7a7ad
to
bcb97e1
Compare
<> | ||
{element} | ||
{/* This block allows to see issues with examples as visual regressions. */} | ||
{error && <div style={{ fontSize: '5rem', color: 'red' }}>{error.toString()}</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.
It's a little clumsy, but it will show us broken examples as visual regressions.
Generated by 🚫 dangerJS |
…b.com/stardust-ui/react into docs/use-source-render
docs/src/utils/exampleContexts.ts
Outdated
@@ -0,0 +1,13 @@ | |||
/** | |||
* Get the Webpack Context for doc site example groups. |
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.
nit: suggest to omit 'Get' verb as these exports just provide corresponding context modules, while 'get' action happens on the client side.
Also, while 'groups' is also correct, would suggest to rename this context to exampleIndexContext
- it will be easier for the reader to immediately infer the files implied by this context, without any additional necessity to remind terminology that is used by docs.
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.
Agree, renamed to exampleIndexContext
and removed the get
verb 👍
// button-example => ButtonExample.source.json | ||
// button-example-shorthand => ButtonExample.shorthand.source.json | ||
return `${_.startCase(exampleKebabName) | ||
.replace(/ /g, '') |
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.
we can be a bit more expressive here. The only source of the whitespace could be either leading or trailing ones of the initial kebab-cased name. So, we might eliminate them before transform will happen, like that:
const trimmedExampleKebabName = exampleKebabName.trim()
return `${_.startCase(trimmedExampleKebabName) ... }...`
While this makes code more efficient, I would put efficiency as the least worthy benefit in this case - the primary goal of this move is rather to improve explicitness of where the spaces (that regex aims to eliminate) might happen from.
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.
Proposed solution is not correct because _.startCase()
will create spaces:
_.startCase('foo-bar')
// => 'Foo Bar'
docs/src/utils/index.tsx
Outdated
export { default as exampleContext } from './exampleContext' | ||
export { default as exampleKebabNameToFilename } from './exampleKebabNameToFilename' | ||
export { exampleGroupsContext, exampleSourcesContext } from './exampleContexts' | ||
export { default as exampleKebabNameToFilename } from './exampleKebabNameToSourceFilename' |
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 not hard to do (which it seems not), I would suggest to rename the reexported entry so it will match the name of the file it is imported from
const exampleSource: ExampleSource = exampleSourcesContext(examplePath) | ||
|
||
return ( | ||
<SourceRender |
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.
still not sure why we are relying on the React Context functionality to render source code - but this is definitely not the point of this PR, we could address this moment later (if necessary)
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'm looking for a better solution there.
new RegExp(`\/${displayName}\/index\.tsx$`).test(path), | ||
) | ||
if (!indexPath) { | ||
return null | ||
} | ||
|
||
const ExamplesElement = React.createElement(exampleContext(indexPath).default) as any | ||
const ExamplesElement = React.createElement(exampleGroupsContext(indexPath).default) as any |
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.
code which also suggests that exampleIndexContext
would aid readability here. With current name used it was necessary for me to verify that all the index files are bundled by exampleGroupsContext
@@ -82,23 +81,24 @@ export default class ComponentExamples extends React.Component<ComponentExamples | |||
) | |||
|
|||
private testExamplesStructure(displayName: string, allPaths: string[]): string[] { |
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.
given the return value of this method, it seems to be a good idea to rename it to something that is more descriptive, like getMissingExamplePaths
- as otherwise it is completely unclear what this method is supposed to return
@@ -82,23 +81,24 @@ export default class ComponentExamples extends React.Component<ComponentExamples | |||
) | |||
|
|||
private testExamplesStructure(displayName: string, allPaths: string[]): string[] { | |||
const examplesPattern = `\.\/\\w*\/${displayName}[\\w\/]*\/\\w+Example` | |||
const allExamplesRegExp = new RegExp(`${examplesPattern}[\\w\.]*\.tsx$`) | |||
const examplesPattern = `\.\/${displayName}[\\w\/]*\/\\w+Example` |
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 seems that there is a problem with the regular expression used here - specifically, with the following part of it:
[\w\/]
Here it seems that the intent is to match either word character or slash, but the problem is that idle slash at start makes this regex to match w
character literally.
This one will work correctly:
[\w\\]
The same problem apparently happens to the rest of the expression, where double slash is used here: \\w+Example
. Am I missing something?
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 simplified it to:
const examplesPattern = `\./${displayName}/[\\w/]+Example`
examplesPattern
is not regex expression, it's a regular string. I'm not sure that we need there regular expressions at all.
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 is much simpler to analyze, thanks!
still there is a problem, unfortunately - and this comes from the fact that slashes are not escaped in the string expression. This is what string expression will be evaluated to: ./displayName/[w/]+Example
(with displayName
='displayName')
And this expression creates several problems:
- each of the path delimiter slashes should be escaped
- dot at the start will match any character (is it our intent, or we would like to match dot literally? could we narrow down the set of characters to match, if so?)
I would see the following string should be used instead:
// here I suppose that intent is to match dot character literally,
// please, make any necessary corrections if it is not
const examplesPattern = `[.][/]${displayName}[/][\w/]+Example`
Please, just verify once again this regular expression before merging these changes. Thank 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.
Sorry, merged before this comment 😿
escaped in the string expression
They will be escaped in new Regexp()
:
const displayName = 'Label'
const r = new RegExp(`\./${displayName}/[\\w/]+Example`)
r.toString() // "/.\/Label\/[\w\/]+Example/"
r.test('./Label/Types/LabelExample') // true
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.
have left several minor comments, but there is one important one that I would like to clarify: https://github.com/stardust-ui/react/pull/644/files#r244656294 . Other than that see these changes being good to merge 👍
Refs #95, fixes #554.
This PR:
exampleContext
and will require onlyindex.tsx
files (Types/index.tsx
,Variations/index.tsx
)*.source.json
files and uses it inExternalExampleLayout
withSourceRender