GithubHelp home page GithubHelp logo

developit / preact-mdl Goto Github PK

View Code? Open in Web Editor NEW
187.0 6.0 26.0 47 KB

:boom: A collection of Preact Components that encapsulate Google's Material Design Lite.

License: MIT License

JavaScript 100.00%
preact mdl material material-design ui ui-kit

preact-mdl's Introduction

preact-mdl

NPM travis-ci

A collection of Preact Components that encapsulate Google's Material Design Lite.

Quick Start

Edit Preact Material Design

Grab the App Skeleton from JSFiddle, Codepen, or Code Sandbox

Using TypeScript? preact-mdl-example is an instant full project setup.

Installation

npm install --save material-design-lite preact-mdl

What does it look like?

See for yourself - preact-mdl powers ESBench and Nectarine.

Here's some live-action demos:


Usage

  • Add MDL stylesheets to your html
<!DOCTYPE html>
<html style="height: 100%; width: 100%;">
<head>
    <meta charset="utf-8">
    <meta name=viewport content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
    <link rel="stylesheet" href="https://code.getmdl.io/1.2.1/material.indigo-pink.min.css">
    <title>Preact-mdl Example</title>
</head>
<body style="height: 100%; width: 100%;">
  <script src="/bundle.js"></script>
</body>
</html>
  • Import mdl module and components from preact-mdl
import { h, Component } from 'preact';
import mdl from 'material-design-lite/material';
import { Button } from 'preact-mdl';

export default class MyButton extends Component {
  render() {
    return(
      <div>
        <Button>I am button!</Button>
      </div>
    )
  }
}

Demos

For now, browse these Open Source projects using preact-mdl:


License

MIT

preact-mdl's People

Contributors

alexkrolick avatar brenapp avatar cvuorinen avatar developit avatar impronunciable avatar joakimbeng avatar mbleigh avatar pitermarx avatar prateekbh avatar rootasjey avatar saboya avatar tbekolay avatar theneikos avatar unindented avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

preact-mdl's Issues

ToDo: Breaking change to update to Preact 7

Preact 7 actually makes MDL vastly easier to work with, because it no longer requires crazy DOM crawling code to evade the recycler. preact-mdl needs to release a new major version that removes all the crawling, and only allows Preact 7+ as a peer dependency.

[MDL bug for info] Cannot dynamically add Tabs

This is for information for anyone else pulling their hair out - there's a fundamental flaw in the implementation of the tabs in MDL that you will hit in any dynamic frontend library.

google/material-design-lite#1165

Due to the way that the elements used for the tabs (and panels) are found and decorated, any tabs added to a tab set after an initial render won't get the JS listeners invoked. I've found that the first tab in the set gets a second listener instead of the second tab getting it.

There's workarounds in the linked issue - I'm trying to find the best one for my use case at the moment.

Slider duplicating on rerender

When I use the Slider component and a rerender happens (state or props change), then the slider will be duplicated.

Might possibly be the same error source as #7? (A problem with the remounting by mdl)

Minimal setup:

class SliderTest extends Component {
  updateState = e => {
    this.setState({
      value: e.target.valueAsNumber
    })
  }

  render(_, { value }) {
    return (
      <div>
        <Slider name='test' min={0} max={100} value={value} onChange={this.updateState} />
      </div>
    )
  }
}

After some changes will render this:

duplicatingslieders

For an example see here:
https://codesandbox.io/s/6wx9r52lw

I will try to tackle this myself as well, but I do not know if my prect / mdl knowledge is enough for that ๐Ÿ˜… .

Documentation

Hey!
Documentation is something really needed here.
reading index.js for props is not really awesome!
do we have something in mind for documentation?
a microsite? another readme?

#HappyToHelp

[Solved] Layout.Drawer rendering issue

Solved

Using the shell pattern instead of re-rendering the root which I should have done in the first place.

Initial post

When a component inside Layout.Drawer is re-rendered, no changes are present.
When using the exact same component out of the Layout.Drawer it works perfectly.
Here is the architecture of the parts related to this issue.

./app.js

export default class App extends Component {

	state = { user: null }

	constructor(props) {
		super(props)
		const config = {
                    ...
		}
		firebase.initializeApp(config)
	}

	render({ }, { user }) {
		return (
			<div id="app">
				<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" />
				<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />

				<Layout fixed-header fixed-drawer>
					<Header title="Blog" />

					<Layout.Drawer onClick={this.toggleDrawer}>
						<Layout.Title>Menu</Layout.Title>
						<SidebarNavigation user={user} onSignIn={this.handleSignIn} onSignOut={this.handleSignOut} />
					</Layout.Drawer>

					<Layout.Content>
						<Router onChange={this.handleRoute}>
							<Home path="/" exact />
							<ArticleDetails path="/article/:articleKey" />
							<ArticleList path="/article-list" />
							<ArticleEditor path="/article-editor" />
							<ErrorRoute default />
						</Router>
					</Layout.Content>
				</Layout>

			</div>
		)
	}

	handleRoute = event => {
		this.currentUrl = event.url
	}

	handleSignIn = () => {
		const provider = new firebase.auth.GoogleAuthProvider();
		firebase.auth()
			.signInWithPopup(provider)
			.then(({ user }) => {
				firebase.database()
					.ref('users')
					.child(user.uid)
					.once('value')
					.then((snapshot) => this.setState({ user: Object.assign(user, snapshot.val()) }))
			})
	}

	handleSignOut = () => {
		firebase.auth()
			.signOut()
			.then(() => this.setState({ user: null }))
	}

	toggleDrawer = () => {
		if (this.base) {
			const layout = this.base.querySelector('.mdl-layout')
			if (layout.classList.contains('is-small-screen')) {
				layout.MaterialLayout.toggleDrawer()
			}
		}
	}
}

./navigation/drawer/index.js

export default class SidebarNavigation extends Component {
  render = ({ user }) => {
    return user && user.admin ?
      (
        <AdminNavigation onSignOut={this.props.onSignOut} />
      ) : (
        <UserNavigation onSignIn={this.props.onSignIn} />
      )
  }
}

./navigation/drawer/user/index.js

export default class UserNavigation extends Component {
  render = () => (
    <Navigation>
      <Navigation.Link href="/">Home</Navigation.Link>
      <Navigation.Link href="/article-list">Articles</Navigation.Link>
      <span onClick={this.props.onSignIn} style="cursor: pointer;">Sign in</span>
    </Navigation>
  )
}

./navigation/drawer/admin/index.js

export default class AdminNavigation extends Component {
  render = () => (
    <Navigation>
      <Navigation.Link href="/">Home</Navigation.Link>
      <Navigation.Link href="/article-list">Articles</Navigation.Link>
      <span onClick={this.props.onSignOut} style="cursor: pointer;">Sign out</span>
      <Navigation.Link href="/article-editor">Editor</Navigation.Link>
    </Navigation>
  )
}

CardMenu doesn't transfer 'for'

Hi,

I cannot get a dropdown menu to work inside of the Card and it seems that the 'for' attribute of the CardMenu is not transferred down to the div.

Would it be possible to support this?

className of instance

should get appended to generated markup's class name list

working without this, makes it a little painful to target components

CSS trouble because of JS-injected stylesheet

I just started to use preact and preact-mdl and like it very much so far. However I had some trouble customizing styles. I am using npm. Is there a convincing reason why you inject the MDL stylesheet via JS __$styleInject (as part your build-toolchain) ? Well, one HTTP request less. But customizing styles, e.g. positioning fab buttons then needs !important, at least when using normal stylesheets. And how do I use an alternative stylesheet with different color theme ? The stylesheet also gets loaded later (the JS must be loaded and parsed first)

btw. a few days ago, MDL 1.1.1 got released, with Lists, Dialogs, Snackbar/Toast components.

`mdl-card--expand` at title level

I was trying to reproduce the following example from the documentation:

<div class="demo-card-image mdl-card mdl-shadow--2dp">
  <div class="mdl-card__title mdl-card--expand"></div>
  <div class="mdl-card__actions">
    <span class="demo-card-image__filename">Image.jpg</span>
  </div>
</div>

I was doing the following:

<Card className='demo-card-image' shadow='2'>
  <Card.Title expand></Card.Title>
  <Card.Actions>
    <span className='demo-card-image__filename'>Image.jpg</span>
  </Card.Actions>
</Card>

Which results in:

<div shadow="2" class="mdl-card demo-card-image mdl-shadow--2dp">
  <div expand="true" class="mdl-card__title mdl-card__title--expand"></div>
  <div class="mdl-card__actions">
    <span class="demo-card-image__filename">Image.jpg</span>
  </div>
</div>

The problem is that expand gets converted into mdl-card__title--expand instead of mdl-card--expand...

Is there a way to generate the right markup, without resorting to className?

Strange <List> Behavior when using preact-router

Replication Instructions:

  1. You can see this issue in a staging version of my app. Go here, and click the first item on this list, when it appears.
  2. Go back using your browser back button
  3. Attempt to click on the navigation icon again
  4. It disappears and will only reappear when you hover over it

Some other strange behaviors include: entire list items becoming invisible after repeated back and forth navigation and List Primary Content disappearing.

Notice that I am using the word disappearing. This is because all the elements are still present in the DOM, as you can see from the inspector. But they are invisible. I've ruled this down to a compatibility issue between this module and the MDL CSS, as the issue is not present when the CSS is removed

Sidenote: This may be more relevant on the preact-router repo, ask me if you want to move it

Drawer menu problems

I am observing the following behavior with drawer menu: it works only as long we don't have a state change at the component which contains the Layout. The example below illustrates it, after 10 seconds the drawer hamburger button disappears

componentDidMount() {
  setTimeout( () => this.setState({ foo: "bar" }), 10000);
}

In nectarine, you wire things up manually, maybe that is the way we are supposed to go. However in document viewer your drawer menu seems to work. Is there anything I am missing ?

TypeScript compilation errors

I'm getting:

node_modules/preact-mdl/dist/index.d.ts(12,41): error TS2314: Generic type 'ComponentProps<C>' requires 1 type argument(s).
node_modules/preact-mdl/dist/index.d.ts(13,34): error TS2314: Generic type 'ComponentProps<C>' requires 1 type argument(s).
node_modules/preact-mdl/dist/index.d.ts(15,31): error TS2314: Generic type 'ComponentProps<C>' requires 1 type argument(s).

This can be fixed by changing preact.ComponentProps to preact.ComponentProps<any> in the .d.ts.

  1. Is this happening for everyone?
  2. Should I just send a PR that fixes it with <any>?

Add MDL stylesheets to your html

How to add MDL stylesheets to html, I don't have an index.html file in src
Sorry I'm new to this!

I used preact-cli to create my project using defaults

Relax preact version?

Should we relax the version of the preact peer dependency, so that preact-mdl can be used with 4.x.x too?

Latest `preact`

Can this project be updated to use the latest preact version, or are they incompatible?

Class incompatibility with preact-compat

I've been scratching my head about this for the best part of a day, but have found the origin - I'm not sure whether the issue belongs to preact-compat or preact-mdl though.

If you are using preact-compat and assign a custom class/className to a component, all the MDL classes are removed. Singlestepping through the code I found that the class I assigned was added to both class and className attributes in the VNode (while all the MDL classes were just in the class attribute) and when the component was finally rendered only the classes listed in className actually made it onto the DOM nodes.

The workaround is to not use preact-compat, so that there's no conflict between the class and className attributes. Obviously not ideal in all cases, although the amount of changes required aren't massive and chances are if you're using preact-mdl you've bought into the ecosystem enough to start removing the compatibility layer.

Isomorphic / Server-side rendering support

Hi @developit
Any idea if there is a way to make this render or at least not break server-side?
It looks like mdl needs the global window which obviously doesn't exist in node.
Basically we want the html to be rendered, but nothing of the browser specific window stuff should happen server-side. Is there a kind of unwindow (like undom) or so?
I would really like to know your thoughts on this, thanks.

data-attributes with preact-mdl

Hi,
I would like to use data-attributes with a CheckBox component, but preact-mdl doesn't propogate these through to the input element. Are there any plans to support this?

Cannot read property 'upgradeElement' of undefined

Any component im trying to use i get

Cannot read property 'upgradeElement' of undefined

in the line:

if (this.base && this.base.parentElement) {
this.upgradedBase = this.base;
mdl().upgradeElement(this.base);
}

installed depencies

    "material-design-lite": "^1.2.0",
    "preact": "^5.7.0",
    "preact-mdl": "^1.3.0",

Some props missing from TypeScript typings

Seems like some props are missing from TypeScript typings, specifically the ones that are applicable to many different components, such as ripple, badge & shadow.

If I understand the implementation correctly, badge & shadow (as well as active & disabled) are applied to all components if the prop is present, even though they really make sense to use with only some specific circumstances. Where as ripple prop is only used to turn off the ripple effect on the components that have it specified with the ripple class property. Would probably make sense to only add typings to components where it makes sense to use these props regardless of the actual implementation? I can make a PR for this if it seems reasonable.

mdl-layout__obfuscator does not remove is-visible class

Hi,
I run into this problem whem using the component Layout.Drawer on small devices.

The problem is basically that the div with class 'mdl-layout__obfuscator' (the gray overlay) some times keeps the class 'is-visible' when the drawer is closed.

I have reproduce this issue and you can find the link below
Link

I am using
material-design-lite version 1.3.0
preact version 8.2.1
preact-mdl version 2.2.1
preact-router version 2.5.5

Invisible errorMessage in TextField

When errorMessage is set on a TextField it is invisible as the default CSS style requires the whole input to be marked with the class 'is-invalid' when errors exist. preact-mdl doesn't do that so it stays invisible.

Are menus working ?

It does not open in my test, when clicking on button, this is how I have wired it up:

<Button id="demo" icon><Icon icon="more_vert" /></Button>
<Menu for="demo" bottom-right={ true } bottom-left={ false }>
  <Menu.Item>Foo</Menu.Item>
  <Menu.Item disabled={ true }>Bar</Menu.Item>
</Menu>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.