Can not override theme of Chakra UI in NUXT js using extendTheme - vue.js

Update 1
I tried the following as #kissu said but it didn't worked,
1.Adding the key directly in nuxt.config.js is not working :
chakra: {
extendTheme: {
breakpoints: ['89rem', '86rem', '90rem', '120rem', '200rem', '300rem'],
}
},
Theme provider looks like this
<template>
<div class="container">
<CThemeProvider>
<CColorModeProvider>
<CBox font-family="body" as="main">
<CReset />
<siteHeader/>
<nuxt />
<siteFooter/>
</CBox>
</CColorModeProvider>
</CThemeProvider>
</div>
</template>
<script>
import {
CThemeProvider,
CColorModeProvider,
CReset,
CBox
} from '#chakra-ui/vue'
3.I tried applying classes corresponding to the breakpoints and also a custom color but it didn't helped too
<CBox bg="mpw.50" height="2rem" width="2rem">sadsad</CBox>
<CBox as="ul" list-style="none" d="flex" flexDirection="column">
<CBox as="li" list-style="none" borderBottom="2px solid #E8E8E8">
<CBox
:bg="[
'rebeccapurple','blue','yellow','orange','grey','#8B008B','#7FFF00'
]"
padding="1rem" d="flex" v-bind="mainStyles[colorMode]">
<CImage :src="require('#/assets/imgs/patient.png')" w="5rem" h="5rem" alt=""/>
<CBox flex="1 1 0" padding="1rem" paddingTop="0" paddingBottom="0" v-bind="mainStyles[colorMode]">
<CText fontSize="2xl" >
Home Isolation Patients
</CText>
<CText pr="0.5rem">
Lorem ipsum xyzzzz
</CText>
anything else that I should try now ?
Original Post is below
I am unable to extendTheme in Chakra UI in my NUXT JS app. I want to use my own breakpoints as per my designs, which means that I need to have more than 4 breakpoints in my app.
In my nuxt.config.js I am importing it and using like below :
import customTheme from './customTheme/custom-theme.js'
chakra: {
extendTheme : customTheme
},
The file custom-theme.js
console.log("LOADING CUSTOM THEME")
export default {
// '38rem', '48rem', '62rem', '80rem',
breakpoints:[ '89rem','86rem','90rem','120rem','200rem','300rem'],
colors:{
mpw:{
50:"#EBEBEB",
}
}
}
When I do console.log in my index.vue
mounted() {
if(process.server){
console.log("ON SERVER")
console.log(this)
}
if(process.client){
console.log("ON CLIENT")
console.dir(this.$chakra.theme)
}
},
then I don't see my custom breakpoints
How can I add my own set of breakpoints like those breakpoints:['89rem', '86rem', '90rem', '120rem', '200rem', '300rem'] ?

Related

Vue.js - Embed Swagger UI inside a Vue component?

I have a form in my Vue component which uploads the api file. Now I want to render the contents of the file like this:
I have imported swagger client library: https://github.com/swagger-api/swagger-ui.
Now, here
is an example of how you do it in a static page. But I need to do it inside a Vue component (or Quasar, specifically), so I do it like that:
Register swagger-ui inside my register components file:
<link rel="stylesheet" type="text/css" href="swagger-ui.css">
Now it is available as:
this.swaggerUI({})
anywhere in my components. Inside my component I have a div in a template to render the api file:
<template>
<q-form>here lies q-file element, submit button and other stuff</q-form>
<div id="swagger-ui"></div>
</template>
In the mentioned question he had something like:
<script>
window.onload = function() {
const ui = SwaggerUIBundle({
url: "https://yourserver.com/path/to/swagger.json",
dom_id: '#swagger-ui',
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
]
})
window.ui = ui
}
</script>
Here's the difference: first of all, no window.onload, I must render it on submit button. Then, I deal with an uploaded file stored in my model, so no URL here. Now, I don't get how to make it work with locally stored file, when I try with the remote url, it gives me:
vue.esm.js?a026:628 [Vue warn]: Error in v-on handler: "Invariant Violation: _registerComponent(...): Target container is not a DOM element."
I was getting a similar error (Target container is not a DOM element) trying to use a static swagger spec. Instead of using window.onload, I found that Vue has the mounted() function, so this Vue 3 file worked for me:
<template>
<div class="swagger" id="swagger"></div>
</template>
<script>
import SwaggerUI from 'swagger-ui';
import 'swagger-ui/dist/swagger-ui.css';
export default {
name: "Swagger",
mounted() {
const spec = require('../path/to/my/spec.json');
SwaggerUI({
spec: spec,
dom_id: '#swagger'
})
}
}
</script>
This one appeared to be a simple yet very unobvious typo: in windows.onload function:
dom_id: '#swagger-ui',
must instead be
dom_id: 'swagger-ui',
without hash sign, that's it!

Aurelia: not recognizing feature module

I just discovered this framework and I was loving it so far. But then I tried to create a feature module and for some reason it's not working.
I created a new Aurelia app using the CLI:
au new
Then I started coding, created an HTML-only custom element and used it, it worked great.
The problem came when I wanted to create a feature module.
First, this is my src folder (yeah, I'm going with a classic todo-list app):
So, in the main.js file I've declared the todo feature module:
import 'regenerator-runtime/runtime';
import * as environment from '../config/environment.json';
import {PLATFORM} from 'aurelia-pal';
export function configure(aurelia) {
aurelia.use
.standardConfiguration()
.feature(PLATFORM.moduleName('todo/index'));
aurelia.use.developmentLogging(environment.debug ? 'debug' : 'warn');
if (environment.testing) {
aurelia.use.plugin(PLATFORM.moduleName('aurelia-testing'));
}
aurelia.start().then(() => aurelia.setRoot(PLATFORM.moduleName('app')));
}
Now, depending on what I do I get one error or another.
Option 1
If I configure todo/index.js as a module like this:
export function configure(config) {
config.globalResources(['./todo-list', './todo-item']);
}
Then I get this warning and the web goes blank:
Option 2
If I comment out the config.globalResources() line in todo/index.js then I don't get the warning, the page seems to work. But when I click on the button to add a new Todo item I get an error that the function doesn't exist.
In app.html I import todo/todo-list.html:
<template>
<require from="./app-header.html"></require>
<require from="./todo/todo-list.html"></require>
<app-header></app-header>
<main>
<todo-list></todo-list>
</main>
</template>
And this is the content of todo-list.html:
<template>
<form>
<label for="item-text">Añadir elemento: </label>
<input id="item-text" value.bind="newTodo"/>
<button type="button" click.trigger="addTodo()">Añadir</button>
</form>
</template>
This is todo-list.js:
import {TodoItem} from './todo-item';
export class TodoList {
constructor() {
this.todos = [];
this.newTodo = '';
this.lastId = 0;
}
addTodo() {
this.lastId++;
this.todos.push(new TodoItem(this.lastId, this.newTodo));
this.newTodo = '';
console.log(this.todos.length);
}
}
So, I guess if I don't configure todo/index.js as a module Aurelia doesn't know that todo-list.html and todo-list.js are related and that's why it can't find the function addTodo().
What am I doing wrong?
I have created a github repo with the code: https://github.com/dhAlcojor/aurelia-todo-list
You need to wrap all references to module names (files) in PLATFORM.moduleName calls.
So instead of
export function configure(config) {
config.globalResources(['./todo-list', './todo-item']);
}
switch to
export function configure(config) {
config.globalResources(
PLATFORM.moduleName('./todo-list'),
PLATFORM.moduleName('./todo-item');
}
Also note that I got rid of wrapping the paths in an array. The framework does that for you.

Using <object> to embed svg but doesn't show anything

I was trying to use to embed the svg picture but it does not show anything. I looked at some other threads and it was suggested to add type="image/svg+xml", however, it did not solve the issue. When I am trying to look at the DOM for some reason it seems to create an endless loop. I attached the picture
This is the compononent
<template>
<div class="logo">
<object type="image/svg+xml" data="logo.svg">
</object>
</div>
</template>
This is the app.vue
template>
<div id="app">
<Demo></Demo>
</div>
</template>
<script>
import Demo from './components/Demo.vue'
export default {
name: 'app',
components: {
Demo
}
}
</script>
```[![Snapshot][1]][1]
[1]: https://i.stack.imgur.com/Q6ipO.png
This happen because vue-loader doesn’t recognize paths in just any attribute. By default just recognize these ones: https://vue-loader.vuejs.org/options.html#transformasseturls
So, there are 3 possible solutions
Note: If you are not using eslint as linter you could remove eslint comments
1: Bind the route to your image
First add the next variable to your data in the component
data() {
return {
// eslint-disable-next-line global-require
mySvg: require('../assets/logo.svg'),
};
},
Next modify your template
<object type="image/svg+xml" :data="mySvg">
2: Add vue-loader rule
If you don't want to have to bind every svg image, you could add a rule to vue-loader in order to say how to handle data attribute in a object
Go to your webpack config file, if you created the project using vue-cli 3.x you have to create a vue.config.js file in the root (same level that package.json)
// vue.config.js
module.exports = {
chainWebpack: (config) => {
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap((options) => {
// eslint-disable-next-line no-param-reassign
options.transformAssetUrls = {
object: 'data',
};
return options;
});
},
};
if you want to check that the config was added, execute vue inspect > webpack.config and expect see something like this (inside webpack.config):
{
loader: 'vue-loader',
options: {
...
transformAssetUrls: {
object: 'data'
}
}
}
More info: https://cli.vuejs.org/guide/webpack.html#working-with-webpack
3: Replace default loader and use svg as vue components
Other option is use vue-svg-loader. This loader inlines the SVGs which enables you to modify them using css. Also optimize your files with SVGO
See more: https://vue-svg-loader.js.org/#vue-cli
It is worth checking that you don't have a CSS rule hiding object tags. Otherwise it seems correct. You probably need to check the path and make sure you can reach your image. I assume your filename is a dummy, but try to use an absolute path. And make sure you can hit the path and see the image in your browser.

vue-apollo: GraphQL queries only run when using <ApolloQuery> tags. Never works in script code. this.$apollo.queries is empty

I know I'm probably missing something really super basic here, I'm trying to run a graphql query with vue-apollo... if I use tags, it works fine
If I try to run queries from inside my code, like in the basic examples in the docs (links below) then nothing happens. The server never receives any request, and this.$apollo.queries is empty.)
Basic examples from the docs:
https://akryum.github.io/vue-apollo/guide/apollo/#queries
https://vue-apollo.netlify.com/guide/apollo/queries.html#simple-query
I've defined the query in the "apollo" property/object... how do I actually execute it when the page loads? Note that I'm using typescript, which is why it's using a "get apollo()" method.
Here's my code...
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
export default class List extends Vue {
myQueryName='my default value';
get apollo() {
return {
myQueryName: {
query: require('../graphql/listMeta.graphql'),
// prefetch: true <-- tried with and without this
}
}
}
}
</script>
<template>
<div>
<!-- THIS DOESN"T WORK ... -->
queries are: {{this.$apollo.queries}} <!-- THIS JUST SHOWS AN EMPTY OBJECT: {} -->
<hr>
myQueryName value is: {{myQueryName}} <!-- THIS JUST SHOWS "my default value" -->
<hr>
<!--
THIS DOES WORK...
<ApolloQuery :query="this.apollo.myQueryName.query" >
<template slot-scope="{ result: { loading, error, data } }"></template>
</ApolloQuery>
-->
</div>
</template>
Note that this.$apollo.queries is empty in the template, probably a clue... but still no idea why its empty. From the docs and examples I've seen it should be populated from my get apollo data method.
Looks basically the same as https://github.com/OniVe/vue-apollo-typescript-example/blob/master/pages/index.vue as far as I can tell, I don't know what the difference is.
I've tried rebuilding the project from scratch multiple times (with and without nuxt), over teh course of months and many different versions of vue/nuxt/apollo/vue-apollo... the queries never run (from memory) unless I use tags.
What am I missing?
You are missing #Component decorator, it is needed to set initial properties of Vue component, so vue-apollo can detect it when component created and make a smartquery property.
import { Component, Vue } from 'vue-property-decorator'
import listMetaDocument from '../graphql/listMeta.gql'
#Component({
name: 'List',
apollo: {
listMeta: {
query: listMetaDocument
},
},
})
export default class List extends Vue { }

Custom print style with Vue.JS print plugin

I am trying to print a VueJS component with custom print style.
Three Vue plugins look interesting on this subject:
1.printd
2.vue-print-nb
3.html-to-paper
Out of the three only html-to-paper has a options object that can pass a custom css style in order to dynamically pass some print css.
My issue is that i can't seem to load the custom css, and also bootstrap classes are messed up on print action.
This is basically what i am doing.
import VueHtmlToPaper from 'vue-html-to-paper'
const options = {
name: '_blank',
specs: [
'fullscreen=yes',
'titlebar=yes',
'scrollbars=no'
],
styles: [
'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css',
'./myPrint.css'
]
}
Vue.use(VueHtmlToPaper, options)
Any suggestion is welcomed.
Thanks
I have tried all these three I think the best one is print.js which is not specifically for Vue.js but it is easily install-able and usable in the vue components.
For example
<script>
import print from "print-js";
export default {
methods: {
printing() {
const style =
"#page { margin-top: 400px } #media print { h1 { color: blue } }";
const headerStyle = "font-weight: 300;";
printJS({
printable: "rrr",
type: "html",
header: "Doctor Name",
headerStyle: headerStyle,
style: style,
scanStyles: false,
onPrintDialogClose: () => console.log("The print dialog was closed"),
onError: e => console.log(e)
});
},
printVisit(id) {
this.$htmlToPaper("rrr");
this.$htmlToPaper("rrr", () => {
console.log("Printing completed or was cancelled!");
});
}
}
};
</script>
VueHtmlToPaper opens a new window with its own style tag. So when you pass a CDN it works, if u pass a local file it does not because it tries to access the resource in your web server but in the wrong URL. Let's see how the page looks when we use a CDN and a local CSS file.
CDN
<html>
<head>
<link rel="style" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css">
</head>
<body>
</body>
</html>
Local CSS file
And let's say you are calling the print function from http://localhost:8080/somepage
<html>
<head>
<link rel="style" href="./myPrint.css">
</head>
<body>
</body>
</html>
This will try to open http://localhost:8080/somepage/myPrint.css. Obviously this will not be accessible to print dialogue.
Solution
Put your custom CSS file in the public or static folder (Where you usually keep favicon)
Modify script path in options, prepend server basepath with the CSS file
Sample Option
import VueHtmlToPaper from 'vue-html-to-paper'
/* This will change according to your server */
let basePath= 'http://localhost:8080';
const options = {
name: '_blank',
specs: [
'fullscreen=yes',
'titlebar=yes',
'scrollbars=no'
],
styles: [
'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css',
`${basePath}/myPrint.css`
]
}
Vue.use(VueHtmlToPaper, options)
Also, the simplest way to access root-relative path is to use /. User /style.css instead of ./style.css