Skip to content
This repository was archived by the owner on Mar 4, 2020. It is now read-only.

docs(Examples): use sources to render dedicated examples, separate contexts #644

Merged
merged 7 commits into from
Jan 2, 2019

Conversation

layershifter
Copy link
Member

@layershifter layershifter commented Dec 19, 2018

Refs #95, fixes #554.

This PR:

  • removes examples from exampleContext and will require only index.tsx files (Types/index.tsx, Variations/index.tsx)
  • creates a new context for *.source.json files and uses it in ExternalExampleLayout with SourceRender

<>
{element}
{/* This block allows to see issues with examples as visual regressions. */}
{error && <div style={{ fontSize: '5rem', color: 'red' }}>{error.toString()}</div>}
Copy link
Member Author

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.

@layershifter layershifter changed the title [WIP] docs(Examples): use sources to render dedicated examples, separate contexts docs(Examples): use sources to render dedicated examples, separate contexts Dec 19, 2018
@DustyTheBot
Copy link
Collaborator

Warnings
⚠️ There are no updates provided to CHANGELOG. Ensure there are no publicly visible changes introduced by this PR.

Generated by 🚫 dangerJS

@@ -0,0 +1,13 @@
/**
* Get the Webpack Context for doc site example groups.
Copy link
Contributor

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.

Copy link
Member Author

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, '')
Copy link
Contributor

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.

Copy link
Member Author

@layershifter layershifter Jan 2, 2019

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'

export { default as exampleContext } from './exampleContext'
export { default as exampleKebabNameToFilename } from './exampleKebabNameToFilename'
export { exampleGroupsContext, exampleSourcesContext } from './exampleContexts'
export { default as exampleKebabNameToFilename } from './exampleKebabNameToSourceFilename'
Copy link
Contributor

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
Copy link
Contributor

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)

Copy link
Member Author

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
Copy link
Contributor

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[] {
Copy link
Contributor

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`
Copy link
Contributor

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?

Copy link
Member Author

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.

Copy link
Contributor

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!

Copy link
Member Author

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

Copy link
Contributor

@kuzhelov kuzhelov left a 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 👍

@layershifter layershifter merged commit 32c4653 into master Jan 2, 2019
@layershifter layershifter deleted the docs/use-source-render branch January 2, 2019 11:52
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Docs example can be broken and merge into master without any check
3 participants