Vue + Tailwind : themeable profile page - javascript

I want to create an app (something like a social network) that lets a user sign-up and enter a bunch of profile information. After this the user is allowed to select one theme (from a set of predefined themes) for displaying this information to other users that come to see the profile.
This is very similar to what Shopify's storefront themes are.
How should I go about trying to design a solution for this?
Apologies in advance for a very high-level vague question.
I know how to set the theme and/or colors etc at the time I writing my code (or maybe during the build step), but I am stuck at even trying to reason how to do this inside a product.

You might use tw-colors in order to create the predefined themes
const { createThemes } = require('tw-colors');
module.exports = {
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
plugins: [
createThemes({
banana: {
'primary': 'steelblue',
'secondary': 'darkblue',
'brand': '#F3F3F3',
},
halloween: {
'primary': 'turquoise',
'secondary': 'tomato',
'brand': '#4A4A4A',
},
darkula: {
'primary': '#2A9D8F',
'secondary': '#E9C46A',
'brand': '#264653',
},
})
],
};
Then apply the theme on the card container
<div class='theme-darkcula'>
<h2 class='text-primary'>Username</h2>
<p class='text-secondary'>...</p>
</div>
<div class='theme-halloween'>
<h2 class='text-primary'>Username</h2>
<p class='text-secondary'>...</p>
</div>
If the theme classNames come from API response you should safelist them, otherwise tailwind will not generate them, see tailwind docs for more details

Related

How to hide element in Vue-html-to-paper?

I need to hide some things when I do print pages. The 2 button signs do not want to be displayed when I want to print. I use plugin https://www.npmjs.com/package/vue-html-to-paper
Check my code:
<div id="printThis">
<h1> My tiyle </h1>
<button> I WAN'T TO DISPLAY THIS BUTTON IN PRINT!!! </button>
<p> My parag </p>
</div>
print(){
this.$htmlToPaper('printThis');
}
Question is simple. I wan't display button in my pdf paper.
I've read through the source code at https://github.com/mycurelabs/vue-html-to-paper/blob/master/src/index.js and it doesn't look like there's a variable built in to do this (which there really should be, maybe you could make a pull request?). But we can make one ourselves.
In the data section of your component, add a variable called printing:
data() {
return {
printing: false,
}
},
Edit your template to use it:
<template>
<div id="printThis">
<h1> My tiyle </h1>
<button v-show="!printing"> I WAN'T TO DISPLAY THIS BUTTON IN PRINT!!! </button>
<p> My parag </p>
</div>
</template>
(Note you can use v-if too. There's some upsides and some downsides.)
Then wrap the method call to the plugin in a method of your own to set and unset the variable. Use the callback the plugin documentation describes to unset the variable:
print(){
this.printing = true;
const options = null; // Set this if you need to, based on https://randomcodetips.com/vue-html-to-paper/
this.$htmlToPaper('printThis', options, () => {
this.printing = false;
});
}
And there you go.
I will say, you could probably write a plugin way better to do the same thing. It'd be nice to have a promise based approach, or at least some defined lifecycle events for print success or failure.
You can specify css file direction and in css file write your option.
Something like this.
__dir/app.js or __dir/main.js
import VueHtmlToPaper from 'vue-html-to-paper';
const options = {
name: '_blank',
specs: [
'fullscreen=yes',
'titlebar=yes',
'scrollbars=yes'
],
styles: [
'css/print.css',
]
}
Vue.use(VueHtmlToPaper, options);
#media print {
.hidden-print {
display: none !important;
}
}

Language selector

I've been researching around for code that will let me click an <a> tag to convert the page's language to a different language using a key value pair, but the countless ones that I've found online lurking around seems to be tailored for its own personal needs or incomplete.
So my question is, how would I go about changing every element with a certain class to the language from the <a> tag I clicked, while using the dictionary keypair?
Here's my current JQuery/JS code:
var langcodes = [{
code: "en",
name: "English",
}, {
code: "zh-Hant",
name: "Traditional",
}, {
code: "zh-Hans",
name: "Simplified",
}, {
code: "vi",
name: "Vietnamese",
}];
var dictionary = [{
//Word one
English: "Abby",
Traditional: "AbbyT",
Simplified: "AbbyS",
Vietnamese: "AbbyV",
}, {
//Word two
English: "Babby",
Traditional: "BabbyT",
Simplified: "BabbyS",
Vietnamese: "BabbyV",
},
//and so on and so forth
];
$(document).ready(function() {
$(".langtype").click(function() { //click an element(language) w/ class langtype
$(".trans").each(function(key, item) {
//for each element with the trans class, change its text to be fitting of .langtype's language
});
});
})
<div class="navitem languagediv">
<a>LANGUAGE <i class="fa fa-caret-down"></i></a>
<div class="dropdown-content">
<a class="dropitem langtype">ENGLISH</a>
<a class="dropitem langtype" href="#">繁体中文</a>
<a class="dropitem langtype" href="#">简体中文</a>
<a class="dropitem langtype" href="#">Tiếng Việt</a>
</div>
</div>
I appreciate all the help or code templates I can get. Thanks!
One way would be to give each word or phrase in the dictionary a key and then put that key on each div that you want translated. Also put an attribute on your language selectors indicating the language that's being selected. In your each loop, read the $(this).attr('key') (if you used 'key' to set the key) and then look up the new word in the dictionary. This is a basic working example: https://jsfiddle.net/nghjucLs/
I wouldn't try to translate word by word (by scanning each .trans element for the word and then searching for it in the dictionary); that could get very slow with a larger dictionary and more text on the page to translate.
I recently used this library:
http://www.openxrest.com/translatejs/
to complete a similar task where I turned certain chunks of website to another language based on user feedback.
Give this a try. They give examples of use with jQuery as well.

How to avoid Vuetify overrides default CSS

Summarize the problem
I am trying to implement the Vuetify to a part of an existing project. But after I added Vuetify to the Project. I found out that the "default" CSS styles for like input field, select are changed. And it makes those input field and select all look like plain text rather than input field and select.
Because I only want to implement the Vuetify for a part of the project, so it is bad that the Vuetify overrides the "default" CSS Rules.
I am looking for a way to implement the Vuetify for a part of an existing project. But the rest of the project should be rendered as normal (just with default CSS, not my own CSS).
To make the Qustion more clair, I will put an example which shows two selects. The first one is made with Vuetify <v-select> and the second one is made with normal HTML code <select>
Provide background and tell us what you've already tried
I have already tried to put custom CSS rules for input field and select after the Vuetify Script and Vuetify CSS link. But Vuetify still overrides my custom CSS-Styles.
Show your code
HTML PART:
<div id="app">
<div>Vuetify select:</div>
<v-select
:items="items"
>
</v-select>
<hr/>
<div>
<div>Normal select:</div>
<select>
<option value="0">test1</option>
<option value="1">test2</option>
<option value="2">test3</option>
</select>
</div>
</div>
JS PART:
new Vue({
el: '#app',
data() {
return {
item: null,
items: [
{
text: "a"
},
{
text: "b"
},
{
text: "c"
},
]
}
}
})
Describe expected and actual results
I expected that I can use Vuetify for some parts of this project. But in the meanwhile, the rest of the project should be acting just like normal (with default CSS).
This is caused by the Vuetify reset styles (src/styles/generic/_reset.scss).
There is also an issue for that problem: https://github.com/vuetifyjs/vuetify/issues/8530. You can find there a little postcss hack from mkalus that isolates necessary styles via the wrapper (adding the prefix class to selectors).
In my case I just needed to remove some element selectors, excluding those that I added myself. So this is my variation of mkalus's solution with the postcss-filter-rules plugin.
I used the filter option to filter selectors. Its description:
Selectors are kept if the function returns true, otherwise they are removed.
And the keepAtRules option to prevent unnecessary deletions:
By default, #font-face and any empty at-rules (after filtering) are removed. To keep specific at-rules, provide an array of names to this option. To keep all at-rules, use the value true.
vue.config.js (Vue CLI 4):
const autoprefixer = require('autoprefixer')
const filterRules = require('postcss-filter-rules')
module.exports = {
/* ... */
css: {
loaderOptions: {
postcss: {
plugins: [
filterRules({
filter: (selector) => {
const re = new RegExp(/^(html|body|\*|ul|ol|select|small)(\W|$)/, 'i')
const exception = '.vue-global'
return !re.test(selector) || selector.includes(exception)
},
keepAtRules: true
}),
autoprefixer
]
}
}
}
/* ... */
}
Now that I've removed some Vuetify reset styles, I can still style html and other elements like this:
html.vue-global
font-size 16px
You can try adding a normalize css file to your project and the vuetify styling should only apply to when you want it to, i use this

third party slider adding dynamic elements with attributes like 'class'. I am using react

I am working on a react app (converting a static HTML website to react app).
It has a slider (revolution slider I guess) that adds dynamic elements. Like etc.
Now react doesn't complain compile time. But on the rendering of the page, it fails for the obvious reason. It should append 'className' instead but I can't modify the source of that library or any third party library for that matter.
What is the best approach to handle this use case?
PS: Apologies in advance. I am naive with React!
Disclamer
If you are not talking about the Revolution Slider I am under the impression you are, please let me know and I will remove this answer. It appears there is a 3rd party library which was made to expose the very problem you are having when using the Revolution Slider in React.js.
It does appear to be poorly documented but lets see if we can make sense of it by checking the repo's source code.
Problem
How to pass a style to the 3rd party popular library Revolution Slider.
Explanation
If you are speaking of Revolution Slider it appears that NPM has a package for this slider here.
It also appears that it has a prop poorly documented in the source code if I am looking at this correctly. On this page you can see the code.
Solution
In that file this function at the bottom of the page appears to check the name of the prop past in.
function fetchAttributes(payload, sk = [], ex = []) {
const attr = {};
const skip = ['children'].concat(sk)
const exceptions = ['class', 'src', 'alt', 'style', 'id'].concat(...ex);
for (let key in payload) {
if (skip.includes(key)) {
continue;
} else if (key === 'class') {
attr[key + 'Name'] = payload[key];
} else if (exceptions.includes(key)) {
attr[key] = payload[key];
} else {
if (key.startsWith('data-')) {
attr[key] = payload[key];
} else {
attr['data-' + key] = payload[key];
}
}
}
return attr;
}
That is important because we can see which prop it is checking for. In this case it appears it looks for,
['class', 'src', 'alt', 'style', 'id']
We can also see an example of that here.
Example Code
import RevSlider, { Slide, Caption } from 'react-rev-slider';
const config = {
delay:9000,
startwidth:1170,
startheight:500,
hideThumbs:10,
fullWidth:"on",
forceFullWidth:"on"
};
<RevSlider config={config}>
<Slide
src="https://i.ytimg.com/vi/dFnvYtPePRA/maxresdefault.jpg"
alt="slidebg1"
data-bgfit="cover"
data-bgposition="left top"
data-bgrepeat="no-repeat"
slideProperties={{
'data-transition': "fade",
'data-slotamount': "7",
'data-masterspeed': "1500"
}}
>
<Caption
class="tp-caption skewfromrightshort fadeout"
data-x="85"
data-y="224"
data-speed="500"
data-start="1200"
data-easing="Power4.easeOut"
>
This is a caption
</Caption>
</Slide>
<Slide
src="https://i.ytimg.com/vi/0xe4H666drk/maxresdefault.jpg"
alt="slidebg1"
data-bgfit="cover"
data-bgposition="left top"
data-bgrepeat="no-repeat"
slideProperties={{
'data-transition': "fade",
'data-slotamount': "7",
'data-masterspeed': "1500"
}}
>
<Caption
class="tp-caption skewfromrightshort fadeout"
data-x="85"
data-y="224"
data-speed="500"
data-start="1200"
data-easing="Power4.easeOut"
>
This is a caption
</Caption>
</Slide>
</RevSlider>
But more specifically look at the prop being past in. It appears you can pass a prop in called, slideProperties which is then past to a function call and checks for any of these,
['class', 'src', 'alt', 'style', 'id']
So to add a style to <Slide /> or <Caption /> it appears you can do so like so,
<Slide class={style.myClass}/> or <Caption id={style.myId} />
It looks a little confusing to me though. in the example code it shows slideProperties and src being used as 2 separate props. But when I read the source code it looks to me as if the prop slideProperties is an object that takes the keys, ['class', 'src', 'alt', 'style', 'id'].
Either way, I think operating with the understanding that we can pass these in one way or another that this can be achieved with little effort.
I think it is safe to assume this will work because of the example code I added above which I found from the README.md file on their github page. It shows them using src="string" in the same way.
We can see src being handled in the function fetchAttributes() which seems to pass the props to the Components. With a little css you can write a few styles to pass it into the 2 Components. Then easily target the li tag and img tag with your css.
I hope this helps.

Prevent or remove p tag placed around images in CKEditor4

My issue is <p> tags are being placed around uploaded image in CKEditor4. Not a huge issue normally but starting to throw CSS off in some templates (like bootstrap).
Currently I get this after uploading an image:
<p><img src="images/example.jpg"></p>
Like to have only:
<img src="images/example.jpg">
I have tried adding (no success for images):
config.autoParagraph = false;
I have visited many threads here on stackoverflow and most all refer to WordPress which I am not using. The CKEditor is in a simple CMS for school blogs on a local network.
Found reference to a WordPress plugin that some say will work (strip out all WP ref), but that has failed miserably:
<?php
/*
Plugin Name: Paragraph Remover
Description: Removes paragraphs around images
Version: 0.1
Author: Martin Vlcek
Author URI: http://mvlcek.bplaced.net
*/
# get correct id for plugin
$thisfile = basename(__FILE__, ".php");
# register plugin
register_plugin(
$thisfile,
'PRemover',
'0.1',
'Martin Vlcek',
'http://mvlcek.bplaced.net',
'Removes paragraphs around images',
'',
''
);
# activate filter
add_filter('content','premover_replace');
function premover_replace($content) {
return preg_replace_callback("/<p>(?:\s| )*(<a[^>]+>)?(?:\s| )*(<img[^>]+>)(?:\s| )*(<\/a>)?(?:\s| )*<\/p>/",'premover_replace_match',$content);
}
function premover_replace_match($match) {
return $match[1].#$match[2].#$match[3];
}
Cannot find solution and hoping for some input. Either a plugin, javascript or PHP, it does not matter.

Categories

Resources