Code Monkey home page Code Monkey logo

handy-collapse's Introduction

handy-collaps.js

A pure Javascript module for accordion/collapse UI without jQuery.
๐Ÿ”— Demo

NPM

npm version Netlify Status

Install

Use from NPM registry

Using npm or yarn, install handy-collapse.
๐Ÿ”— NPM

# npm
npm install handy-collapse

# yarn
yarn add handy-collapse

Then import and init it.

import HandyCollapse from "handy-collapse";

new HandyCollapse({ 
    //... 
});

Use from CDN

๐Ÿ”— UNPKG

<script src="https://unpkg.com/browse/handy-collapse/dist/handy-collapse.iife.js" defer>

Then init.

new HandyCollapse({ 
    //... 
});

Usage

1.Markup

With minimum markup

<!-- 
    Add data attribute, button/content element.
    Control Button:  data-{namespase}-control="{ID}" * multiple elements
    Collapsible element:  data-{namespase}-content="{ID}" * only one element
 -->
<button type="button" data-hc-control="uniqContentID">Show/Hide Content</button>

<div data-hc-content="uniqContentID">Toggle Content</div>

With aria-* attribute for accessibility

<button type="button" data-hc-control="uniqContentID" aria-expanded="false" aria-controls="theID">
  Show/Hide Content
</button>

<div id="theID" data-hc-content="uniqContentID" aria-hidden="true">Toggle Content</div>

2.Initialize

 const myAccrodion = new HandyCollapse();

Options

Option Name Type Default Desc
nameSpace string "hc" Set namespace both toggleButtonAttr & toggleContentAttr
toggleButtonAttr string `data-${nameSpace}-control` Attribute name for Controller button element
toggleContentAttr string `data-${nameSpace}-content` Attribute name for Content element
activeClass string "is-active" A class on opened element
isAnimation boolean true With animation Slide
closeOthers boolean true Close others Content
animationSpeed number 400 CSS transition duration (ms) *only isAnimation:true
cssEasing string "ease-in-out" CSS transition easing *only isAnimation:true
onSlideStart (isOpen: boolean, contentId: string) => void () => void Callback on Open/Close Animation Start
@param isOpen
@param {String} contentId * Don't ID Attribute
onSlideEnd (isOpen: boolean, contentId: string) => void () => void Callback on Open/Close Animation End
@param isOpen
@param contentId * Don't ID Attribute

Methods

Method name type desc
open(contentId, runCallback, isAnimation) (contentId: string, runCallback: boolean = true, isAnimation: boolean = true) => void Open the content
close(contentId, runCallback, isAnimation) (contentId: string, runCallback: boolean = true, isAnimation: boolean = true) => void Close the content
const myAccrodion = new HandyCollapse();

 // Open the content with `data-${namespace}-content="contentId"` attribute.
myAccrodion.open("contentId");

// Do not hook callbacks, and no animtion.
myAccrodion.open("contentId", false, false);

Examples

๐Ÿ”— Demo

JS

//Default Options
const myAccrodion = new HandyCollapse();

//Full Options
const myAccrodionCustom = new HandyCollapse({
  nameSpace: "hc", // Note: Be sure to set different names when creating multiple instances
  activeClass: "is-active",
  isAnimation: true,
  closeOthers: true,
  animationSpeed: 400,
  cssEasing: "ease",
  onSlideStart: (isOpen, contentID) => {
    console.log(isOpen);
    const buttonEl = document.querySelectorAll(`[data-hc-control='${contentID}']`);
    console.log(buttonEl);
  },
  onSlideEnd: (isOpen, contentID) => {
    console.log(isOpen);
    const contentEl = document.querySelector(`[data-hc-content='${contentID}']`);
    console.log(contentEl);
  }
});

// Open by Js
myAccrodion.open("content01");

// Close by Js
myAccrodion.close("content01");

HTML

<!-- 
    BUTTON :  data-{namespase}-control="{ID}" * multiple element
    CONTENT:  data-{namespase}-content="{ID}" * only one element
 -->
<!-- basic -->
<button type="button" data-hc-control="content01" aria-expanded="false" aria-controls="basicContent01">
  Show/Hide Content 01
</button>
<div id="basicContent01" data-hc-content="content01" aria-hidden="true">... Content 01 ...</div>

<!-- if add activeClass(def: "is-active"), Opened on init. -->
<button
  type="button"
  class="is-active"
  ใ€€
  data-hc-control="content02"
  aria-expanded="true"
  aria-controls="basicContent02"
>
  Show/Hide Content 02
</button>
<div id="basicContent02" class="is-active" data-hc-content="content02" aria-hidden="false">... Content 02 ...</div>

<!-- Can use nested accordion -->
<!-- Note: the `closeOthers` parameter must be set to `false` -->
<button type="button" data-hc-control="parentContent" aria-expanded="true" aria-controls="netstedParantContent">
  Show/Hide parent content
</button>
<div id="netstedParantContent" data-hc-content="parentContent" aria-hidden="true">
  ... parent content ...
  <button type="button" ใ€€ data-hc-control="childContent" aria-expanded="true" aria-controls="netstedChiledContent">
    Show/Hide child content
  </button>
  <div id="netstedChiledContent" data-hc-content="childContent" aria-hidden="true">... child content ...</div>
</div>

License

MIT

handy-collapse's People

Contributors

dependabot[bot] avatar sk-rt 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

Watchers

 avatar  avatar

handy-collapse's Issues

Radio button being unchecked when collapsed

Steps to recreate:

  1. Add a radio button inside of a collapse container.
  2. check the radio button
  3. collapse the container and expand it again.

Expected result: the radio button is still checked
Actual result: the radio button is no longer checked

I discovered this bug in Chrome, but it does not happen in Safari. I did not test any other browsers. Only seems to affect radio buttons - no other input element. I suspected this could be some kind of chrome bug/feature, but I tested with some other collapse libraries and could not reproduce it.

How to call open or close methods on multiple elements at the same time?

Calling the open or close methods on a single element works perfectly:
myAccrodion.open("content01")

But calling the open or close methods on multiple elements does not work correctly:
myAccrodion.open("content01")
myAccrodion.open("content02")

It seems to open the space where the content exists, but the content is invisible.
(Basically, it causes the data-hc-content elements to have style attributes of max-height: none; visibility: hidden; when they should have max-height: none; visibility: visible;)

Any idea if I am doing something wrong or if this is a bug? Thank you for the cool package. ๐Ÿ‘

Add: `destroy()` method

For dynamic initialization, add destroy() method to remove EventListeners and object references.

ref. #30

CDN links

Hi,

Do you have links hosted on CDN's?

thanks

HandyCollapse() is not a constructor

When building a Vue component with Rollup, the error HandyCollapse is not a constructor is thrown in the browser.
It works though when called like this: new HandyCollapse.default(). After some digging, the problem is fixed if the module is built with webpack configuration below.

/* webpack.confg.js */
output: {
        path: esmOutputPath,
        publicPath: publicPath,
        filename: "[name].js",
        library: {
            type: 'umd',
            name: 'HandyCollapse',
            export: 'default',
            umdNamedDefine: true
        }
    }

Thought we'd share for anyone running into the same issue.

Accessibility issue

The hidden content (links, buttons) inside collapsible area can be traversed by tab key. Expected behavior is to navigate over control buttons if the content is hidden.

Won't close after calling handyCollapse.open()

Problem

So far handy-collapse has been great, so thank you. However, I just ran into an issue when using the javascript open method directly.

Steps to re-create

  1. create a simple collapse with one data-{namespace}-control="myID" and one data-{namespace}-content="myID"
  2. It should be collapsed by default (no is-active class)
  3. Add another button that calls handyCollapse.open('myID') when clicked
  4. Click the button created in step 3, myID content will expand as expected
  5. But now try using the original control created in step 1

Expected Result

myID content should collapse, and be controlled normally by the main control (data-{namespace}-control="myID")

Actual Result

myID content collapses and then instantly expands again when using the main control (data-{namespace}-control="myID")

Also note that the bug only occurs after the second button (created in step 3) is clicked.

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.