Closed BSarmady closed 4 years ago
What i have done is just copied the CSS and JS CDN code into a local file and just named them material.css
and material.js
respectively.
Having fully compiled components just sitting in the repo it kind of not needed. If you really want to have more modularity with the components in your final compiled file instead of doing the CDN way above, then you can just run a quick development instance of the repo, pick out the components that you want and save the compiled file into whatever project you want.
Thank you for reply and apologize for long comment before hand.
That is what I did, I have a local copy of the material-components-web.min.css
and material-components-web.min.js
but I still haven't achieve anything.
lets say I want to put a drawer in my page. For the sake of argument, lets say it is a pure javascript page which doesn't use any frameworks (well it still does use jQuery, vue and a few others)
I look at web catalog and like the look of Modal Drawer
and want to use that. No source code is available in that page, and I can't right click and view source to see how you did it, because demo is react application and minified too. I'll try to find that information links provided under Resources,
Material Design Guidelines
, well I don't need that yet, I have to put the drawer in my page before looking at do or don'tDocumentation
, nice I can read and implement it word by word so I have drawer on my page (continues below).Source Code
which are a bunch of typescripts. I can't use them in my pure JavaScript page and readme.md at the bottom of page is same as document in 2nd link.Now I follow the documentation word by word.
npm install @material/drawer
Don't need this one, I believe the script is already included in the version that I have downloaded from CDN. And anyway, my pure javascript page doesn't use node or npm
Icons
Sure I'll add following to head of my page
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
Styles
Isn't that already included in the material-components-web.min.css
downloaded from CDN?
JavaScript Instantiation
The one I want is other variants, so I add following lines to my HTML page. and because you didn't use document.ready
I put the script at the bottom of the page to make sure all elements are loaded.
<script>
import {MDCDrawer} from "@material/drawer";
const drawer = MDCDrawer.attachTo(document.querySelector('.mdc-drawer'));
</script>
variants
Now from under variants
section I go and copy the HTML code under Modal Drawer
section to my HTML page. rest of the document is about customization. There was a Javascript to allow clicking on the hamburger icon to activate or deactivate the drawer which is under Dismissible Drawer
I think I'm gonna need that too even though that script is under different section.
Now my HTML looks like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="stylesheet" href="fonts/MaterialIcons.css">
<title>Material Components Web | Catalog</title>
<link type="text/css" rel="stylesheet" href="material-components-web.min.css">
<script type="text/javascript" src="material-components-web.min.js"></script>
</head>
<body class="mdc-typography">
<aside class="mdc-drawer mdc-drawer--modal">
<div class="mdc-drawer__content">
<nav class="mdc-list">
<a class="mdc-list-item mdc-list-item--activated" href="#" aria-current="page">
<i class="material-icons mdc-list-item__graphic" aria-hidden="true">inbox</i>
<span class="mdc-list-item__text">Inbox</span>
</a>
<a class="mdc-list-item" href="#">
<i class="material-icons mdc-list-item__graphic" aria-hidden="true">send</i>
<span class="mdc-list-item__text">Outgoing</span>
</a>
<a class="mdc-list-item" href="#">
<i class="material-icons mdc-list-item__graphic" aria-hidden="true">drafts</i>
<span class="mdc-list-item__text">Drafts</span>
</a>
</nav>
</div>
</aside>
<div class="mdc-drawer-scrim"></div>
<div>Main Content</div>
<script>
import {MDCList} from "@material/list";
const list = MDCList.attachTo(document.querySelector('.mdc-list'));
list.wrapFocus = true;
import {MDCDrawer} from "@material/drawer";
const drawer = MDCDrawer.attachTo(document.querySelector('.mdc-drawer'));
import {MDCTopAppBar} from "@material/top-app-bar";
const topAppBar = MDCTopAppBar.attachTo(document.getElementById('app-bar'));
topAppBar.setScrollTarget(document.getElementById('main-content'));
topAppBar.listen('MDCTopAppBar:nav', () => {
drawer.open = !drawer.open;
});
</script>
</body>
</html>
This page is in my Apache and browsing with Firefox, and .... Nothing on screen! Checking the javascript console:
SyntaxError: import declarations may only appear at top level of a module
Hmmm! ok! I'll add type="module" to script tag and refresh the page, no error this time but still nothing!
This is what I meant when I said, These components are hard to use.
Now let me give you an example of JQueryUI, but this time with no director commentary. Also there is no drawer in jQueryUI so I'm go with Modal Dialog instead.
Go to demo page for dialog, click on view source link
below demo frame
and copy the whole HTML to your file and browse it (of course from a Web Server) and it already works. and next is just mater of customizing the dialog.
If you inspect the code you'll see that all you need to create the dialog is a DIV
to put dialog content in, then call the dialog function ($( "#dlgDiv" ).dialog();
) on it. All the styles will be added by JavaScript. I can also pass options to dialog function like $( "#dlgDiv" ).dialog({option1:'somevalue'});
<div id="dlgDiv" title="Basic dialog">
<p>This is the default dialog which is useful for displaying information.</p>
</div>
<script>
$("#dlgDiv").dialog();
</script>
In an ideal case for Material components I should have something like this to show the drawer and then call a Javascript function like following to make it operational
<aside id="modal-drawer">
<div>
<nav>
<ul>
<li data-icon="inbox" data-link="Inbox">text</li>
...
</ul>
...
</nav>
</div>
</aside>
<script type="module">
const drawer = MDCDrawer.attachTo(document.querySelector('#modal-drawer'));
</script>
or even better if those functions are prefixed like jquery, for example:
<script type="module">
const drawer = MDC.Drawer(document.querySelector('#modal-drawer'));
</script>
I fully agree that these component are hard to use. If you don't go though the 'normal' dev environment then it takes a bit of set up. It took me like 2 months to properly figure out what I was doing using the CDN version. If you are looking for working drawer code, this is code that I'm using on one of my apps:
const drawer = mdc.drawer.MDCDrawer.attachTo(document.querySelector('.mdc-drawer'));
const topAppBar = mdc.topAppBar.MDCTopAppBar.attachTo(document.getElementById('app-bar'));
topAppBar.setScrollTarget(document.getElementById('main-content'));
topAppBar.listen('MDCTopAppBar:nav', ()=> {
drawer.open = !drawer.open;
});
If you are going to continue using the CDN version (or the local copied code), then you need to define a variable by going:
const newBtn = mdc.button.MDCButton.attachTo(document.querySelector('.newBtn'));
As is shown in the quick start guide on the main README.md page at the top.
(And no I don't believe that the icons are included as that is maintained by a separate part of google. Not 100% sure about that though)
CyborgSemon, thank you for the example.
I'm sure icons are not included in CDN, but styles are.
So from my understanding, if I'm using a components, I will need to call them like mdc.[compoent name in lowercase].MDC[Component name in Camel case].
There are few questions
Do I need to make a constant to be able to access same element instance of component again? Is there any other way to access components after they are created? there are situations that I need to access a element from different script and they might not exist. I don't have a way to force my team to use same constant name for their drawer for example. but they won't be able to change '.mdc-drawer'
Is there a reason for component paths being that deep mdc.button.MDCButton.attachTo()
instead of just MDCButton.attachTo()
?
[EDIT] removed the last question, it was my mistake. latest version does work with Firefox 54 and above.
In order of your questions:
Yes you do.
No you don't have to make it a constant, or even a variable. You can just call the .attachTo()
method to an element and leave it at that. It is just recommenced that you save the attached component to a variable because if you don't, I don't believe you can re-select the component version of the element. (I might be wrong here. But you should just save it as a variable anyway if you plan on using any of the methods / values later.)
You should check out the importing JS documentation. The CDN version imports the JS slightly differently compared to going through the 'normal' dev environment. The way that the docs suggest that you set up the variables for the CDN way is to do it like this.
const MDCButton = mdc.button.MDCButton;
That way you then don't have to type out the mdc.button.MDCButton
all the time. You can then just do this:
const newBtn = MDCButton.attachTo(document.querySelector('#newBtn'));
It should be working? You can check the version of the CDN by the url. The supplied one should say @latest
somewhere in the URL, that will then change to the version number when you visit the link in your browser. So for example, currently if you were to visit the link it would replace latest with @3.2.0
Hope this helps :)
I have tried to use these components because I thought they were much more complete than others like Materialize. But something as trivial as placing grids inside a container and expecting them to be centered without occupying the entire viewport is impossible even though the same documentation uses components that do things like these but are not included in the final package.
the only thing left of this painful experience with packages that you must compile yourself is that I learned Babelify in the painful way ... so thank you?
@kurai021
But something as trivial as placing grids inside a container and expecting them to be centered without occupying the entire viewport is impossible
Can you provide a codepen example? Because I think I've done exactly what you have described here in a project of mine.
the only thing left of this painful experience with packages that you must compile yourself is that I learned Babelify in the painful way ... so thank you?
Then just use the CDN? It's not that hard to just set up a compiling environment using the getting started guide.
Thanks for your feedback! If you haven't already, I'd also suggest taking a look at Material web components. Our hope is that this will be an easier way to consume Material on the web and address these concerns.
A few years back when these components just started, I requested a feature to add compiled versions without any compile requirement from users. This is still not happened.
The way these components are published is like you go buy a can of soup from supermarket and they give you a can of water and instruction saying
Notice the issue? There is no recipe for cooking in normal soup pan, you need to buy chicken, clean it, cut it, buy vegetables, clean it, wash it, chop it and then cook them all yourself!
If you look at jQuery UI components, you can select version, tick the components you need and download it, usage is as easy as adding a CSS and a JS to your page and the rest is your pure knowledge of CSS, JS, JQuery and JQuery UI components themselves.
With current state of your components, a user (developer) need to know how to use npm, nodejs, webpack and many other tools so the can just compile the components. And this is just the start, you still need to figure out how to put that component in your page. You have covered advanced uses of your components in angular and react. But there is no mention of how to use them with simple pure JavaScript on an HTML page?
I am using these components on one project since last year, and guess what, I couldn't build the package due to compile errors and gave up. Instead downloaded the JS and CSS from your demo pages.
Just a note, a developer working in mission critical and high security industry such as finance, insurance, health or an enterprise, can't just install whatever tools they like, they might be on intranet with no Internet access on all the stations. You can't use CDN as source of your components (Referer headers security).
In an Industry that customers only have basic knowledge of computer, you can't just support last 2 versions of the browser. I still have customers that use Firefox 36 on windows XP. I'm not expecting you to support past 20 version of the browser, that is my job. IMHO, it is lazy to test just for last 2 version of browsers (which makes it like 10 browsers?) I think a component should work on at least latest + LTS versions or alternatively older components should be available for download too, in case support for older browsers are needed.
As others also mentioned, because you need to learn how compile these components too, using them becomes troublesome and learning curve too steep. I rather use bootstrap and jQuery UI instead even though I like to use Material.IO very much.
I appreciate if you could add compiled versions of your code for download (simply a JS and CSS) too. and clear working sample that doesn't require me to open source of pages and track what is running and how is running.