Skip to content
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

[docs-infra] Support multiple tabs in demos #40901

Merged
merged 18 commits into from Apr 17, 2024

Conversation

bharatkashyap
Copy link
Member

@bharatkashyap bharatkashyap commented Feb 2, 2024

Open to suggestions on how to make all files real-time editable, since the option I had in mind (which would require updating the react-runner instance scope Modules every time an import was changed) seems to me a bit too complex to become part of the v1 implementation.

Preview (Autocomplete): https://deploy-preview-40901--material-ui.netlify.app/material-ui/react-autocomplete/

Tab A Tab B
Screenshot 2024-02-02 at 7 46 47 PM Screenshot 2024-02-02 at 7 47 34 PM

@bharatkashyap bharatkashyap added the docs Improvements or additions to the documentation label Feb 2, 2024
@mui-bot
Copy link

mui-bot commented Feb 2, 2024

Netlify deploy preview

https://deploy-preview-40901--material-ui.netlify.app/

Bundle size report

No bundle size changes (Toolpad)
No bundle size changes

Generated by 🚫 dangerJS against 3f90f79

@danilo-leal danilo-leal changed the title [docs] Support multiple tabs in demos [docs-infra] Support multiple tabs in demos Feb 2, 2024
@danilo-leal danilo-leal added scope: docs-infra Specific to the docs-infra product and removed docs Improvements or additions to the documentation labels Feb 2, 2024
@danilo-leal danilo-leal changed the base branch from master to next February 2, 2024 21:41
@danilo-leal danilo-leal changed the base branch from next to master February 2, 2024 21:42
@danilo-leal

This comment was marked as resolved.

@michaldudak
Copy link
Member

This is so good! Thanks for working on it!

I wonder if we still need the collapse/expand button. Or perhaps it can simply adjust the max height of the code container instead of extracting the return value of the main function. cc @danilo-leal

I've noticed that the JS/TS switch doesn't work. The JS source is always displayed.

@bharatkashyap
Copy link
Member Author

I've noticed that the JS/TS switch doesn't work. The JS source is always displayed.

That is probably since the Combo Box demo has identical source for both cases; I've only added this to one demo for a proof of concept. I'll add it to a second with different sources to demonstrate JS/TS source switching working as expected

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Feb 12, 2024
@danilo-leal
Copy link
Contributor

Just realized that the styles we added to make the tabs fit nicely within a demo container break them when in a standalone tabbed code block. For example, the installation commands one:

Screenshot 2024-02-12 at 18 47 26

Should we make these different components? Or some other strategy for applying the styles depending on the context?

Copy link
Member

@oliviertassinari oliviertassinari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A quick review, great to see this making progress 👍

Comment on lines 159 to 160
'docs-components-autocomplete-data', // No components, contains only data for the demo
'docs-components-transfer-list-utils', // Commont utilities for demos
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these should be handled automatically. It doesn't scale to ignore folders and non React components manually.

Suggested change
'docs-components-autocomplete-data', // No components, contains only data for the demo
'docs-components-transfer-list-utils', // Commont utilities for demos

To ignore files that don't follow the ComponentName React convention.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be a standalone PR, he hit the same pain with: docs-getting-started-templates-landing-page/getLPTheme.png.

Comment on lines 13 to 12
function not(a: readonly number[], b: readonly number[]) {
return a.filter((value) => b.indexOf(value) === -1);
}

function intersection(a: readonly number[], b: readonly number[]) {
return a.filter((value) => b.indexOf(value) !== -1);
}

function union(a: readonly number[], b: readonly number[]) {
return [...a, ...not(b, a)];
}
import { intersection, union, not } from './utils/helpers.js';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks fine to test the PR out, but I don't think this should be deduplicate for the final version of the PR.

Comment on lines 4 to 5
'no-console': ['off', { allow: ['info'] }],
// not very friendly to prop forwarding
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That file looks like technical debt to me. This should be in the root .eslintrc file

Suggested change
'no-console': ['off', { allow: ['info'] }],
// not very friendly to prop forwarding

@@ -1,6 +1,7 @@
import * as React from 'react';
import TextField from '@mui/material/TextField';
import Autocomplete from '@mui/material/Autocomplete';
import top100Films from './data/top100Films.js';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect:

Suggested change
import top100Films from './data/top100Films.js';
import top100Films from './data/top100Films.ts';

or likely:

Suggested change
import top100Films from './data/top100Films.js';
import top100Films from './data/top100Films';

to keep it simple

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean that the relative imported package should always be a .ts file?

What I'm thinking is if there is no extension, it would become a lot more complicated to figure out which file to load when resolving these relative imports in loader.js

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume you're importing .js because it can be imported in both JS and TS.

IMO it can be kept as it is, and in further step, write imported files with TS and modify the docs:typescript:formatted script to generate the imported file in JS, and update the import line

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexfauquette By as it is do you mean keep the .js extension?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

docs/src/modules/components/Demo.js Outdated Show resolved Hide resolved
docs/src/modules/components/DemoEditor.tsx Outdated Show resolved Hide resolved
@@ -332,9 +332,25 @@ export default function DemoToolbar(props) {
const handleSnackbarClose = () => {
setSnackbarOpen(false);
};

const copyWithRelativeModules = React.useCallback(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why have this in the scope of the component? Why not in the parent scope called from demoData?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean why not move this function (including the clipboard-copy dependency) to the parent scope of Demo.js?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To the root scope of DemoToolbar.js

extractImports(demos[demoName].raw).forEach((importModuleID) => {
// detect relative import
// skip for modules that are not demos
if (!toolbarHidden.has(moduleID.replace('./', ''))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I guess this could ship as its own PR optimizing things?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean taking this part apart into a separate PR focussed only on optimisation? I'd imagine this can stay, whereas future optimisation can go in a new PR

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should have this as a standalone win/PR. If you go to https://mui.com/material-ui/react-grid/#interactive. Why are we loading the source to make that demo editable? Doesn't make sense.

docs/src/modules/components/HighlightedCodeWithTabs.tsx Outdated Show resolved Hide resolved
@oliviertassinari
Copy link
Member

oliviertassinari commented Mar 3, 2024

@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Mar 5, 2024
@danilo-leal
Copy link
Contributor

@bharatkashyap is there anything I can do to help this PR move forward? 😃

@bharatkashyap
Copy link
Member Author

@bharatkashyap is there anything I can do to help this PR move forward? 😃

Haha, I guess not 😅 It needs some final work to address review feedback - I've planned to close it this week

@oliviertassinari oliviertassinari added the new feature New feature or request label Mar 12, 2024
Copy link
Member

@oliviertassinari oliviertassinari left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Pre-v1:

For v1:

  • TypeScript support
  • Atomic commit for state change

For v2:

For a v3

  • TS/JS switch using useTransition

@@ -0,0 +1,11 @@
export function not(a, b) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export function not(a, b) {
export function not(a: readonly number[], b) {

docs/src/modules/components/HighlightedCodeWithTabs.tsx Outdated Show resolved Hide resolved
@@ -332,9 +332,25 @@ export default function DemoToolbar(props) {
const handleSnackbarClose = () => {
setSnackbarOpen(false);
};

const copyWithRelativeModules = React.useCallback(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To the root scope of DemoToolbar.js

extractImports(demos[demoName].raw).forEach((importModuleID) => {
// detect relative import
// skip for modules that are not demos
if (!toolbarHidden.has(moduleID.replace('./', ''))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should have this as a standalone win/PR. If you go to https://mui.com/material-ui/react-grid/#interactive. Why are we loading the source to make that demo editable? Doesn't make sense.

Comment on lines 159 to 160
'docs-components-autocomplete-data', // No components, contains only data for the demo
'docs-components-transfer-list-utils', // Commont utilities for demos
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be a standalone PR, he hit the same pain with: docs-getting-started-templates-landing-page/getLPTheme.png.

@siriwatknp
Copy link
Member

siriwatknp commented Mar 13, 2024

nit: I think the underline is not necessary. An active tab should have a background without hover.

image

@@ -1,6 +1,7 @@
import * as React from 'react';
import TextField from '@mui/material/TextField';
import Autocomplete from '@mui/material/Autocomplete';
import top100Films from './data/top100Films.js';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume you're importing .js because it can be imported in both JS and TS.

IMO it can be kept as it is, and in further step, write imported files with TS and modify the docs:typescript:formatted script to generate the imported file in JS, and update the import line

docs/src/modules/components/Demo.js Outdated Show resolved Hide resolved
docs/src/modules/components/DemoEditor.tsx Outdated Show resolved Hide resolved
Copy link
Member

@alexfauquette alexfauquette left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good.

I tried my best to understand the markdown loader, but I probably don't have enough understanding of its behavior to catch bugs.

Comment on lines 171 to 172
});
relativeModuleFilename = `${importModuleID}${extension}`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe throw an error if you do not find the file. to say to the user

Hey in the dem xxx you import yyy which does not exist. PLeas ad either

  • yyy.js
  • yyy.jsx

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thaugh this comment was nitpicking, but in https://github.com/mui/mui-x/blob/master/docs/data/date-pickers/date-picker/CustomizationExamplesNoSnap.js

The .js file imports a .tsx (which is weird) but then the error message on build time is:

Error: Could not find a module for the relative import "./examplesConfig.stylingundefined" in the demo "CustomizationExamplesNoSnap.js"

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I saw that and the latest commit should fix this

@joserodolfofreitas
Copy link
Member

joserodolfofreitas commented Apr 9, 2024

Quick question: Once this PR is merged, can we bring the feature to MUI X directly?

@alexfauquette
Copy link
Member

Yes, I tried the PR here: mui/mui-x#12714

// If the demo is a JS demo, we can assume that the relative import is either
// a `.js` or a `.jsx` file, with `.js` taking precedence over `.jsx`
// likewise for TS demos, with `.ts` taking precedence over `.tsx`
const extensions = variant === 'JS' ? ['.js', '.jsx'] : ['.ts', '.tsx', '.js', '.jsx'];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To support https://github.com/mui/mui-x/blob/master/docs/data/date-pickers/date-picker/CustomizationExamplesNoSnap.js

Suggested change
const extensions = variant === 'JS' ? ['.js', '.jsx'] : ['.ts', '.tsx', '.js', '.jsx'];
const extensions = variant === 'JS' ? ['.js', '.jsx', '.ts', '.tsx'] : ['.ts', '.tsx', '.js', '.jsx'];

packages/markdown/loader.js Outdated Show resolved Hide resolved
packages/markdown/loader.js Outdated Show resolved Hide resolved
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Apr 11, 2024
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Apr 11, 2024
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Apr 12, 2024
@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Apr 12, 2024
@bharatkashyap
Copy link
Member Author

@danilo-leal This is okay to merge as a v1 for me, pending a review from you around how it looks 😅

@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Apr 16, 2024
@danilo-leal
Copy link
Contributor

Looks great to me! I only noticed that the borders on the code block/editor and the demo toolbar are a bit funky—they appear and disappear depending on the mode/tab selected. Check it out:

Screen.Recording.2024-04-16.at.18.49.31.mov

The demo toolbar has a top border in light mode. But, it seems the code block/editor loses its borders on the second tab.

Screen.Recording.2024-04-16.at.18.49.59.mov

In dark mode, the demo toolbar doesn't have both a top and bottom border anymore.

I thought I had fixed these things on #41827 😅 I'll leave you to it as I'm having weird conflicts to pull the latest changes from this PR, so it should be faster if you can tackle it. Later design improvements can come iteratively right after, I think!

@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Apr 17, 2024
@alexfauquette
Copy link
Member

@danilo-leal I tried to fix it in
c43ca52

In light mode, the code has no border because the contrast between code and the background is enough

In dark mode keep the border gray,

Copy link
Contributor

@danilo-leal danilo-leal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's 🚢 it!

@bharatkashyap bharatkashyap merged commit c7bc3ed into mui:next Apr 17, 2024
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new feature New feature or request scope: docs-infra Specific to the docs-infra product
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[docs-infra] Support code tabs [docs-infra] Support shared source between demos
9 participants