Headless UI component will not take style - vue.js

I'm currently playing around with Headless UI and I can't seem to style any of the components.
This is the code in my tabs file
<template>
<TabGroup>
<TabList class="bg-blue-900/20 rounded-xl">
<Tab>Products Information</Tab>
<Tab>Find Offices Nearby</Tab>
<Tab>Requirements</Tab>
</TabList>
<TabPanels>
<TabPanel>Content 1</TabPanel>
<TabPanel>Content 2</TabPanel>
<TabPanel>Content 3</TabPanel>
</TabPanels>
</TabGroup>
</template>
<script>
import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '#headlessui/vue'
export default {
components: {
TabGroup,
TabList,
Tab,
TabPanels,
TabPanel,
},
}
</script>

It's either of these problems
Tailwind CSS is not installed or configured properly so you cannot use Tailwind CSS classes like 'rounded-xl'.
'bg-blue-900/20' is not an inbuilt tailwind CSS class, so either customize color in tailwind or use inbuilt colours like 'bg-blue-400', 'bg-blue-500', etc

Tailwindcss v2.1 introduced JIT mode that generates styles on-demand.
You need to enable jit mode to use such classes like bg-blug-900/20.
You can see how to do that in official doc

Related

How to build web component with styling library using vite and vue 3?

I am able to build vue web component and load it in other pages, but I can't find document how to correctly include a UI framework. It seems the web component is under shadowDOM and import css using style tag won't work.
(Add the CDN link in the template and style is applied)
Any hint on any framework, Vuetify or Ant Design or Tailwind CSS will be appreciated.
Similar question: Vuetify build as Web component style not showing
Using custom elements without Shadow DOM is trivial. Just add like the way you do traditionally. However, with Shadow DOM, things are tricky. Only inheritable CSS styles pass through the Shadow DOM. Everything else is blocked. No straight forward integration with existing design systems (Vuetify, Ant, etc.) is not directly possible if that library is only exposing global CSS.
If the design system or a component library is exposing styles i.e. css files for individual components, then you can that with some effort.
The best solution is to use constructable stylesheet. You can use a bundler like Webpack to load the stylesheet for individual component (if and only if it is provided) as a string and feed it to the stylesheet constructor method as illustrated here.
// Read SCSS file as a raw CSS text using Webpack/Rollup/Parcel
import styleText from './my-component.scss';
const sheet = new CSSStyleSheet();sheet.replaceSync(styleText);
// Use the sheet inside the web component constructor
shadowRoot.adoptedStyleSheets = [sheet];
However, Firefox and Safari are yet to implement it.
If you need a fallback, then there are ways that are not so clean. Approach is same. Import the CSS/SCSS as a string and using the template literal, add it to the element's inner style tag.
import styleText from 'ant/button.css';
class FancyComponent extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.innerHTML = `
<!-- Styles are scoped -->
<style>
${styleText}
</style>
<div>
<p>Hello World</p>
</div>
`;
}
}
customElements.define('fancy-comp', FacyComponent);
This all relies on the assumption that ant/material/veutify is exposing styles as individual files instead of one global file.
Alternately, the browsers have started supporting the link tag inside the Shadow DOM. But again it is really useful if you have styles for individual components. Read more about that here.

Cannot use vue-start-rating in nuxt.js?

Cannot Used vue-star-rating in nuxt.js ReferenceError
document is not defined
<template>
<star-rating v-model="rating"></star-rating>
</template>
import StarRating from "vue-star-rating";
export default {
components: {
StarRating
}
}
thi is my codesandbox
Currently vue-star-rating does not support SSR, however, there is a feature-request open for this.
Currently, the only way to get this working with nuxt is to downgrade vue-star-rating to 1.6.2 and wrap it in no-ssr tags,
<no-ssr>
<star-rating :rating="3"></star-rating>
</no-ssr>
The solution above didn't work for me.
So, I just took the library (2 components and 1 class) and moved it to my component folder, so the components support the SSR now.

createApp({}).mount('#app') clears #app's child elements in vue3

So I'm trying to add Vue3 to an existing asp.net core project. What I'd like to happen is for my razor app to render as normal, then use custom vue components to give my frontend a more reactive feel. However, when I mount an empty vue app to my wrapper div (parent of all other body content), it seems to be deleting all innerHTML of that wrapper div, completely removing all server rendered body content.
In my _Layout.cshtml file, I'm wrapping all content in a div with id 'app'.
<body>
<div id='app'>
#RenderBody()
</div>
<script src="~/js/vue-app/dist/js/chunk-vendors.76316534.js"></script>
<script src="~/js/vue-app/dist/js/app.bf4c5ba9.js"></script>
</body>
in main.js
import { createApp } from 'vue'
const vueApp = createApp({}).mount('#app');
// component definitions below
With the app set up like this, when I run my .net project I see a blank white browser window instead of the razor compiled html that I expect. In Vue2, it was possible to do this:
const vueApp = new Vue({
el: '#app',
data: {
....
},
methods: {
....
}//, etc
});
Which would result in the app being rendered as normalthe vue app bound to #app, making vue available to the child content (model binding, vue click handling, etc).
I've tried playing around with the isHydrate optional parameter on mount(), but it causes no change in the result.
Am I missing something here? How do you slowly migrate an existing project to use vue3 if you can't mount the app without clearing content? Any guidance is much appreciated.
Thank you
Notes:
vue-next runtime-dom source If this method is the mount method getting called, I'm not sure why container.innerHTML would not be getting set in the component. {} is not a function, and render/template is not defined for it.
vue-next runtime-core apiCreateApp source If this is the method getting called....I have no idea.
Update
Vue 3, without template renderer, will not be able to handle the templates after it has been compiled. To fix that, you can import vue/dist/vue.esm-browser (and vue.runtime.esm-browser.prod for prod), instead of the default vue. This will allow run-time component rendering.

How to insert content inside tinymce editor using vue js?

I want to insert content like <span class="some-class">text</span> inside tinymce editor using a button in vue js template. How could I accomplish that using the tinymce-vue wrapper?
Here's the code:
<template>
<tinymce-editor
api-key="my-api-key-here"
/>
<button #click="addContent">button</button>
</template>
import Editor from '#tinymce/tinymce-vue'
export default {
components: {
tinymceEditor: Editor
},
methods: {
addContent () {
tinymce.activeEditor.setContent('<span class="some-class">text</span>');
}
}
}
Edit:
I also installed tinymce using npm i tinymce --save and added the import import tinymce from 'tinymce/tinymce to the code above. Now I don't get the error 'tinymce' is not defined anymore, but the editor doesn't appear either.
If you want to use tinymce in vue with typscritt to set up your content and avoid the undefined error you need to import tinyMCE as
import { getTinymce } from '#tinymce/tinymce-vue/lib/cjs/main/ts/TinyMCE';
Then you can set your content
getTinymce().activeEditor.setContent('coucou');
In your event handler for the button click, you can call TinyMCE's .setContent() method to set editor content.
Here is a demo:
https://codesandbox.io/s/set-content-in-tinymce-in-vue-jzciu
Don't forget, tinymce-vue doesn't include the code for TinyMCE itself. You'll either have to use an API key (which you can get for free at tiny.cloud) or use a self-hosted installation of TinyMCE. (For more info, see Step 6, here: https://www.tiny.cloud/docs/integrations/vue/#procedure)
I finally gave up trying to get access to tinymce in Vue 3 component. It either undefined or if it is not undefined - setContent command just do nothing - no errors but still no content inserted.
I just used recommended for "#tinymce/tinymce-vue" way of data binding using v-model
It looks like this:
<Editor
v-model="someLocalVar"
api-key="no-api-key"
:init="{
plugins: 'lists link image table code help wordcount',
}"
/>
then
watch(someLocalVar, () => {
//do whatever you like with your someLocalVar
});
If you want to insert content into TinyMCE you should use its APIs to do so:
https://www.tiny.cloud/docs/api/tinymce/tinymce.editor/#setcontent
https://www.tiny.cloud/docs/api/tinymce/tinymce.editor/#insertcontent
For example:
tinymce.activeEditor.setContent('<span class="some-class">text</span>');
tinymce.activeEditor.insertContent('<span class="some-class">text</span>');

vue-material localized theme to avoid conflict

Running a vuejs application as component of a website, using vue-material theming css create conflict with existing css.
By default, vue-material add a class on html <html class="md-theme-default"> to apply its style but I am trying to change that by only applying on a specific DOM element which should be my vue app.
Coming from material-ui, what I am looking for is the equivalent of <ThemeProvider> component.
Also, I only import a few components doing the following:
import { MdTabs, MdRadio } from "vue-material/dist/components";
import "vue-material/dist/vue-material.min.css";
import "./theme.scss";
Vue.use(MdRadio);
Vue.use(MdTabs);
Theme.scss redefine colors to match my theme.
#import "./variables";
#import "~vue-material/dist/theme/engine"; // Import the theme engine
#include md-register-theme("default", (
primary: $purple,
accent: $purple
));
#import "~vue-material/dist/theme/all"; // Apply the theme
I am using single .vue files with the following template synthax:
<template>
<div>
<md-radio v-model="radio" :value="objA">20€ / an</md-radio>
<md-radio v-model="radio" :value="objB">2€ / mois</md-radio>
</div>
</template>