Extending nodes: Lexical node does not exist in active editor

I’m running a React Vite project with a Lexical editor. I’m trying to extend the list node, to make it styleable (square, circle, roman numerals, etc.). Here is my extended node file:

    import { ElementNode, createCommand } from 'lexical';
    import { ListNode } from '@lexical/list';

    export const INSERT_UNORDERED_CUSTOM_LIST_COMMAND = createCommand('INSERT_UNORDERED_CUSTOM_LIST_COMMAND');

    export class ExtendedListNode extends ListNode {
        __listStyleType;
        __key;

        static getType() {
            return 'custom-list'
        }

        static clone(node) {
            console.log("ExtendedListNode: clone(): node", node);
            return new ExtendedListNode(node.__listStyleType, node.__key);
        }

        consructor(listStyleType, key) {
            console.log("ExtendedListNode: constructor(): listStyleType", listStyleType);
            console.log("ExtendedListNode: constructor(): key", key);
            super('bullet', 1, key)
            this.__listStyleType = listStyleType || 'circle';
            this.__key = key;
        }

        createDOM(config) {
            const dom = document.createElement(this.getTag());
            dom.style.listStyleType = this.__listStyleType;
            return dom;
        }

        updateDOM(prevNode, dom, config) {
            if (prevNode.__listStyleType !== this.__listStyleType) {
                dom.style.listStyleType = this.__listStyleType;
            }
            return false;
        }

        static importJSON(serializeNode) {
            return {
                ...super.importJSON(serializedNode),
                listStyleType: serializedNode.listStyleType
            };
        }

        exportJSON() {
            return {
                ...super.exportJSON(),
                listStyleType: this.__listStyleType
            };
        }

        getTag() {
            return 'ul';
        }

        getListStyleType(listStyleType) {
            return this.__listStyleType;
        }

        setListStyleType(listStyleType) {
            this.__listStyleType = listStyleType;
        }

        export function $createExtendedListNode(listStyleType, key) {
            console.log(`$createExtendedListNode('${listStyleType}')`);
            return new ExtendedListNode(listStyleType, key);
        }

        export function $isExtendedListNode(node) {
            return node instanceof ExtendedListNode;
        }
    }

Here is my config that replaces the ListNode with the ExtendedListNode:

    import { ListItemNode, ListNode } from '@lexical/list';
    import { ExtendedListNode } from '/src/components/lexical/ExtendedListNode';

    const editorConfig = {
        namespace: 'MyApp',
        nodes: [
            ListItemNode,  //other nodes left out of this snippet to keep it simple
            { 
                replace: ListNode, with: (listNode) => {
                    console.log("this listNode node", listNode);
                    const newNode = new ExtendedListNode('square');  //, listNode.__key  , listNode.getKey()
                    console.log("this newNode node", newNode);
                    return newNode;
                },
                withKlass: ExtendedListNode,
            },
        ],
        onError(error) {
            throw error;
        },
        theme: LexicalTheme,
    }

The error message I’m getting (line numbers may be off, as I can’t post all the code):
screenshot of error message

Text of error message (line numbers may be off, as I can’t post all the code):

Uncaught Error: Lexical node does not edist in active editor stage. Avoid using the same node references between nested closures from editorState.read/editor.update.
    at editor.update.discrete (lexicalUtil.js:42:29)

Uncaught Error: Lexical node does not edist in active editor stage. Avoid using the same node references between nested closures from editorState.read/editor.update.
    at ExtndedListNode.getLatest
     at ExtndedListNode.getWritable
     at ExtndedListNode.markDirty
     at editor._pendingEditorState.tag
     at $beginUpdate
     at updateEditor
     at markAllNodesAsDirty
     at LexicalEditor.registerNodeTransform
     at @lexical_react_Lexic...js
     at commitHookEfectListMount

I can see my editor flash on the screen or a split second, but then the page goes blank white. If I comment out the extended list node replace in the editorConfig, the page and editor render fine, so I’m guessing I’ve got something coded wrong in that, or in the extended node file. Any ideas? Thanks!

Delaying 2 setIntervals using setTimeout doesn’t work

I’ve been writing a userscript for a site and I want to show an update notification while the user is tabbed off of the site, and I came up with an idea to use the site title for that.

This is my current code:

let str = "Please update your script!"
let str2 = "[insert previous site title]"
setInterval(function(){document.title = str}, 1000)
setTimeout(function(){setInterval(function(){document.title = str2}, 1000)}, 1000)

the code should work in theory but instead flashes str for way less than 1000 ms, and goes back to str2 when done, and the routine never repeats, even with the setInterval.

I’ve tried moving the code to a function and using setInterval() on that too, but it does the same thing.
The code in question:

function updateDialog(str, str2) {
    document.title = str
    setTimeout(function(){document.title = str2}, 1000)
}
setInterval(updateDialog("Please update your script!", "[insert previous site name]"), 1000)

I’ve already got the update check code for that, by the way.

Any reason for why this doesn’t work the expected way?

How to hide other element when I click on one?

I’m trying to hide the other buttons that are created with my for loop when I click on one of the element I created.

Here is the loop where my button elements are created:

//diplay the fixed bar product by name
for (let i = 0; i < barType.fixedBar.length; i++) {
  barNameButton = document.createElement("button");
  barNameButton.setAttribute("classe", `${barType.fixedBar[i].name}`);
  document.body.appendChild(barNameButton);
  barNameButton.innerHTML = `${barType.fixedBar[i].name}`;
}

When one of the names has been clicked on I want to hide the others and display some options for that specific type that has been selected.

Using Framer Motion add class to div after scrolling fully past it

I have an element that becomes visible when it enters the viewport, with scroll animated child elements, I need for it to stay visible after scrolling past, with the animations done after, but reverses animations with scrolling up and reverts to being invisible when scrolled back up again.

I was able to achieve that using GSAP using the scrolltrigger toggleClass, onLeave and onEnterBack

const tl = gsap.timeline({
         scrollTrigger: {
           trigger: section,
           scrub: true,
        start: "top 80%",
         end: "center center",
            toggleClass: "isVisible",
          onLeave: () => section.classList.add("isScrolled"),
           onEnterBack: () => section.classList.remove("isScrolled"),
         },
       });

but I had to move from gsap to framer motion since I have quite a bit of animations that require dom-manpulation and elements entering and exiting it plus between route loading animations, which unfortunately GSAP can’t do.

So with Framer Motion, I’m assuming this is possible to do but the documentation isn’t that great so I couldn’t find what I was looking for.

And I wanted to have that done using Framer Motion because I think it’s better to have the code relating to these elements in one place and is done using one library.

PHP not updating global variable DURING loop? [duplicate]

I have a javascript file that sends XMLHttpRequests to a PHP file. The javascript file is something like this:

let formData = new FormData();
formData.append("field1", ["mockdata1", "mockdata2"]);

let xhr = new XMLHttpRequest();
xhr.open("POST", "../phpscripts/agent.php");
xhr.send(formData);

And the PHP file is something like this:

//globals 
$globalResult = "undefined";


if( !empty( $_POST['field1'] )){
  
   $localResult; 

   for($x=0; $x<someLimit; $x++){
      //update $localResult with cURL calls
      
      //also set the globalResult
      set_globalResult($localResult);

    }

    return $result;
}

function get_globalResult(){
  global $globalResult;
  return $globalResult;
}

function set_globalResult($param){
   global $globalResult;
   $globalResult = $param;
}

The cURL calls that occur within the loop in my PHP file take some time. Each one can take between 0.5 to 2 seconds. I find that it takes about 10 seconds or so for my xhr object in Javascript to finally get the response.

What I want to do is create a kind of listening system so that it can read the progress that is occuring within the loop. i.e. read the result after each cURL call.

So I have created a global variable in my php file called $globalResult. Which is supposed to get updated from inside the loop. I have also created a getter and setter for this variable.

So to use this global variable, I have created a second XHR object in my javascript file that makes requests to this same PHP file every 1 second (using setInterval). Something like this:

setInterval( function() {
  let form2 = new FormData();
  form2 .append("listen", ["mockdata1", "mockdata2"]);

  let xhr_listener = new XMLHttpRequest();
  xhr_listener.open("POST", "../phpscripts/agent.php");
  xhr_listener.send(form2 );
}, 1000);

xhr_listener.onreadystatechange = function (){
            if (xhr_listener.readyState === XMLHttpRequest.DONE){
               //inject xhr_listener.response into a div
              }

And the PHP file has an additional part like this:

if( !empty( $_POST['listen'] )){
      $result = get_globalResult();
    
    $returnPackage = array("Result" => $result);

   echo       json_encode($returnPackage);  
}

Even with a setup like this, I find that the response of that xhr_listener is always “undefined” (the initial value of the global variable). Even though I am setting a new value to the global variable from inside the loop?

Why?

It seems that the new value assignment to the global value finalizes only after that loop is finished in PHP. Is that really how it works? Or is the updated value accessible after each iteration of the loop?

TypeScript: Complex conditional form field type system with dynamic validation based on multiple option flags

I’m building a TypeScript form library with conditional fields that need to be dynamically typed based on form type and several option flags. I need a robust type system that shows the correct field names based on multiple conditions.

Base Types

export type FormType = "bank" | "card" | "token";

export type CardFieldName = "name" | "number" | "expiration_date" | "security_code";
export type BankFieldName = "account_number" | "bank_code" | "account_type";
export type AddressFieldName = "address_line1" | "address_line2" | "address_city" | "address_state" | "address_region" | "address_country" | "address_postal_code";

export type FieldName = CardFieldName | BankFieldName | AddressFieldName;

Form Creation API

// Basic form creation
const tokenForm = createForm({ formType: 'token' }) // Shows both bank and card fields
const bankForm = createForm({ formType: 'bank' })   // Shows only bank fields
const cardForm = createForm({ formType: 'card' })   // Shows only card fields

// Advanced usage with options
const advancedForm = createForm({
  formType: 'card',
  showAddress: true,
  showLabels: true,
  labels: {
    name: 'Full Name on Card',
    number: 'Card Number',
    address_line1: 'Address Line 1' // Only valid when showAddress is true
  },
  requiredFields: ['name', 'number'] // Should only allow valid field names
})

Form Option Type

type FormOptions = {
  formType: FormType; /* If card show CardFieldName's - If bank show BankFieldName's - If token show both CardFieldName's and BankFieldName's */
  showAddress?: boolean; /* If showAddress is true, it should include all of the AddressFieldName's */
  showLabels?: boolean;
  showPlaceholders?: boolean;
  hideErrorMessages?: boolean;
  labels?: Record<FieldName, string>; /* If showLabels is true, a user should be able based off of the field types so we know which field names we can set labels for */
  placeholders?: Record<FieldName, string>; /* If showPlaceholders is true, a user should be able based off of the field types so we know which field names we can set placeholders for */
  errorMessages?: Record<FieldName, string>; /* If hideErrorMessages is false, a user should be able based off of the field types so we know which field names we can set error messages for */
  defaultValues?: Record<FieldName, string>; /* We need to know all the field names available so we know which fields we can set default values for. Some fields DO NOT allow default values though even if they are present in field names */
  requiredFields?: Array<FieldName>; /* We need to know all the field names available so we know which fields we can set as required. Some fields are required NO MATTER WHAT so we can only set some fields as required */
  hideFields?: Array<FieldName>; /* We need to know all the field names available so we know which fields we can hide. Some fields are can NOT be hidden though even if they are available in field names */
}

Desired Type Behavior

I need TypeScript to enforce the following complex rules:

  1. Form Type Restrictions:

    • If formType: 'card', only CardFieldName values should be valid
    • If formType: 'bank', only BankFieldName values should be valid
    • If formType: 'token', both CardFieldName and BankFieldName values should be valid
  2. Conditional Address Fields:

    • If showAddress: true, then AddressFieldName values should also be valid
    • If showAddress is falsy, AddressFieldName values should be invalid
  3. Option-Dependent Record Types:

    • labels should only allow keys from the available field names, and only if showLabels: true
    • placeholders should only allow keys from the available field names, and only if showPlaceholders: true
    • errorMessages should only allow keys from the available field names, and only if hideErrorMessages: false
  4. Field Restrictions with Business Logic:

    • defaultValues should only allow keys from the available field names, but exclude fields that don’t support default values
    • requiredFields should only allow values from the available field names, but exclude fields that are always required
    • hideFields should only allow values from the available field names, but exclude fields that cannot be hidden

Example Scenarios That Should Type-Check Correctly

// Valid: card fields only
const cardForm = createForm({
  formType: 'card',
  labels: {
    name: 'Name on Card',
    number: 'Card Number'
  }
});

// Invalid: includes bank field with card form
const invalidForm1 = createForm({
  formType: 'card',
  labels: {
    name: 'Name on Card',
    account_number: 'Account Number' // Error: not valid for card form
  }
});

// Invalid: includes address field without showAddress
const invalidForm2 = createForm({
  formType: 'card',
  labels: {
    name: 'Name on Card',
    address_line1: 'Street Address' // Error: showAddress not true
  }
});

// Valid: address fields with showAddress true
const cardWithAddressForm = createForm({
  formType: 'card',
  showAddress: true,
  placeholders: {
    name: 'John Doe',
    address_line1: '123 Main St' // Valid because showAddress is true
  }
});

// Invalid: using errorMessages when hideErrorMessages is true
const invalidForm3 = createForm({
  formType: 'bank',
  hideErrorMessages: true,
  errorMessages: { // Error: errorMessages not allowed when hideErrorMessages is true
    account_number: 'Invalid account number'
  }
});

// Invalid: trying to make a non-configurable field required
const invalidForm4 = createForm({
  formType: 'card',
  requiredFields: [
    'security_code' // Error: security_code is always required and cannot be in requiredFields
  ]
});

// Invalid: trying to hide a field that cannot be hidden
const invalidForm5 = createForm({
  formType: 'card',
  hideFields: [
    'number' // Error: card number cannot be hidden
  ]
});

// Invalid: trying to set default for a field that doesn't allow defaults
const invalidForm6 = createForm({
  formType: 'card',
  defaultValues: {
    security_code: '123' // Error: security_code cannot have a default value
  }
});

What I’m Looking For

I need a comprehensive type solution that:

  1. Handles all conditional field types based on formType and showAddress
  2. Enforces the presence/absence of option-dependent fields like labels, placeholders, and errorMessages based on their corresponding boolean flags
  3. Implements business logic restrictions for defaultValues, requiredFields, and hideFields
  4. Provides helpful TypeScript error messages
  5. Achieves proper type inference so developers get autocomplete for the correct fields only

What would be the best approach? Should I use:

  • Discriminated unions with conditional types?
  • Generics with mapped types?
  • Custom utility types?
  • A combination of these?

Also, how would you recommend handling runtime validation alongside static typing?

PHP not updating global variable DURING loop?

I have a javascript file that sends XMLHttpRequests to a PHP file. The javascript file is something like this:

let formData = new FormData();
formData.append("field1", ["mockdata1", "mockdata2"]);

let xhr = new XMLHttpRequest();
xhr.open("POST", "../phpscripts/agent.php");
xhr.send(formData);

And the PHP file is something like this:

//globals 
$globalResult = "undefined";


if( !empty( $_POST['field1'] )){
  
   $localResult; 

   for($x=0; $x<someLimit; $x++){
      //update $localResult with cURL calls
      
      //also set the globalResult
      set_globalResult($localResult);

    }

    return $result;
}

function get_globalResult(){
  global $globalResult;
  return $globalResult;
}

function set_globalResult($param){
   global $globalResult;
   $globalResult = $param;
}

The cURL calls that occur within the loop in my PHP file take some time. Each one can take between 0.5 to 2 seconds. I find that it takes about 10 seconds or so for my xhr object in Javascript to finally get the response.

What I want to do is create a kind of listening system so that it can read the progress that is occuring within the loop. i.e. read the result after each cURL call.

So I have created a global variable in my php file called $globalResult. Which is supposed to get updated from inside the loop. I have also created a getter and setter for this variable.

So to use this global variable, I have created a second XHR object in my javascript file that makes requests to this same PHP file every 1 second (using setInterval). Something like this:

setInterval( function() {
  let form2 = new FormData();
  form2 .append("listen", ["mockdata1", "mockdata2"]);

  let xhr_listener = new XMLHttpRequest();
  xhr_listener.open("POST", "../phpscripts/agent.php");
  xhr_listener.send(form2 );
}, 1000);

xhr_listener.onreadystatechange = function (){
            if (xhr_listener.readyState === XMLHttpRequest.DONE){
               //inject xhr_listener.response into a div
              }

And the PHP file has an additional part like this:

if( !empty( $_POST['listen'] )){
      $result = get_globalResult();
    
    $returnPackage = array("Result" => $result);

   echo       json_encode($returnPackage);  
}

Even with a setup like this, I find that the response of that xhr_listener is always “undefined” (the initial value of the global variable). Even though I am setting a new value to the global variable from inside the loop?

Why?

It seems that the new value assignment to the global value finalizes only after that loop is finished in PHP. Is that really how it works? Or is the updated value accessible after each iteration of the loop?

Looping elements and sequentially clicking on children

I’m trying to automate a task through Firefox’s console in Developer Tools by running some jQuery code.

First, an example of the nodes I need to loop through. Note inline comments. There are nodes where the button has a span that doesn’t contain the word Cycling and should be skipped.

<div class="ActivityListItem_activityType__qQkN4">
    <button>
        <span class="ActivityListItem_activityTypeText__jWs2o">Cycling</span>
        <span class="InlineEditDropdown_iconPointerDown__0bK4V ActivityListItem_isHidden__2pG6N"><i
                class="icon-pointer-down"></i>
        </span>
    </button>

    <!-- dynamically added after clicking above button -->
    <ul class="InlineEditDropdown_dropdownContainer__E5M6g" role="menu">
        <!-- omitted children li -->
        <li class="InlineEditDropdown_dropdownItem__WkY6H null null" tabindex="0"><a href="#" role="menuitem">Mountain Biking</a></li>
        <!-- omitted children li -->
    </ul>
</div>

The steps that seem to need to be replicated:

  1. click the button, which fires and event and makes a list appear
  2. from the list, click the option wanted which fires another event

The script I’m running in the console:

var script = document.createElement('script');
script.src = 'https://code.jquery.com/jquery-3.6.0.min.js';
document.head.appendChild(script);

var x = 0;
//select using start of the class name
$('div[class^="ActivityListItem_activityType"]').each(function(x){
    //alert("here..."+x); //outputs incremented value
    
    //click to make the list appear
    $(this).children('button span:contains("Cycling")').click();
    
    //click the right li to launch event
    $(this).children('ul li a:contains("Mountain Biking")').click();
});

No errors, but I’m not seeing much happen either (other than the alert when it’s enabled).

Assuming my selectors are wrong? Perhaps I’m misunderstanding how to use .children()?

How to render on nodejs server side?

Given this server.ts code:

import 'ignore-styles';
import register from '@babel/register';
import express from "express";
import fs from "fs";
import path from "path";
import ReactDOMServer from "react-dom/server";
import App from "./src/App";

register({
  ignore: [/(node_modules)/],
  extensions: ['.ts', '.tsx'],
  presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript'],
});

const app = express();

app.use("^/$", (req, res) => {
  fs.readFile(path.resolve("./build/index.html"), "utf-8", (err, data) => {
    if (err) {
      console.error(err);
      return res.status(500).send("Some error happened");
    }

    const renderedApp = ReactDOMServer.renderToString(<App />);
    return res.send(
      data.replace('<div id="root"></div>', `<div id="root">${renderedApp}</div>`)
    );
  });
});

app.use(express.static(path.resolve(__dirname, "..", "build")));

app.listen(3005, () => {
  console.log("App is launched");
});

I have the following syntax error:

'App' refers to a value, but is being used as a type here. Did you mean 'typeof App'?ts(2749)
type App = /*unresolved*/ any

And when I try to run the server app with npx tsx server.ts I get the following error:

[...]
> npx tsx server.ts


node:internal/modules/run_main:122
    triggerUncaughtException(
    ^
Error [TransformError]: Transform failed with 1 error:
[...]/server.ts:24:59: ERROR: Expected ">" but found "/"

The App component is stored in the /src folder:

import React from "react";

const App: React.FC = () => {
  return (
    <div className="app">
      <h1>Hello world</h1>
    </div>
  );
};

export default App;

together with the index.tsx

import React from "react";
import App from "./App";
import { hydrateRoot } from 'react-dom/client';


const container = document.getElementById('root');
const root = hydrateRoot(container, <App/>);

And the server.ts file is at the root of the repository, in the parent folder of src.

And this is my tsconfig.json file:

{
  "compilerOptions": {
    "target": "ESNext",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "ESNext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src"
  ]
}

One more thing important to mention is that my VSC compiler is greying out the import of the App(import App from "../client/src/App";), so it doesn’t even see the <App /> from the code as the App from the import.

How can I get this working? I’m trying to render some react on server side using nodejs + express and I just can’t figure out what’s wrong with this one.
Any help will be much appreciated!

React Application Loading with Delay, Showing Blank Screen Initially

I’m working on a mid-level React project, and I’m facing an issue when the app is loaded for the first time on any device. Initially, the screen stays blank, and after some time, the entire page loads. This delay causes a poor user experience, especially on first visits.

What could be causing this issue, and how can I resolve it to improve the initial loading time and avoid the blank screen?

Here are a few things I’ve tried:

Ensured that assets (JS/CSS) are properly bundled.

Checked the network tab in Dev Tools for any slow resource loading.

I’m looking for suggestions on how to optimize the initial load and improve the perceived performance.

Leaflet React map does not load?

I tried to use a React Leaflet example and but it does not render map correctly. My codes is:

import './App.css';
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';

const App = () => {
  return (
    <MapContainer center={[51.505, -0.09]} zoom={13} scrollWheelZoom={false}>
      <TileLayer
        attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      />
      <Marker position={[51.505, -0.09]}>
        <Popup>
          A pretty CSS3 popup. <br /> Easily customizable.
        </Popup>
      </Marker>
    </MapContainer>
  );
}

export default App;

What I get is:

screenshot

Maybe you’ll say I do not have Leaflet CSS. But when I add the
import "leaflet/dist/leaflet.css" in main.jsx and also
.leaflet-container { width: 100%; height: 100vh; }
in App.css

the map does not appear at all. Now I get:
enter image description here

How can I fix my codes?

mapbox-gl-js creates artifacts in corner with geojson data (only when screen height is > 1024px)

Minimum reproducible example:

I am using mapbox-gl-js on a website (angular)

I am using this dataset for the MRE (minimum reproducible example):

Here is the github repo:
https://github.com/folsze/mapbox-gl-js-world-map-artifact

How to reproduce:

  1. clone project
  2. in terminal: npm i
  3. in terminal: npm run start
  4. open browser inspect tools
  5. select device to “responsive”
  6. set screen height to > 1024 px (e.g. 1025 px)
  7. zoom all the way out on the map (mousewheel)

Then you will see the artifact here, at the world wrap:

enter image description here

Note:
I am getting the data from here:
https://www.naturalearthdata.com/downloads/50m-cultural-vectors/50m-admin-0-countries-2/

and converted shpfile to geojson using the QGIS software

here is the resulting data:

https://github.com/folsze/mapbox-gl-js-world-map-artifact/blob/main/src/assets/a.geojson

(note: you can even see the issue in the data itself on the github OSM-viewer, so I guess it’s not the libraries fault but the data has some issues)

(drop into layers, right click feature, Export->Save Feature As…-> GeoJson)

Note:

Here is my relevant code:

HTML:

<ion-content [fullscreen]="true">
  <div id="map"></div>
</ion-content>

CLASS:

import { Component } from '@angular/core';
import { IonContent } from '@ionic/angular/standalone';
import * as mapboxgl from 'mapbox-gl';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
  imports: [IonContent],
})
export class HomePage {

  map!: mapboxgl.Map;
  features: any[] = [];

  constructor() {}

  ngOnInit() {
    fetch('/assets/a.geojson')
      .then(response => response.json())
      .then(data => {
        this.features = data.features;
        this.initializeMap(data);
      });
  }

  initializeMap(geojsonData: any) {
    this.map = new mapboxgl.Map({
      attributionControl: false,
      accessToken: 'pk.eyJ1IjoiZmVsaXhvbHN6ZXdza2kiLCJhIjoiY2xyNTZrOTJvMWcxeTJrbnZsM2RuOGk5aiJ9.TENtwqeAtqAqSNzFmg0i4w',
      container: 'map',
      style: {
        version: 8,
        glyphs: 'mapbox://fonts/mapbox/{fontstack}/{range}.pbf',
        sources: {
          'countries': {
            type: 'geojson',
            data: geojsonData,
            promoteId: 'admin',
          }
        },
        layers: [
          {
            id: 'background',
            type: 'background',
            paint: {
              'background-color': '#c6ecff'
            }
          },
          {
            id: 'country-fills',
            type: 'fill',
            source: 'countries',
            paint: {
              'fill-color': '#2e34da',
              'fill-opacity': 1
            }
          },
          {
            id: 'country-borders',
            type: 'line',
            source: 'countries',
            paint: {
              'line-color': '#000',
              'line-width': 0.5,
            }
          }
        ]
      },
      center: [-84.077922, 10.0651],
      zoom: 7
    });

  }

}

On click of button the background color of div does not change

I have a simple program where, on the click of button, I expect the background of my component color to change, but it does not. Where am I making mistake?

import { useState } from "react";
import './sixth.css';

const Sixth = () => {

    const [bgColor, setBgColor] = useState("white"); 

    const bgFunc = (val)=> {
        setBgColor(val); 
    }

    return (
        <div className="sixth" style={{'background': {bgColor}}}>
            <button onClick={()=> bgFunc("red")}>red</button>
            <button onClick={()=> bgFunc("green")}>green</button>
            <button onClick={()=> bgFunc("blue")}>blue</button>
        </div>
    )
}

export default Sixth;

Terminal Layout Library

What I need

For one card-game prototype I’m developing I need module that would handles user interface in terminal.

I want to display pretty and aligned layout of game board and allow user to interact with it using keys and arrows. It’s worth pointing out that layout of game board is more complex then simple table.

Attempted Solution

I wrote small library that work like this:

  1. Switch terminal into raw + alternate mode (using curses gem)
  2. Print A thing based on data (supposedly board layout)
  3. Every time user presses a key we care about, update data
  4. Refresh screen and repeat from step 2

It also supports switching between scenes

Problem

My library is too low level to know how to print aligned layout or make it intractable. I don’t what to solve this problem myself.

Does anyone know library that does that? My project is written in Ruby, but I can rewrite it into JavaScript, so preferably one that works with those two languages.