Add guides for Ruby on Rails
Summary
Add guides for Ruby on Rails
Detailed Description
As Ruby on Rails is on fire (again), please add installation and configuration guides for it.
Use Cases
Develop pretty and UX-friendly products with Preline 💖
What exactly do you feel like it's missing? I think the process itself is fairly straightforward.
Something along the lines of:
Setup
Add Tailwind to your Rails project as recommended in TailwindCSS guides or just using the rails generators (see rails new --css=tailwind myapp).
Then add Preline to your project
yarn add preline
# yarn add clipboard # or any other plugins
Make sure you include any plugins you might be using, such as: clipboard, vanilla-calendar-pro, etc. See what needs to be included for each component on the docs on plugins page.
Check your package.json and see the "scripts": {} include the correct build command for CSS using tailwindcss:
{
"dependencies": {
...
"@tailwindcss/cli": "4.0.16",
"preline": "^3.0.0",
},
"scripts": {
"build": "esbuild app/javascript/*.* --bundle --sourcemap --format=esm --outdir=app/assets/builds --public-path=/assets",
"build:css": "npx @tailwindcss/cli -i ./app/assets/stylesheets/application.tailwind.css -o ./app/assets/builds/application.css"
}
}
Import Preline
# app/javascript/application.js
import "preline"
# If you use plugins as ClipboardJS load them here
import ClipboardJS from "clipboard";
window.ClipboardJS = ClipboardJS;
and in the stylesheets
@import 'tailwindcss';
@plugin '@tailwindcss/typography';
@plugin '@tailwindcss/forms';
@plugin '@tailwindcss/aspect-ratio';
@plugin '@tailwindcss/container-queries';
@import "../../../node_modules/preline/variants.css";
Careful when using Turbo
If you're using Turbo then you need to take care of re-initializing Preline after turbo:load and/or turbo:render events. Here's how I've done it.
import { initClipboardJS } from "./preline/clipboard-fix"
initCustomScripts = () => {
// Custom fix for clipboard.js Preline helper where I removed addEventListener
// from the Preline helper and load it manually here.
initClipboardJS();
// Re-initialize Preline
HSStaticMethods.autoInit();
}
document.addEventListener("turbo:load", (event) => {
console.debug("turbo:load event fired", event);
initCustomScripts();
});
You can find clipboard-fix.js in one of the lower comments in this thread.
While the above instructions worked with Preline 2.7 I'm having issues with setting up the imports with 3.0 and make them work. Specifically, the JS part needs to be setup in a certain way that I still need to figure out. I can't get
Maybe some guides (using jsbundling-rails with npm/yarn/bun/...) wouldn't be that bad after all 😅
I've updated the code in my comment above to reflect my current working solution. I've had to manually extract the fix for Clipboard.js (from node_modules/preline/src/helpers/clipboard/index.ts)
@lenart so maybe put it here? ;)
Like I've said, I've updated the comment above with my workaround. For clipboard-fix.js I've copied the code from node_modules/preline/src/helpers/clipboard/index.ts and updated it slightly so that it doesn't bind to load event but allows me to call it manually. Here's the file for convenience:
// app/javascript/preline/clipboard-fix.js
// Code copied from: node_modules/preline/src/helpers/clipboard/index.ts
export function initClipboardJS(clipboardSelector = '.js-clipboard') {
const $clipboards = document.querySelectorAll(clipboardSelector);
$clipboards.forEach((el) => {
const clipboard = new ClipboardJS(el, {
text: (trigger) => {
const clipboardText = trigger.dataset.clipboardText;
if (clipboardText) return clipboardText;
const clipboardTarget = trigger.dataset.clipboardTarget;
const $element = document.querySelector(clipboardTarget);
if (
$element.tagName === 'SELECT' ||
$element.tagName === 'INPUT' ||
$element.tagName === 'TEXTAREA'
)
return $element.value;
else return $element.textContent;
},
});
clipboard.on('success', () => {
const $default = el.querySelector('.js-clipboard-default');
const $success = el.querySelector('.js-clipboard-success');
const $successText = el.querySelector('.js-clipboard-success-text');
const successText = el.dataset.clipboardSuccessText || '';
const tooltip = el.closest('.hs-tooltip');
let oldSuccessText;
if ($successText) {
oldSuccessText = $successText.textContent;
$successText.textContent = successText;
}
if ($default && $success) {
$default.style.display = 'none';
$success.style.display = 'block';
}
if (tooltip) window.HSTooltip.show(tooltip);
setTimeout(function () {
if ($successText && oldSuccessText)
$successText.textContent = oldSuccessText;
if (tooltip) window.HSTooltip.hide(tooltip);
if ($default && $success) {
$success.style.display = '';
$default.style.display = '';
}
}, 800);
});
})
}
In my main file (eg. application.js) I can then force initialisation whenever needed (eg. turbo:load).
import { initClipboardJS } from "./preline/clipboard-fix"
document.addEventListener("turbo:load", (event) => {
initClipboardJS();
})