Can I somehow modify uikit's JS to allow me to use it with SvelteKit? - uikit

I have been working on this problem for a year now and can't find any resolution, so here goes nothing:
Since a recent update to Svelte or UIKit (sadly I don't know which) they seem to be conflicting with eachother. Svelte seems to want to control the DOM more aggressively than before, which interferes with UIKit's modifications. For example accordions and grids aren't displayed correctly.
My website footer should look like
, but actually looks like
All these examples and more can be seen on d20cay.com. The problem arises when you reload the page.
I tried
more explicitly setting the appropriate classes, which fixes the alignment of the elements, but the content of the accordion is visible (on load) when closed.
Contacting the UIKit developers with this issue. I didn't get a response.
Contacting the Svelte developers with this issue. I got a response saying I should check with the UIKit developers.
I tried figuring out the issue in the UIKit JavaScript and CSS, but I'm not good enough and/or the files are just too big.
Minimal working (or in this case not working) example can be found at github.com/d20cay/sveltekit-test.
At this point I'm just going to switch to a different CSS or UI framework. If anyone every finds a solution to this issue, be it in a few year's time I would very much appreciate a comment. Thanks.

As I see, the problem is somewhere in the SvelteKit hydration. It seems like the hydration is too aggressive and removes CSS classes that are not present in the HTML markup from svelte component.
As far as I understand, the following happens:
SvelteKit renders HTML on the server side (SSR).
uikit.js is loaded on the client side and applied to the rendered HTML (UIkit adds, for example, uk-grid class to elements with uk-grid attribute, registers ResizeObserver/MutationObserver, etc.).
SvelteKit hydrates the index.svelte component on the client side and this operation removes, for example, uk-grid class.
Without uk-grid class UIkit layout is broken.
Workaround 1
You can start uikit.js always after hydration. For this move uikit.js to src/lib/uikit.js and import it on mount.
src/routes/__layout.svelte:
<script>
import { onMount } from 'svelte'
onMount(() => {
import('$lib/uikit.js')
})
</script>
<slot/>
Workaround 2
Disable hydration for components that uses UIkit. But with this workaround Svelte JavaScript expressions will not work on the client side.
src/routes/index.svelte:
<script context="module">
export const hydrate = false
</script>
<div class="uk-child-width-1-2" uk-grid>
<div>test1</div>
<div>test2</div>
</div>
<ul uk-accordion>
<li>
<a class="uk-accordion-title" href="#">Item 1</a>
<div class="uk-accordion-content">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
</div>
</li>
</ul>

Related

With Quasar, images are displayed in the browser but not in the emulator (or actual phone)

I've written some Vue 3 code which works well in the browser but not in the emulator (for Android or iPhone) or on the actual phones.
The code loops through (v-for) a list of jpegs (1 to 3 currently) and displays the image, like this:
<template>
<div v-for="contact in contactDetails.contacts"
:key="contact.id">
<div><img :src="getImage(contact.id)" class="flex-container" alt="" style="height: 300px"></div>
</div>
</template>
<script setup>
const getImage = (imageData) =>{
return `src/assets/${imageData}.jpeg`
</script>
As I said, the above (slightly truncated code) works on the browser but not on the emulators or the actual phones.
I have looked around on the web but can't find the solution. Guidance will be appreciated.
So ... I fixed it.
The most important thing is that in Quasar your images have to be in, or in a folder under, the public folder.
Getting the path correct was a little bit difficult for me but the console would give clues on where it was looking (where it would give an error message along the lines of GET https://local/host/.../image.jpg or whatever).
I didn't have to do the fancy schmancy inserting a function into the :src URL as above. So my code looks something like this:
<div v-for="contact in contactDetails.contacts"
:key="contact.id">
<div class="linkTitle">{{ contact.service }}</div>
<img class="flex-containter" :src="`/${contact.imageURL}`" style="height:200px"/>
</div>
I faced the same thing.
i had to generate bundles in order test them directly on the phone.

Angular Google Maps – polyline works on Stackblitz but not locally

I need to wrap a div tag inside of an agm-polyline so it will accommodate both an ngFor and ngIf directive on the same agm-polyline-point tags. Example:
<agm-polyline [strokeColor]="'blue'">
<div *ngFor="let waypoint of waypoints">
<agm-polyline-point *ngIf="boolean" [latitude]="waypoint.lat" [longitude]="waypoint.lng"></agm-polyline-point>
</div>
</agm-polyline>
Adding the wrapped div results in the polyline no longer showing up in my browser when accessing on my computer from localhost:4200. However, when I run the code on Stackblitz it works perfectly.
Any ideas why this is happening? I've tried it locally on two versions of #agm/core (1.0.0 and 3.0.0-beta.0) with the same results each time.
Github is here.
Use ng-container instead of div.
When you use div tags, they are inserted into the DOM, which can interfere with the styling and structure of the page.
In contrast, ng-container tags are excluded from the DOM, but can use ngIf and other Angular constructs just as you are now.
<agm-map [latitude]="lat" [longitude]="lng">
<agm-polyline [strokeColor]="'blue'">
<ng-container *ngFor="let waypoint of waypoints">
<agm-polyline-point *ngIf="boolean" [latitude]="waypoint.lat" [longitude]="waypoint.lng"></agm-polyline-point>
</ng-container>
</agm-polyline>
</agm-map>

Vue.js transitions not working in Laravel Blade + Sass

My Google search didn't come up with any answer to is this expected behavior or am I doing something wrong.
My HTML:
<a v-on:click="showInformation = !showInformation">Show / Hide</a>
<transition name="fade">
<p class='further-info' v-if="!showInformation">Lorem ipsum dolor.</p>
</transition>
EDIT: Just found out that it works like this:
<transition name="fade">
<div v-if="!showInformation">
<p class='further-info'>Lorem ipsum dolor</p>
</div>
</transition>
This is not documented in the Vue.js documentation and it's clearly shown that it should work as the first example. Is this expected in my case?
My SASS:
.fade-enter-active, .fade-leave-active
transition: opacity .5s
.fade-enter, .fade-leave-to
opacity: 0
Pretty straight forward, but I may be doing something wrong. Whenever I click the button the p shows and hides correctly, but without any transition effect.
Using:
Laravel 5.7.9
Vue.js 2.9.6 (with ES6)
Sass 1.14.2 (but not relevant since it complies the transition code correctly)
The HTML file is written a blade template file
You should change the v-if to a v-show. This way the element exists in the page even though it's not displayed.

Angular UI-Router breaks Angular Material Flex and md-content

everybody.
I am using the following:
angular: 1.6.1,
angular-material: 1.1.3,
angular-ui-router: 1.0.0-rc.1
All my views are built using components and I am routing them with the UI-Router 1.x component syntax:
$stateProvider
.state('main', {
url: '/main',
component: 'main',
})
For the sake of completeness, my components are laid out as follows:
angular
.module('app.main')
.component('main', {
templateUrl: '/modules/main/main.html',
controller: MainCtrl,
})
MainCtrl.$inject = [];
function MainCtrl (){
}
My index.html is as follows:
<body ng-app="app" layout="column" ng-cloak>
<md-toolbar layout="row" layout-align="center center">
<h1>Site Title</h1>
</md-toolbar>
<div layout="column" flex ui-view></div>
My view for the main component is irrelevant at this point as the problem starts here. If, for example, my view for main.html is as follows:
<div layout="row" flex>
Content
</div>
The div will NOT flex. If, however, it is simply added in place of the ui-view in the parent, it will flex as normal.
<body ng-app="app" layout="column" ng-cloak>
<md-toolbar layout="row" layout-align="center center">
<h1>Site Title</h1>
</md-toolbar>
<div layout-align="column" flex>
Content (THIS WORKS FINE!)
</div>
Both contain the same attributes in the inspector apart from the usual differences in using ui-view.
This also seems to be causing problems with md-content, which will only scroll if it is the element in the parent that contains the ui-view. Any nested md-contents will not scroll.
I have also tried using the original ui-router way of routing to controllers and templates which was the norm before the .component syntax.
There is a similar problem listed here:
Angular Material layout breaks when using UI-Router
It seems that this gentleman's solution was to abandon UI-Router and use ng-route. I really don't want to move away from UI-Router and am considering completely abandoning Angular-Material but would really prefer to avoid that.
Can anybody please help out with this?

When to use spring:url tag?

I think the question is the same for huge manipulations with URL (ie Why?). Where people just reconstruct the URL from scratch.
Does it not hinder the visibility of the app for UI developers if all they see:
<link href="${some_url_possibly_not_named_logically_i_e_karamba1243}/less/bootstrap.less"/>
I just don't understand use cases where these tags are used and why should I?
How can this example snippet be improved with usage of spring:url tag? Would it be used just to remove repetitive part of URL?
<div id="header">
<ul>
<li>Home</li>
<li>My Profile</li>
<sec:authorize access="hasRole('ROLE_Coach')">
<li>Training</li>
</sec:authorize>
<sec:authorize access="hasRole('ROLE_Player')">
<li>Training</li>
</sec:authorize>
<sec:authorize access="hasRole('ROLE_Manager')">
<li>Administration</li>
</sec:authorize>
</ul>
</div>
Or the major concern is that if same URL will be used in another .jsp we can just grab a variable, but then again this tag is specific to jsp scope so other pages cannot use it. I
What's wrong with the traditional approach? Are there examples where I can't use anything but spring:url.
It is exactly one of those cases where everyone uses it, no one explains(even google - providing super url reconstruction cases) and everyone happy except me, feeling confused and dumb :-)
Use it when you need to have dynamic components in generated URLs (e.g. /app/resources/{name}) and when you need to make sure those URL components (e.g. {name} as above) are properly escaped. Look here for more info.
Also note that you CAN have global attributes that you use with e.g. the <spring:url /> tag across multiple JSPs. Have a look at setExposedContextBeanNames(String[]) here.

Resources