I use this package: https://github.com/greyby/vue-spinner for showing a spinner.
<template>
<pulse-loader :loading="loading" :color="color" :size="size"></pulse-loader>
</template>
<script>
import { PulseLoader } from 'vue-spinner/dist/vue-spinner.min.js';
export default {
components: { PulseLoader },
data () {
return {
loading: true,
color: "black",
size: "10"
}
}
}
</script>
For some reason the spinner is not showing???!?! There are no erros in my console!
You should not be importing from the dist folder.
Please, try importing the vue component source, doing as shown in the documentation:
import PulseLoader from 'vue-spinner/src/PulseLoader.vue'
Docs: https://github.com/greyby/vue-spinner#es6
UPDATE:
Considering Browserify restriction on applying transforms in files inside node_modules, then you could try the code snippet provided in the mentioned GitHub issue:
var PulseLoader = require('vue-spinner/dist/vue-spinner.min').PulseLoader;
The website I was working on had a custom CSS-file. It was missing the correct styles. Possibly because it was for an older version of Bootstrap.
Make sure that there is a definition for .spinner-border anywhere in your styles. If not, find out why not and fix it.
I have copied the style from the source-code of the Vue examples page for a quick fix.
#keyframes spinner-border {
to { transform: rotate(360deg); }
}
.spinner-border {
display: inline-block;
width: 2rem;
height: 2rem;
vertical-align: text-bottom;
border: .25em solid currentColor;
border-right-color: transparent;
border-radius: 50%;
-webkit-animation: spinner-border .75s linear infinite;
animation: spinner-border .75s linear infinite;
}
Related
I am working to redo this Codepen in React Typescript. I found it in the blogpost here
Simple way - creating React App and adding into css file it works perfect.
No I tried the way with styled components and it seems I am missing something as it does not work yet?
App.tsx
import React from "react";
import "./App.css";
import styled from "styled-components";
/* Animate when Houdini is available */
const Houdini = styled.div`
width: 400px;
height: 300px;
border-radius: 10px;
padding: 2rem;
margin: auto;
display: grid;
place-content: center;
text-align: center;
font-size: 1.5em;
--border-size: 0.3rem;
border: var(--border-size) solid transparent;
/* Paint an image in the border */
border-image: conic-gradient(
from var(--angle),
#d53e33 0deg 90deg,
#fbb300 90deg 180deg,
#377af5 180deg 270deg,
#399953 270deg 360deg
)
1 stretch;
background: rgb(255 255 255 / var(--opacity));
#supports (background: paint(houdini)) {
#property --opacity {
syntax: "<number>";
initial-value: 0.5;
inherits: false;
}
#property --angle {
syntax: "<angle>";
initial-value: 0deg;
inherits: false;
}
#keyframes opacityChange {
to {
--opacity: 1;
}
}
#keyframes rotate {
to {
--angle: 360deg;
}
}
.rainbow {
animation: rotate 4s linear infinite, opacityChange 3s infinite alternate;
}
/* Hide the warning */
.warning {
display: none;
}
}
`;
function App() {
return (
<>
<Houdini>
<p>
This demo uses a real border with <code>border-image</code>, a
background, and finally Houdini to animate.
</p>
</Houdini>
<div>
<p>
⚠️ Your browser does not support{" "}
<a href="https://web.dev/css-individual-transform-properties/">
#property
</a>{" "}
so the animation won’t work
<br />
Please use Chrome.
</p>
</div>
</>
);
}
export default App;
And a slight variation the working Codepen
And the change in my App.tsx the rest is the same like above - same issue, I used styled components and the effect does not show.
const Houdini = styled.div`
.
.
.
--border-size: 0.3rem;
border: var(--border-size) dotted transparent;
background-image: linear-gradient(
to right,
rgb(255 255 255 / var(--opacity)),
rgb(255 255 255 / var(--opacity))
),
conic-gradient(
from var(--angle),
#d53e33 0deg 90deg,
#fbb300 90deg 180deg,
#377af5 180deg 270deg,
#399953 270deg 360deg
);
background-origin: border-box;
background-clip: padding-box, border-box;
.
.
.
`;
The culprit is the nested CSS rule that launches the animation:
.rainbow {
animation: rotate 4s linear infinite, opacityChange 3s infinite alternate;
}
...which, in the CodePen sample, targets the element with the border:
<div class="rainbow">
<p>This demo uses a real border with <code>border-image</code>,
a background, and finally Houdini to animate.</p>
</div>
But once converted to styled-components, the <div> with the "rainbow" class name was replaced by the <Houdini> styled React component. Hence its class name is no longer "rainbow", but generated by styled-components.
<Houdini> // styled-components replaces it by something like "<div class="sc-bczRLJ kCseJt">"
<p>
This demo uses a real border with <code>border-image</code>, a
background, and finally Houdini to animate.
</p>
</Houdini>
In order to achieve the same effect (i.e. preparation then a nested rule to launch the animation, applied on the same class name), we can simply use the & (ampersand) identifier, that styled-components replaces by the generated class name (SASS/SCSS technique):
https://styled-components.com/docs/basics#pseudoelements-pseudoselectors-and-nesting
& a single ampersand refers to all instances of the component; it is used for applying broad overrides
& /*.rainbow*/ {
animation: rotate 4s linear infinite, opacityChange 3s infinite alternate;
}
...and now the animation works!
Note: do not forget to also define your initial CSS variables (e.g. in the global CSS file):
:root {
--angle: 45deg;
--opacity: 0.5;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
Demo on CodeSandbox: https://codesandbox.io/s/winter-dream-ej7yec?file=/src/App.tsx:1069-1176
<script>
import '#interactjs/auto-start'
import '#interactjs/actions/drag'
import '#interactjs/actions/resize'
import '#interactjs/modifiers'
import '#interactjs/dev-tools'
import interact from '#interactjs/interact'
// Step 1
const slider = interact('.slider') // target elements with the "slider" class
slider
// Step 2
.draggable({ // make the element fire drag events
origin: 'self', // (0, 0) will be the element's top-left
inertia: true, // start inertial movement if thrown
modifiers: [
interact.modifiers.restrict({
restriction: 'self' // keep the drag coords within the element
})
],
// Step 3
listeners: {
move (event) { // call this listener on every dragmove
const sliderWidth = interact.getElementRect(event.target).width
const value = event.pageX / sliderWidth
event.target.style.paddingLeft = (value * 100) + '%'
event.target.setAttribute('data-value', value.toFixed(2))
}
}
})
</script>
<style>
.sliders {
padding: 1.5em
}
/* the slider bar */
.slider {
position: relative;
width: 100%;
height: 1em;
margin: 1.5em auto;
background-color: #29e;
border-radius: 0.5em;
box-sizing: border-box;
font-size: 1em;
-ms-touch-action: none;
touch-action: none;
}
/* the slider handle */
.slider:before {
content: "";
display: block;
position: relative;
top: -0.5em;
width: 2em;
height: 2em;
margin-left: -1em;
border: solid 0.25em #fff;
border-radius: 1em;
background-color: inherit;
box-sizing: border-box;
}
/* display the value */
.slider:after {
content: attr(data-value);
position: absolute;
top: -1.5em;
width: 2em;
line-height:1em;
margin-left: -1em;
text-align: center;
}</style>
<div class="sliders">
<div class="slider"></div>
<div class="slider"></div>
<div class="slider"></div>
</div>
I'm trying to use interact.js in rails 6, but I cannot get it to work. I am a newbie so this may be a common question, but how do I properly import an external library like interact.js. I've tried everything I've found online so I imagine I'm looking for the wrong thing. Any help will be appreciated, Thanks in advance!
this syntax:
import '#interactjs/auto-start'
import '#interactjs/actions/drag'
import '#interactjs/actions/resize'
import '#interactjs/modifiers'
import '#interactjs/dev-tools'
import interact from '#interactjs/interact'
is used for npm modules import. You can't do that in the browser without preprocessing your code. You can import the library like this, preferably in a separate script tag. But if you plan to import only one library you can set it
<script src="CDN url"></script>
Put it above your other script tag. Find an appropriate CDN host for your library. Example: https://cdnjs.com/libraries/interact.js/1.0.2
You can't use those import statements like this. If you import the library from CDN, you can use it like in the documentation. Look at https://interactjs.io/docs/installation CDN pre-bundled usage. I presume interact is globally exposed and you don't have to import anything.
If you want to go the proper way about this, you would be setting up a separate project/folder for your frontend application. That application has to be then built, and you attach the built distribution files in your Rails HTML. It depends on your purposes.
I've just included react-h5-audio-player into my project and following the README page to customise the styles by overwriting the SCSS variables responsible for the colours.
However it seems like my styles just get ignored. Do you have any idea what could be going wrong here? Thank you very much.
This is the codesandbox where I've reproduced the problem: https://codesandbox.io/s/react-and-scss-forked-yeu0q?file=/src/index.js
As you can see I've included the style.css (which contains the overwritten variables) in 3 places -- before importing audioplayer's js, before importing audioplayer's css and after both of these just in case to see if any of these works. I also randomly added !default and !important to the variables hoping that at least some of the syntax would work, but the styles are just keep being ignored.
I will also include the code to this post if someone prefers seeing it here rather in codesandbox:
style.css:
html,
body {
background-color: papayawhip;
font-family: sans-serif;
h1 {
color: tomato;
}
}
$rhap_theme-color: #ff0000; // Color of all buttons and volume/progress indicators
$rhap_background-color: #ff0000 !important; // Color of the player background
$rhap_bar-color: #ff0000 !default; // Color of volume and progress bar
$rhap_time-color: #0000ff !important !default; // Font color of current time and duration
$rhap_font-family: inherit !important; // Font family of current time and duration
index.js:
import React from "react";
import { render } from "react-dom";
import "./styles.scss";
import AudioPlayer from "react-h5-audio-player";
import "./styles.scss";
import "react-h5-audio-player/src/styles.scss";
import "./styles.scss";
const App = () => (
<div>
<h1>Hello</h1>
<AudioPlayer src="http://example.com/audio.mp3" />
</div>
);
render(<App />, document.getElementById("app"));
For another approach you can use this example:
.rhap_container {
background: #f7f7f9;
}
.rhap_controls-section {
margin-bottom: 15px;
}
.rhap_progress-section {
height: 20px;
padding-bottom: 20px;
}
.rhap_main-controls-button {
width: 80px !important;
height: 80px !important;
}
.rhap_main-controls-button {
width: 56px;
height: 56px;
display: block;
}
.rhap_main-controls-button svg {
color: #ff5555;
width: 100%;
height: 100%;
}
.rhap_progress-filled,
.rhap_progress-indicator {
background-color: #ff5555 !important;
}
.rhap_button-clear.rhap_volume-button {
color: #ff5555 !important;
}
.rhap_volume-bar, .rhap_volume-indicator {
background-color: red;
}
I am trying to trigger the button when mouse clicked it or a key is pressed and I get confused about communication between components. How should I call pressDown() in KeyButton component from its father component, or is there a better way to implement this function?
Here's my attempt
Container of button
<template>
<key-button :message="'Msg'" :callback="pressKey" ></key-button>
</template>
<script setup>
import KeyButton from "./KeyButton.vue";
import {ref,onMounted} from "vue";
onMounted(()=>{
addEventListener('keypress',(e)=>{
//trigger button
});
})
const pressKey = () => {
//exec when button clicked
}
</script>
KeyButton Component
<template>
<button class="button" :class="{'animate': active}" v-on="{mousedown:pressDown,animationend:triggerAnim}">{{props.message}}</button>
</template>
<script setup>
import {ref,defineProps} from 'vue';
const props = defineProps({
message: String,
callback: Function
})
const active = ref(false);
//Function to trigger button
const pressDown = ()=>{
props.callback();
triggerAnim();
}
const triggerAnim = ()=>{
active.value = !active.value;
}
</script>
<style scoped>
button{
display: flex;
height: 5rem;
width: 5rem;
justify-content: center;
align-items: center;
font-size: 2rem;
color: white;
border-color: deepskyblue;
border-width: 0.15rem;
border-radius: 50%;
background-color: lightskyblue;
margin-bottom: 1rem;
margin-left: 2rem;
outline: none !important;
}
.animate{
animation: zoom 0.2s;
}
#keyframes zoom {
0%{
transform: scale(1);
}
10%{
transform: scale(0.9);
}
100%{
transform: scale(1);
}
}
</style>
You shouldn't pass methods as props in vue as this creates interdependencies among the components and makes them less reusable.
Instead of passing the method you should emit an event from the KeyButton Component on keypress and listen to it in the parent component, like so:
// KeyButton Component
<button #click="$emit('button-pressed')" />
// Parent
<KeyButton #button-pressed="pressKey" />
You should not pass callbacks as props between components. Vue has a pattern to share functions between components: enter link description here, provide/inject pattern.
Although, I suggest you follow the approach Aside gave to you, and work with event handling provided by vue by emitting an event on child component to the parent.
I've got a setup where I'm using divs as buttons, and when they're clicked they add to ingredients to my burger.
JS:
<div id="ingredientBox">
<Ingredient
ref="ingredient"
v-for="item in currentIngredients"
v-on:increment="addToBurger(item)"
:item="item"
:lang="lang"
:ui-labels="uiLabels"
:key="item.ingredient_id">
</Ingredient>
</div>
With CSS:
.ingredient {
border: 1px solid #f5f5f28a;
padding: 0.8em;
width: 23vh;
height: 19vh;
background-color: green;
border-radius: 25px;
margin: 10px;
text-align: center;
}
I now want the div to react visually when clicked (maybe change color for like 0.2 seconds or something. I've looked around and only find info on how to change color permanently, is there a simple way of changing the color for just a brief moment?
You can use CSS keyframe animation to pull this off:
#keyframes animate-burger-button {
0% {
background: red;
}
50% {
background: yellow;
}
100% {
background: green;
}
}
#ingredientBox:active {
animation: animate-burger-button 0.8s forwards;
}
I would also add another note to try and use a button instead of a div, make accessibility a lot easier.
You could do something like
#ingredientBox:active {
color: red;
}
You could use setTimeout to add a class to the button and then remove it.
code:
buttonTrigger() {
element.classList.add('somesyle'); // add colour changing class to element
setTimeout(() => {
element.classList.remove('somestyle'); //remove the class after 0.2 seconds
}, 200)
}
EDIT
I was going to also suggest using CSS keyframes but #AlexanderKaran already suggested it. That is a good option too.