Custom attributes given to Stencil web components in Vite/Vue3 will not trigger any reactions

Short backstory

I initially set up my project with a vue-cli environment using Vue 2 and options-api. Recently, I decided to transition to create-vue, which is based on Vite with Vue 3 and Typescript. To incorporate web components from Stencil into my project, I created an npm package. While this process was smooth with my previous tech stack, I am currently facing challenges that I can't seem to figure out.

Current situation

Upon importing the npm package into my new environment, I encountered several errors which I managed to resolve by upgrading Stencil from v2.7.0 to v2.16.1 and adding experimentalImportInjection for proper compilation in Vite.

// stencil.config.ts

...
extras: {
  experimentalImportInjection: true
}

The main issue now lies with passing props to these components.

In Stencil, I have defined the props as follows:

  @Prop() state: 'none' | 'focus' | 'active' = 'none';

  @Prop() label: string;

  @Prop() meta: string;

  @Prop() disabled = false;

  @Prop() valid?: true | false | null = null;

While in my Vue code, I declare the custom component like this:

<fds-input id="loginEmail" label="Email" meta="meta text" :valid="false" :disabled="isDisabled">
  <input type="email" v-model="email" @blur="checkEmail" data-cy="input-text-email"/>
</fds-input>

My primary objective is to change the value of valid to toggle between valid and invalid states, each with different CSS styles.

Findings so far

  1. Altering the value of :valid or :disabled does not reflect any changes, regardless of whether I pass values as strings or booleans.
  2. On the other hand, changing the values of meta and label works seamlessly, be it through binding (:meta="") or regular attribute (meta="").
  3. When inspecting the element in my browser (Chrome), only the ID and class are visible on the element.
  4. Interestingly, setting the attribute valid="false" within a setTimeout function using vanilla JavaScript triggers the desired component state change.
  5. Even after upgrading Stencil to the latest version of v2, there has been no impact on the current issues.

Answer №1

Issue Resolved!

Although the root cause remains unclear, it is evident that Vite/Rollup handles custom elements generated from Stencil differently compared to vue-cli/Webpack.

In vue-cli/Webpack, my custom elements appear in the DOM tree as shown below:

<fds-input id="loginEmail" label="Email" valid="false">
...
</fds-input>

However, with Vite/Rollup, the appearance changes to:

<fds-input id="loginEmail">
...
</fds-input>

By adding the reflect: true option for the props I wish to modify in Stencil, the attributes become visible in the DOM and can be styled using CSS.

I also adjusted the prop to accept strings instead of booleans, ensuring backward compatibility and pleasing typescript. Using optional booleans with a null default was not an ideal strategy.

@Prop({ reflect: true }) valid?: 'true' | 'false';

NOTE: While all data passed to the custom element functions correctly, the issue lies with CSS styling due to a lack of targetable elements.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How should JSON files stored on the server side be properly utilized in Next.js?

Currently, I have a collection of JSON files that I expose through an API endpoint on my web application for global access. This allows different parts of the application to retrieve the data by sending a fetch request to itself... However, since this inf ...

In React Router v6, you can now include a custom parameter in createBrowserRouter

Hey there! I'm currently diving into react router v6 and struggling to add custom params in the route object. Unfortunately, I haven't been able to find any examples of how to do it. const AdminRoutes: FunctionComponent = () => { const ...

Tips for defining a distinct series of key-value pairs in typescript

Having experience with a different language where this was simple, I am finding it challenging to articulate a sequence of pairs: Each pair is made up of two basic elements (such as strings or numbers) Each element may appear multiple times within the lis ...

Issue: Button ClickEvent is not triggered when the textArea is in onFocus mode

Is there a way to automatically activate a button ClickEvent when the textArea input is focused? Keep in mind that my textArea has some styles applied, causing it to expand when clicked. Here is an example: https://stackblitz.com/edit/angular-ivy-zy9sqj?f ...

Difficulty in monitoring the present machine status through XState in a React application

I'm encountering an issue where I am trying to access the Machine state from within a function in a React component using state.value. However, the current state never changes and it always displays the initial state. Strangely, if I include an onClic ...

In Javascript, check if an item exists by comparing it to null

I am working with a dropdown list that can be used for various types of data. Some of the data includes an isActive flag (a BOOLEAN) while others do not. When the flag is absent, I would like to display the dropdown item in black. However, if the flag exis ...

How can I set a document ID as a variable in Firebase Firestore?

I recently set up a firestore collection and successfully added data (documents) to it. Firestore conveniently generates unique document ids for each entry. Inserting Data this.afs.collection('questions').add({ 'question': message, &a ...

Using Angular2 to assign the response from an http.get request to a class object

I am a beginner in Angular and I have a JSON file that holds the configuration URL for my application. Path: app/config/development.json { "apiUrl": "http://staging.domain.com:9000/", "debugging": true } Below is the content of my config.service.t ...

Tips for efficiently transferring information from Node.js to Vue 3 during server-side rendering

As I work on constructing a website with vue.js 3, my aim is to implement server-side rendering while also transmitting data from my fastify (or express) server to vue.js 3. I have heard of a tool called express-vue: github link, but it is designed for v ...

Loading static images in Vue components within a Django application

I am currently using a combination of Laravel Mix, Django, and Vue in my project. I want to be able to display static images within my Vue component that are stored in the 'static/img' folder. To begin with, I have created an alias in the Webpac ...

"The ion-label in Ionic2 is cutting off some of the text and not displaying it

I'm currently facing an issue with ion-label inside ion-item. The description is not properly displaying and instead, it shows dot-dot.. ..I need the entire text to be visible. Is there any solution available? <ion-card *ngFor="let product of prod ...

AngularJS 2: Modifications to templates or components do not automatically reflect in the user interface

My background is in Angular 1, where everything worked seamlessly. However, I am encountering serious issues trying to create a basic application using Angular 2 in Visual Studio. After carefully following the "5 minute tutorial" and getting it to work, I ...

"Experience a blank page equipped with vue-router featuring history mode and optimized for production purposes

I am a beginner with Vue and encountered the following error. I created a small project using the template from https://github.com/vuejs-templates/webpack with its default settings. After adding vue-router, everything works well in development mode. Howev ...

Converting PHP code to Typescript

Currently, I am working on developing a function for firebase that will trigger a POST request to call a specific URL. While I have successfully implemented GET requests, tackling the POST method has proven to be more challenging. I have some sample code ...

What is the best way to display JSON file results when clicking a button using Vue?

Once again, it's me! Check out my latest project here I am looking to retrieve data from a json file by inputting the necessary details and clicking on the button. For instance, let's say we want to find job listings for developers in Istanbul ...

Is there a way to turn off linting while utilizing vue-cli serve?

I am currently running my project using vue-cli by executing the following command: vue-cli-service serve --open Is there a way to stop all linting? It seems like it's re-linting every time I save, and it significantly slows down the process of ma ...

Issue with Angular 5 EventEmitter causing child to parent component emission to result in undefined output

I've been trying to pass a string from a child component to its parent component. Child Component: //imports... @Component({ selector: 'child', templateUrl: './child.component.html', styleUrls: ['./child.c ...

What steps can be taken to receive an alternative result when selecting a checkbox?

Currently, I am tackling the issue with checkboxes in Vuetify. The challenge lies in achieving a different output for the second {{ selected.join() }}. For example, when I select the checkbox labeled "Social Media," I receive the text "On our social medi ...

What is causing Axios to not effectively handle server response errors?

Currently, I am working with Laravel and Vue. I am using axios to make a request which responds with JSON data. However, if the data cannot be found, it returns a 404 error. Despite this, the catch block of axios does not seem to work. Here is the front-e ...

Exploring depths with Typescript recursion

I'm attempting to implement a recursive search in Typescript, but I am encountering an issue where TS is unable to determine the return type of the function. function findDirectory( directoryId: Key, directory: Directory, ) { if (!directory) ret ...