Giter Site home page Giter Site logo

socketsupply / components Goto Github PK

View Code? Open in Web Editor NEW
84.0 8.0 7.0 7.77 MB

Example Components (Built with Tonic)

Home Page: https://tonicframework.dev

License: MIT License

JavaScript 98.32% CSS 0.99% Shell 0.15% Stylus 0.53%
web-components cba components component-library minimalist minimal ui ui-components ui-design ui-router

components's People

Contributors

aprile avatar bcomnes avatar chicoxyzzy avatar dependabot[bot] avatar filmaj avatar heapwolf avatar helloxiuxiu avatar joemccann avatar jwerle avatar mikeal avatar raynos avatar theashraf 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

components's Issues

Incorrect input padding

When there is no icon there should be no padding to accommodate it on the right hand side of the input.

Issue reRendering the TonicChart component

I am using the TonicChart component. It renders well.

I am trying to make a change programmatically, e.g. changing the width via
document.getElementsByTagName('tonic-chart')[0].reRender({'width': '400px', 'height': '600px', 'src': '{"labels":["Foo","Bar","Bazz"],"datasets":[{"label":"Quxx (millions)","backgroundColor":["#c3c3c3","#f06653","#8f8f8f"],"data":[278,467,34]}]}'})

The component does not render anymore.

Here is a self-contained HTML page that contains the TonicChart code (mostly unchanged).
I have just hardcoded the chart.js and forced the data to be read from the src attribute.

<html>

<head>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<script type="module">
import Tonic from './@socketsupply/tonic/index.js'

export class TonicChart extends Tonic {
  static stylesheet () {
    return `
      tonic-chart {
        display: inline-block;
        position: relative;
      }

      tonic-chart canvas {
        display: inline-block;
        position: relative;
      }
    `
  }


  draw (data = {}, options = {}) {
    const root = this.querySelector('canvas')
    const type = this.props.type || options.type

    if (!this.Chart) {
      console.error('No chart constructor found')
      return
    }

    return new this.Chart(root, {
      type,
      options,
      data
    })
  }

  async redraw () {
    return this.connected()
  }

  async fetch (url, opts = {}) {
    if (!url) return {}

    try {
      const res = await window.fetch(url, opts)
      return { data: await res.json() }
    } catch (err) {
      return { err }
    }
  }

  async connected () {
    let data = null
    this.Chart = Chart // hard-coded


    if (!this.Chart) return

    const options = {
      ...this.props,
      ...this.props.options
    }

    const src = this.props.src
    console.log(src)

    /*
    if (typeof src === 'string') {
      const response = await this.fetch(src)

      if (response.err) {
        console.error(response.err)
        data = {}
      } else {
        data = response.data
      }
    }

    if (src === Object(src)) {
      console.log('object')
      data = src
    }
    */
   data = JSON.parse(src)
    console.log(data)

    if (data && data.chartData) {
      throw new Error('chartData propery deprecated')
    }

    if (data) {
      this.draw(data, options)
    }
  }

  render () {
    const {
      width,
      height
    } = this.props

    this.style.width = width
    this.style.height = height

    return this.html`
      <canvas ...${{ width, height }}>
      </canvas>
    `
  }
}

Tonic.add(TonicChart, 'tonic-chart');
</script>
</head>


<body>
This is a test.

<tonic-chart
    width="500px"
    height="250px"
    src='{"labels":["Foo","Bar","Bazz"],"datasets":[{"label":"Quxx (millions)","backgroundColor":["#c3c3c3","#f06653","#8f8f8f"],"data":[278,467,34]}]}'
    type="line">
</tonic-chart>



</body>

</html>

id attribute not propagated to tonic-button

I use multiple tonic-buttons as part of a larger component, and for this parent component's click handler, I want to figure out which button got clicked. Since the id attribute doesn't seem to get passed along to the final button element created, I can't use e.target.matches, as per tonic event docs to determine which button got clicked.

Also the tonic-button properties lists out id as a property.

If I'm doing it wrong, please let me know :D if not, I can try my hand at a PR! lemme know

Migrate to ESM

Tonic is ESM already. We want components to be ESM as well

Calling `reRender()` from an event handler has suprising behavior

Today I noticed that calling reRender() synchronously from an event handler has suprising behavior.

I have a change handler on a tonic-input to do validation when the input value changes.

By calling reRender() on my component to update the errorMessage on tonic-input I actually mess with the focus / blur state of the tonic-input component.

The order of events is :

  • click away from DOM element after adding text
  • change ; => reRender
  • reRender => TonicInput#setEvents() => focus()
  • blur event but input.focus() is already called so i am still focused on the input even though i clicked away
  • click away again
  • blur fires; working as expected.

Basically the DOM is firing a series of events in an order that makes sense to the browser ['change', 'blur'] and by mutating innerHTML or re-rendering components synchronously in one of those event handlers can cause all kinds of weird side effects that break the flow of events.

Proposed solution

Change the behavior of reRender() to schedule the re-render in the request animation frame. Add a new method called reRenderSync() to force reRender right now if that's the desired behavior.

Alternative solution

We could use some "magic" to only schedule a reRender() in request animation frame if we are currently inside an event handler by setting a global boolean in handleEvent() ; this means that reRender() becomes reRenderSync() if called outside of an event handler.

CSS Build Artifacts

We should allow a build option where instead of the styles being inlined with the component and attached to a style element at runtime, they can be compiled to a single build artifact. This way the user can include the css any way they want and we can take better advantage of caching.

TonicRouter seems to have issues working with hash fragments

I want to host my Tonic app using static file hosting, so I can't have users request paths that don't really exist (actually I am experimenting with web extensions, so it's not really hosted at all). That's why I keep my application paths inside the hash fragment of the URL. I can't get TonicRouter to match these, though.

Initially I only got a blank page (so not even the none router matched), but I managed to resolve that using the pushState-hack. but still, I am not able to get it to match the itworks-router.

Is this intended?

import Tonic from '@socketsupply/tonic';
import {TonicRouter} from '@socketsupply/components/router';

class MWE extends Tonic {
   connected () {
    window.history.pushState({},"", window.location); // HACK
    this.addEventListener('match', this.reRender);
  }
  
  render () {
    return this.html`
      <tonic-router id="itworks-router" path="/#/itworks">
        it works
      </tonic-router>
      
      <tonic-router id="notfound-router" none>
        it at least sort of works
      </tonic-router>
    `;
  }
}

Tonic.add(TonicRouter);
Tonic.add(MWE);

document.body.innerHTML = '<m-w-e id="container"></m-w-e>';

Add a way to force close a tonic-split

I couldn't find any way to close a split run, calling toggle() sometimes opens it

I ended up doing

const splitRun = document.querySelector('#split-run')
if (splitRun) {
  const isOpen = splitRun.right.style.width && splitRun.right.style.width !== '0px'
  if (isOpen) {
    splitRun.toggle('right')
  }
}

First check if its open and only if its open call toggle to close it. cc @heapwolf

Dialog height

Make height of dialog automatically adjust to content if height="auto".

Inline toaster can get in the way of input elements

Thanks for the tonic and components libraries! I really like them!

I have a problem on desktop Chrome (Version 75.0.3770.142 (Official Build) (64-bit) on Mac) where clicking on a tonic-input sometimes doesn't register. I have to 'search' around the input area with my mouse before the cursor will turn into a type cursor, and I am able to click into the input and start typing.

After some digging around, it turns out that an inline-toaster component, which is disabled, that I placed right before the input in the document, is somehow getting in the way and making it difficult to click into the input. Perhaps best shown with a screenshot:

Screen Shot 2019-07-23 at 5 35 20 AM

In the above screenshot, trying to click into the input in the upper-half of the input won't work, i.e., clicking into the green area of the screenshot no workie. Turns out the div.tonic--main component highlighted in the screenshot is part of the inline-toaster component.

Here's the relevant markup:

    return `
      <h3>Create a new note:</h3>
      <tonic-toaster-inline id=error-toast type=danger dismiss=true
        display=${error ? 'true' : 'false'}>
        ${error}
      </tonic-toaster-inline>
      <form name="new_note" action=${ROOT}api/notes method=post>
        <tonic-input
            label="Note"
            type=text
            id=note_body
            name=note
            placeholder="Enter your note"
            spellcheck=false>
        </tonic-input>
        <tonic-button async=true id=note_submit>
            Submit
        </tonic-button>
      </form>

I'm using tonic v9.0.5 of tonic and v5.2.4 of components.

Thanks in advance for any help!

namespace all classes used interally

To prevent any collisions with user css, all classes used internally should be prefixed in the following format...

.library--component--classname

For example...

.tonic--windowed--outer

Actual reference here

Support inline tonic-dialog

I was trying to get tonic-dialog to work in a declarative way instead of in a sub class way

For example

class InlineDialog extends Dialog {
  render () {
    return this.html`
      ${this.childNodes}
    `
  }
}
Tonic.add(InlineDialog)

For the dialog really all I wanted was to just to <tonic-dialog><div>...</div></tonic-dialog>

However the implementation of tonic-dialog is completely different to the implementation of every other component because it uses the DOM api to build nodes instead of HTML and thus doesn't get to benefit from any of the _prop or _placehold logic in tonic.

create a scrollable component

a pattern we've noticed is that we have a <section class="scrollable">...</section> tag in some places with the appropriate overflow set on it. The scrollTop position often needs to be remembered, a component that had this in its state would be useful.

Windowed: Allow text selection for the rows.

When using the windowed component to create a table, it can be useful to allow text selection to copy content from the scrollview.

This would only be useful for some tables / windowed sub classes.

tonic-input cuts off content if content contains a double-quote and you re-render it

A way to reproduce this is for example:

      <form name="new_note" action=/api/notes method=post>
        <tonic-input
            label="Note"
            type=text
            id=note_body
            name=note
            placeholder="Enter your note"
            spellcheck=false>
        </tonic-input>
        <tonic-button async=true id=note_submit>
            Submit
        </tonic-button>
      </form>

And then have this code in the click handler:

  click (evt) {
    // TODO: a problem here when you enter double quotes - upon submitting the
    // input text gets cut off at the double quote. weird.
    if (Tonic.match(evt.target, 'tonic-button#note_submit')) {
      const note_body = this.root.querySelector('#note_body');
      const submit = this.root.querySelector('#note_submit');
      if (note_body.value.length === 0) {
        note_body.setInvalid('Note cannot be empty!');
        evt.preventDefault();
        submit.loading(false);
        return;
      }
      note_body.setValid();
    }
  }

If you enter a value into the input that contains a double quote, say my"note, and click the button, you'll notice that before the form POSTs to the server, the note content will cut off at the double quote. I dug around a bit and it turns out that it's caused by the call to setValid(). That eventually routes to code inside the tonic repo, and in particular, here: https://github.com/heapwolf/tonic/blob/master/index.js#L129

The content variable returned by the above line contains the HTML for the input and the double quote is not being escaped inside the <input> tag value attribute. So upon calling setValid(), the input inside tonic-input looks something like <input type="text" value="my"note /> - and so the rest of the note gets cut off.

Checkbox click issue

If checked attribute isn't specified, the client event does not appear to fire when the label is clicked.

how to run tests?

would be nice to have docs around that in the readme so that I can send PRs more easily ๐Ÿ˜„

and i could even try to set up CI for it

Template string not working in component attribute

<tonic-chart
  type="line"
  width="600"
  height="150px"
  options="${opts}"
  src="./chartdata.json">
</tonic-chart>

The value of options when passed to the component is {0: '$', 1: '{', 2: 'o', 3: 'p', 4: 't', 5: 's', 6: '}' instead of the value of opts.
I have tried with backsticks and I am getting the same result.

Am I missing something?

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.