Created
January 28, 2022 20:31
-
-
Save matoni109/355358c15a0d3a5aa1a7d0aedca6fe4e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Controller } from 'stimulus'; | |
export default class extends Controller { | |
static targets = ['menu', 'button']; | |
static values = { open: Boolean }; | |
connect() { | |
this.toggleClass = this.data.get('class') || 'hidden'; | |
this.visibleClass = this.data.get('visibleClass') || null; | |
this.invisibleClass = this.data.get('invisibleClass') || null; | |
this.activeClass = this.data.get('activeClass') || null; | |
this.enteringClass = this.data.get('enteringClass') || null; | |
this.leavingClass = this.data.get('leavingClass') || null; | |
if (this.hasButtonTarget) { | |
this.buttonTarget.addEventListener('keydown', this._onMenuButtonKeydown); | |
} | |
this.element.setAttribute('aria-haspopup', 'true'); | |
} | |
disconnect() { | |
if (this.hasButtonTarget) { | |
this.buttonTarget.removeEventListener( | |
'keydown', | |
this._onMenuButtonKeydown | |
); | |
} | |
} | |
toggle() { | |
this.openValue = !this.openValue; | |
} | |
openValueChanged() { | |
if (this.openValue) { | |
this._show(); | |
} else { | |
this._hide(); | |
} | |
} | |
_show(cb) { | |
setTimeout(() => { | |
this.menuTarget.classList.remove(this.toggleClass); | |
this.element.setAttribute('aria-expanded', 'true'); | |
this._enteringClassList[0].forEach(klass => { | |
this.menuTarget.classList.add(klass); | |
}); | |
this._activeClassList[0].forEach(klass => { | |
this.activeTarget.classList.add(klass); | |
}); | |
this._invisibleClassList[0].forEach(klass => | |
this.menuTarget.classList.remove(klass) | |
); | |
this._visibleClassList[0].forEach(klass => { | |
this.menuTarget.classList.add(klass); | |
}); | |
setTimeout(() => { | |
this._enteringClassList[0].forEach(klass => | |
this.menuTarget.classList.remove(klass) | |
); | |
}, this.enterTimeout[0]); | |
if (typeof cb === 'function') cb(); | |
}); | |
} | |
_hide(cb) { | |
setTimeout(() => { | |
this.element.setAttribute('aria-expanded', 'false'); | |
this._invisibleClassList[0].forEach(klass => | |
this.menuTarget.classList.add(klass) | |
); | |
this._visibleClassList[0].forEach(klass => | |
this.menuTarget.classList.remove(klass) | |
); | |
this._activeClassList[0].forEach(klass => | |
this.activeTarget.classList.remove(klass) | |
); | |
this._leavingClassList[0].forEach(klass => | |
this.menuTarget.classList.add(klass) | |
); | |
setTimeout(() => { | |
this._leavingClassList[0].forEach(klass => | |
this.menuTarget.classList.remove(klass) | |
); | |
if (typeof cb === 'function') cb(); | |
this.menuTarget.classList.add(this.toggleClass); | |
}, this.leaveTimeout[0]); | |
}); | |
} | |
_onMenuButtonKeydown = event => { | |
switch (event.keyCode) { | |
case 13: // enter | |
case 32: // space | |
event.preventDefault(); | |
this.toggle(); | |
break; | |
default: | |
// do nothing | |
} | |
}; | |
show() { | |
this.openValue = true; | |
} | |
hide(event) { | |
if (this.element.contains(event.target) === false && this.openValue) { | |
this.openValue = false; | |
} | |
} | |
get activeTarget() { | |
return this.data.has('activeTarget') | |
? document.querySelector(this.data.get('activeTarget')) | |
: this.element; | |
} | |
get _activeClassList() { | |
return !this.activeClass | |
? [[], []] | |
: this.activeClass.split(',').map(classList => classList.split(' ')); | |
} | |
get _visibleClassList() { | |
return !this.visibleClass | |
? [[], []] | |
: this.visibleClass.split(',').map(classList => classList.split(' ')); | |
} | |
get _invisibleClassList() { | |
return !this.invisibleClass | |
? [[], []] | |
: this.invisibleClass.split(',').map(classList => classList.split(' ')); | |
} | |
get _enteringClassList() { | |
return !this.enteringClass | |
? [[], []] | |
: this.enteringClass.split(',').map(classList => classList.split(' ')); | |
} | |
get _leavingClassList() { | |
return !this.leavingClass | |
? [[], []] | |
: this.leavingClass.split(',').map(classList => classList.split(' ')); | |
} | |
get enterTimeout() { | |
const timeout = this.data.get('enterTimeout') || '0,0'; | |
return timeout.split(',').map(t => parseInt(t)); | |
} | |
get leaveTimeout() { | |
const timeout = this.data.get('leaveTimeout') || '0,0'; | |
return timeout.split(',').map(t => parseInt(t)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = { | |
purge: { | |
content: [ | |
'./app/components/*.html.erb', | |
'./app/views/wheelhouse/**/*.html.erb', | |
'./app/views/layouts/wheelhouse/*.html.erb', | |
'./app/webpack/controllers/*.js', | |
'./app/webpack/packs/*.js', | |
'./app/assets/javascript/**/*.js' | |
] | |
}, | |
darkMode: false, // or 'media' or 'class' | |
mode: 'jit', | |
theme: { | |
extend: {} | |
}, | |
variants: { | |
extend: {} | |
}, | |
plugins: [] | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Note: You must restart bin/webpack-dev-server for changes to take effect | |
default: &default | |
source_path: app/webpack | |
source_entry_path: packs | |
public_output_path: packs | |
public_root_path: public | |
cache_path: tmp/cache/webpacker | |
check_yarn_integrity: false | |
webpack_compile_output: false | |
# Additional paths webpack should lookup modules | |
# ['app/assets', 'engine/foo/app/assets'] | |
resolved_paths: [] | |
additional_paths: ['app/components'] | |
# Reload manifest.json on all requests so we reload latest compiled packs | |
cache_manifest: false | |
# Extract and emit a css file | |
extract_css: true | |
static_assets_extensions: | |
- .jpg | |
- .jpeg | |
- .png | |
- .gif | |
- .tiff | |
- .ico | |
- .svg | |
- .eot | |
- .otf | |
- .ttf | |
- .woff | |
- .woff2 | |
extensions: | |
- .jsx | |
- .js | |
- .mjs | |
- .sass | |
- .scss | |
- .css | |
- .module.sass | |
- .module.scss | |
- .module.css | |
- .png | |
- .svg | |
- .gif | |
- .jpeg | |
- .jpg | |
development: | |
<<: *default | |
compile: true | |
check_yarn_integrity: true | |
# Reference: https://webpack.js.org/configuration/dev-server/ | |
dev_server: | |
https: false | |
host: localhost | |
port: 3035 | |
public: localhost:3035 | |
hmr: false | |
# Inline should be set to true if using HMR | |
inline: true | |
overlay: true | |
compress: true | |
disable_host_check: true | |
use_local_ip: false | |
quiet: false | |
headers: | |
'Access-Control-Allow-Origin': '*' | |
watch_options: | |
ignored: '**/node_modules/**' | |
test: | |
<<: *default | |
compile: true | |
# Compile test packs to a separate directory | |
public_output_path: packs-test | |
production: | |
<<: *default | |
# Production depends on precompilation of packs prior to booting for performance. | |
compile: false | |
# Extract and emit a css file | |
extract_css: true | |
# Cache manifest.json for performance | |
cache_manifest: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html class="h-full bg-gray-100"> | |
<head> | |
<title>Wheelhouse</title> | |
<%= javascript_pack_tag 'wheelhouse' %> | |
<%= stylesheet_pack_tag 'wheelhouse' %> | |
<%# <script src="https://cdn.tailwindcss.com"></script> %> | |
</head> | |
<body class="h-full"> | |
<!-- This example requires Tailwind CSS v2.0+ --> | |
<div class="min-h-full"> | |
<nav class="bg-white shadow-sm"> | |
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> | |
<div class="flex justify-between h-16"> | |
<div class="flex"> | |
<div class="flex-shrink-0 flex items-center"> | |
Wheelhouse | |
</div> | |
</div> | |
<div class="hidden sm:ml-6 sm:flex sm:items-center"> | |
<!-- Profile dropdown ---> | |
<div class="inline-block text-sm px-4 py-2 leading-none rounded no-underline text-gray hover:text-gray-900 hover:bg-white mt-4 lg:mt-0"> | |
<div class="relative" data-controller="dropdown" data-dropdown-invisible-class="opacity-0 scale-95" | |
data-dropdown-visible-class="opacity-100 scale-100" | |
data-dropdown-entering-class="ease-out duration-300" | |
data-dropdown-enter-timeout="300" | |
data-dropdown-leaving-class="ease-in duration-300" | |
data-dropdown-leave-timeout="300"> | |
<div data-action="click->dropdown#toggle click@window->dropdown#hide" role="button" data-dropdown-target="button" tabindex="0" class="inline-block select-none bg-white rounded-full flex text-sm focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" id="user-menu-button" aria-expanded="false" aria-haspopup="true" > | |
<span class="appearance-none flex items-center inline-block text-gray-700"> | |
<%= image_tag "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80", class: "rounded-full h-8 w-8 align-middle" %> | |
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" class="h-4 w-4"><path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"></path></svg> | |
</span> | |
</div> | |
<div data-dropdown-target="menu" class="absolute right-0 mt-2 hidden"> | |
<div class="bg-white shadow rounded border overflow-hidden"> | |
<%= link_to 'Profile', root_path, data: {action: "click->dropdown#toggle"}, class: 'no-underline block pl-8 py-3 text-gray-900 bg-white hover:bg-gray-300 whitespace-nowrap' %> | |
<%= link_to 'Password', root_path, data: {action: "click->dropdown#toggle"}, class: 'no-underline block px-8 py-3 text-gray-900 bg-white hover:bg-gray-300 whitespace-nowrap' %> | |
<%= link_to 'Accounts', root_path, data: {action: "click->dropdown#toggle"}, class: 'no-underline block px-8 py-3 text-gray-900 bg-white hover:bg-gray-300 whitespace-nowrap' %> | |
<%= link_to 'Billing', root_path, data: {action: "click->dropdown#toggle"} ,class: 'no-underline block px-8 py-3 text-gray-900 bg-white hover:bg-gray-300 whitespace-nowrap' %> | |
<%= link_to 'Sign Out', root_path, data: {action: "click->dropdown#toggle"}, method: :delete, class: 'no-underline block px-8 py-3 border-t text-gray-900 bg-white hover:bg-gray-300 whitespace-nowrap' %> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Profile dropdown End ---> | |
</div> | |
</div> | |
</div> | |
</nav> | |
<div class="py-10"> | |
<main> | |
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> | |
<div data-controller="hello"> | |
</div> | |
<%= yield %> | |
</div> | |
</main> | |
</div> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment