Giter Site home page Giter Site logo

stimulus-components / stimulus-components Goto Github PK

View Code? Open in Web Editor NEW
960.0 960.0 25.0 1.97 MB

A modern Stimulus library delivering common JavaScript behaviors with a bunch of customizable controllers.

Home Page: https://www.stimulus-components.com/

License: MIT License

JavaScript 1.53% Vue 94.39% TypeScript 4.08%
npm-package rails stimulus-components stimulus-controllers stimulusjs

stimulus-components's Introduction

Stimulus components

πŸ‘‰ Introducing Stimulus components.

πŸ“š Documentation

See Stimulus Components Website.

πŸ‘· Contributing

Do not hesitate to contribute to the controllers by adapting or adding features ! Bug reports or pull requests are welcome.

Don't forget to drop a 🌟 on GitHub to support the project.

πŸ“ License

This project is released under the MIT license.

stimulus-components's People

Contributors

chiastolite avatar cprodhomme avatar elmolesto avatar etcook avatar guillaumebriday avatar guillaumebriday-pa avatar imadilkhalil avatar ishadijcks avatar jmsche avatar jsantos avatar magico avatar ocarreterom avatar sausyn avatar shawnaukstak avatar sho918 avatar thomaslandauer avatar timothyjosefik avatar ur5us 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  avatar  avatar  avatar  avatar  avatar  avatar

stimulus-components's Issues

Nested Sortable issue

Hi there,
I've run into an issue with a sortable list that contains sortable lists, a minimal example being:

<div data-controller="sortable">
    <div data-controller="sortable" class="inner-list">
        <div>item 1a</div>
        <div>item 1b</div>
    </div>
    <div data-controller="sortable" class="inner-list">
        <div>item 2a</div>
        <div>item 2b</div>
    </div>
</div>

The observed behavior is that sorting the items inside the "inner-lists" works as intended, but sorting the "inner-lists" themselves doesn't work correctly. After grabbing an "inner-list" and moving it, it gets locked into the first new position it enters, and can't be moved around any more (i.e. back to its original position) until the drag is released and a new one is initiated. Based on some additional testing, it also seems like the "end" event doesn't fire when dragging an "inner-list". Removing the controller from the "inner-list" allows the outer sortable to function again. Unfortunately there are no errors in the console so I don't have much else to help diagnose this issue, or any way to find a workaround.
Thank you!

Quick input validator

Hi, I just added a quick input validator on a rails app I'm working on. If there's some interest to adding something like that to stimulus-components, I wouldn't mind giving it a go.

If a field is required, submit button is disabled.
image

When the user inputs some text, submit button is enabled.
image

Feature request: Modal component

Hello!

First off, this project looks amazing. Awesome work πŸŽ‰

I was wondering if there are any plans for or if you'd consider adding a Modal component. Something like this:

<div data-controller="modal">
  <a href="#" data-action="modal#show">Click me</a>
  <div data-modal-target="overlay">
    <!-- modal overlay here -->
  </div>
</div>

with support for transitions and all the other bells and whistles that the existing components have.

rails stimulus:manifest:update removes components from manifest

Hello,

Having an issue with the way we import stimulus components.
Every component installation is made using yarn install stimulus-component-xyz and manually editing index.js to add the new component.

My problem lies with the command found on hotwired/stimulus-rails

rails stimulus:manifest:update

I use it to add my own controllers and ensure old ones are removed from the index.js
The problem is that it also removes the stimulus component i added manually.

What's expected

Stimulus components import method should not be deleted when using rails stimulus:manifest:update. I doubt it's doable though since we have no control over this.
At least documentation should warn us from using that command and provide an alternative since hotwired is the default way in rails 7 this will probably happen to more people.

What's happening

Running rails stimulus:manifest:update removes all manually added stimulus components

Repro

  1. clone the repository

  2. notice app/javascript/controllers/index.js contains:

import ScrollTo from 'stimulus-scroll-to
application.register('scroll-to', ScrollTo)
  1. Run rails stimulus:manifest:update
  2. Notice that app/javascript/controllers/index.js no longer holds references to scrollTo component

Should I just stop using rails stimulus:manifest:update and only create my controllers using rails generate stimulus controllerName ?

Thank you

Toggle Element controller

Just a simple controller to toggle elements outside the scope of the controller itself.

import { Controller } from '@hotwired/stimulus'


export default class extends Controller {
  static classes = ['hidden']

  static values = {
    id: String,
  }

  initialize() {
    this.class = this.hasHiddenClass ? this.hiddenClass : 'hidden'
  }

  connect() {
    this.element.addEventListener('click', this.toggle)
  }

  disconnect() {
    this.element.removeEventListener('click', this.toggle)
  }

  toggle = () => {
    const element = document.getElementById(this.idValue)
    if (element) {
      element.classList.toggle(this.class)
    }
  }
}
<button type="button" data-controller="toggle-element" data-toggle-element-id-value="menu">
  Toggle menu.
</button>

<div>…</div>

<nav id="menu"></nav>

Maybe this could be useful for others too. I'm not sure about the naming though. (And a selector instead of an id could possibly make more sense.) What do you think?

Btw. thank you for this project; It helped me a lot in understanding stimulus! ❀️

Google Tag Manager controller

Adding Google Tag Manager on a website is pretty much:

  1. an initializer:
    <!-- Google Tag Manager -->
    <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
    new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
    j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
    'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
    })(window,document,'script','dataLayer','GTM-XXXX');</script>
    <!-- End Google Tag Manager -->
  2. a bunch of objects pushed into a global array on user events:
    <a href="…" onClick="dataLayer.push({'event': 'someUserAction', someContext: 'whateverYouWant'})">…</a>

I'm pretty sure there's a way to do this using Stimulus, with something like:

<a href="…" data-controller="gtm" data-gtm-event="someUserAction" data-gtm-some-context="whateverYouWant">…</a>

I'm not sure how initialization could be done in a DRY-manner, though πŸ€”
And I'm not sure whether the Stimulus version is actually more or less readable than the onClick version πŸ˜…
But you know, I'm just brain-dumping some use-cases…

Typeahead Controller

  • Enable type-a-head autocompletion on text input or textarea
parameters: {
url: <path> // path to autocomplete data
triggers: ["@", "+", ":"], // characters pressed to trigger type-a-head
}

Component Request - Youtube Video Player

I found that a youtube video component might be useful for those interested in programmatically controlling youtube video or adding analytics.

Here's a very rough example controller I created that might be able to be used as basis for a component:

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static values = {
    id: String,
    height: {type: Number, default: 315},
    width: {type: Number, default: 560}
  }
  connect() {
    this.element[this.identifier] = this;

    let tag = document.createElement('script');
    tag.src = "https://www.youtube.com/player_api";
    let firstScriptTag = document.getElementsByTagName('script')[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

    // Replace the 'ytplayer' element with an <iframe> and
    // YouTube player after the API code downloads.
    let player;
    window.onYouTubePlayerAPIReady = () => {
      player = new YT.Player(this.element, {
        height: this.heightValue,
        width: this.widthValue,
        videoId: this.idValue,
        events: {
          'onStateChange': this.onPlayerStateChange
        }
      });
    }

    // Should somehow expose these events in the component
    this.onPlayerStateChange = (event) => {
      if (event.data == YT.PlayerState.PLAYING ) {
        alert(`Play Promo Video at ${Math.floor(player.getCurrentTime())}`);
      }else if (event.data == YT.PlayerState.ENDED) {
        alert("Complete Promo Video")
      }
    }
  }
}

usage:

<div data-controller="youtube-video" data-youtube-video-id-value="qYIG9R7yJ1Q"></div>

NOTE: This is very rough and you can only embed a single video element with this. Being able to handle multiple videos and not rely on a single function call would probably be useful for making this more universal.

Filterable controller

I will probably soon write a little component to filter from a list of html elements.
Interested in something like this, would be happy to contribute that.

<div data-controller="filterable">
  <input data-action="onkeyup->filterable#filter" data-filter-hidden-class="hidden">
  Listing <span data-target="filterable.filteredCount"> entries
  <div data-target="filterable.entry">
    Your content here.
  </div>
  ...
  <div data-target="filterable.noResults" class="hidden">
    Sorry, no results.
  </div>
</div>

stimulus-timeago: Rails helper

Hello!

Any idea why the stimulus-timeago Rails helper doesn't seem to work with any of the locales in say https://github.com/svenfuchs/rails-i18n/?

def timeago(date, format: :long)
  return if date.blank?

  content = I18n.l(date, format: format)

  tag.time(content,
            title: content,
            data: {
              controller: 'timeago',
              timeago_datetime_value: date.iso8601
            })
end

[...]

<p>Created <%= timeago(@project.created_at) %></p>

I get English despite having set a different locale with I18n.locale in my application controller.

Thanks!

Password Controller

I think we need another controller to show / hide passwords in password fields.

Rails 7 - Multiple the same id on select

# model
class RoomType < ApplicationRecord
  ...
  has_many :room_facilities
  accepts_nested_attributes_for :room_facilities, allow_destroy: true, reject_if: :all_blank
  ...
end
# the form
<%= form_with(model: room_type, data: { controller: 'nested-form' }) do |form| %>
...
<%= form.fields_for :room_facilities do |room_facility| %>
    <%= render "facility_field", f: room_facility %>
  <% end %>
  
  <template data-nested-form-target="template">
    <%= form.fields_for :room_facilities, @room_type.room_facilities.build do |room_facility| %>
      <%= render "facility_field", f: room_facility %>
    <% end %>
  </template>

  <!-- Inserted elements will be injected before that target. -->
  <div data-nested-form-target="target"></div>
  <button type="button" data-action="nested-form#add">Tambah Fasilitas</button>
...
<% end %>
# facility_field
<div class="nested-form-wrapper" data-new-record="<%= f.object.new_record? %>">
  <%= f.label :fasility_id %>
  <%= f.collection_select(:fasility_id, Fasility.all, :id, :nama, {include_blank: true}, {prompt: 'Choose'}) %>

  <button type="button" data-action="nested-form#remove">Hapus Fasilitas</button>

  <%= f.hidden_field :_destroy %>
</div>
...

Screenshot from 2023-03-05 14-32-11

There's the same id on the select menu. How do I supposed to make it different? this resulted that only one selected on the last option that choosen into params. didn't care how many attributes that I added, he just choose the last one.

skeleton for new component? Or a github repo template?

I have a small stimulus component I'd like to contribute, as I find it very useful in my own code. It displays languages and countries from their respective ISO codes, saving the user from needing to do the lookup in the server code.

Is there a skeleton for the component repository? The components here seem to all be in TypeScript, I can convert it. But the documentation and such should all be standardized. If there's a skeleton that already exists, I'd love to use it.

Also, what's the procedure for doing this? I can create a repo for testing and such, then move it to here? I'd also like some feedback on my implementation, especially naming the attributes, and even naming the component.

The code itself isn't that complicated, I can also paste it here, since it's just one file.

issue with encoding

When I copy-paste with stimulus-clipboard, the "&" character it returns its HTML code to the clipboard (&amp) , it does that too with < and > (&lt and &gt)

I don't have this problem with a right click then copy-paste.

Great Job

Congratulations to what you are doing Guillaume !
It's great to have created Stimulus components and added more πŸš€.
Thank you.


Bravo Γ  ce que tu fais Guillaume !
C'est super d'avoir crΓ©er des composants Stimulus et d'en ajouter d'autres πŸš€.
Merci.

Stimulus nested form expanded by default

Instead of launching the nested form by pushing a button, is there a way to have it expanded with one record ready to go at first, then push the add button to add more form rows after that?

anchor styling controller

I've written a controller for my purposes, which might yet be useful to the stimulus js community:

What is this?

  • We might have many items on the screen.
  • We might want to highlight some, according to the URL anchor present https://www.example.com/1#anchor_1 - in this case, we might want to highlight elements with a particular matching hash. Of course, if the hash changes, we might want to highlight a new element.

image

If you change the hash, a new element will be highlighted. If you want additional functionality, you can override the controller and specify additional effects etc.

Proposal

If you like it, i can make a PR for this + demo page. pls let me know if it will be useful to the community.

// anchor_styler_controller.js

import { Controller } from "stimulus";

export default class extends Controller {
  static classes = ["highlight"]  

  static values = { matchingId: String}  

  static targets = ["highlight"]  

  connect() {
    this.onHashChange()
    window.addEventListener("hashchange", this.onHashChange.bind(this))
  }

  disconnect(){
     window.removeEventListener("hashchange", this.onHashChange.bind(this)) 
  }

  onHashChange(e){
    if(window.location.hash)
    {
      this.anchor = window.location.hash.substring(1)      
      
      if (this.isAnchorMatching())
      {
        this.highlight()
      }
      else
      {
        this.unhighlight()
      }
    }
  }
  
  isAnchorMatching(){
    return this.matchingIdValue === this.anchor
  }
  
  highlight(){
    this.element.classList.add(...this.highlightClasses)          

    let targetClassName = this.highlightTargetClassName()

    this.highlightTargets.forEach((t) => {
      if(t.getAttribute(targetClassName)){        
        t.classList.add(...t.getAttribute(targetClassName).split(" "))        
      }
      
    }, this)
  }

  unhighlight(){
    this.element.classList.remove(...this.highlightClasses)          

    let targetClassName = this.highlightTargetClassName()
    
    this.highlightTargets.forEach((t) => {
      if(t.getAttribute(targetClassName)){        
        t.classList.remove(...t.getAttribute(targetClassName).split(" "))        
      }
      
    }, this)
  }


  highlightTargetClassName(){
    return "data-" + this.identifier + "-highlight-class"
  }
}

/*

// we need to style an element, if the anchor matches the element
// in a particular way.

<div data-controller="anchor-styler" 
     data-anchor-styler-highlight-class="shadow shadow-lg border border-primary border-2 mb-5 mt-5" 
     data-anchor-styler-matching-id-value="<%= dom_id(@active_record_instance)%>">

     <p data-anchor-styler-target="highlight" data-anchor-styler-highlight-class="text-primary" >       
         This will only be styled if the anchor matches
      </p>

</div>

// This will allow you to style
// matching elements, however your want to.
// if you need complex matching logic, then you can simply
// override methods 
// and you can style the elements however you like
*/

MapLibre GL JS component

Hey @guillaumebriday, first of all, thanks for this great project!

I would like to show you a component that is largely inspired by your project: stimulus-maplibre. I work a lot with maps (and in particular with the MapLibre library). So I figured it could be helpful to have a reusable Stimulus controller for handling the boilerplate setup for displaying a map. The controller could then be extended for custom map layers and interactions.

I built the component in a rather quick way and it is in fact not completely finished yet. However, I wanted to check with you if it could be a fit for your Stimulus Components project. I see that maps may not be the most common thing, but perhaps it could be useful for some people still. Let me know what you think!


(Btw, the similar setup to your components is no coincidence - I have used almost the same tooling and configs because they seemed like a good setup)

Failed to resolve module specifier Rails 7.0 (All components)

I am trying to use the components following the documentation

  1. I install the package of the component I want with yarn.
  2. In my app/javascript/controllers/index.js file I add the component as described in the documentation.

image

Error displayed by the browser
Uncaught TypeError: Failed to resolve module specifier "stimulus-autocomplete". Relative references must start with either "/", "./", or "../".

I have found people with my same problem that solved it with a package call to a yarn cdn, I think it makes no sense to call a cnd with the code when the code is in local.

Error-1
Error-2

ruby "2.7.0"
rails "7.0.2"

Upgrade to stimulus 3

It seems that for the new version of stimulus (3) the right import path should be "@hotwired/stimulus" instead of stimulus. This seems to be breaking the components. Any chance this could be updated?

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.