Here’s an alternative approach using custom component.
Prompt
Create a list of tags in a pill-style that would use the “Tags” column as input, each element delimited by a comma, justify-content: start, align-items: start.
Once clicked, determine the chosen tag’s name, set the chosen tag’s name to the “Viewing” column, wait 100ms, and execute the “Show tag” action.
Code
<html>
<head>
<script src="//unpkg.com/alpinejs"></script>
<style>
/*! tailwindcss v3.4.4 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit;margin:0}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }.flex{display:flex}.cursor-pointer{cursor:pointer}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.justify-start{justify-content:flex-start}.space-x-2>:not([hidden])~:not([hidden]){--tw-space-x-reverse:0;margin-left:calc(.5rem*(1 - var(--tw-space-x-reverse)));margin-right:calc(.5rem*var(--tw-space-x-reverse))}.rounded-full{border-radius:9999px}.bg-\[\#613DC7\]{--tw-bg-opacity:1;background-color:rgb(97 61 199/var(--tw-bg-opacity))}.bg-transparent{background-color:transparent}.px-4{padding-left:1rem;padding-right:1rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}
</style>
</head>
<script>
const S = Alpine.reactive({"tags":null,"viewing":null});
S.init = () => {
window.parent.postMessage({ type: "start-component" }, "*");
};
Alpine.data("state", () => S);
let updateTimeout = null;
Alpine.effect(() => {
let updates = {};
// Alpine needs to know about all the fields to watch them
if (S.tags !== null) updates.tags = S.tags;
if (S.viewing !== null) updates.viewing = S.viewing;
// Debounce updates to prevent spamming the parent window
if (updateTimeout) {
clearTimeout(updateTimeout);
updateTimeout = undefined;
}
updateTimeout = setTimeout(() => {
const updatesNoProxy = JSON.parse(JSON.stringify(updates));
window.parent.postMessage({ type: "set-state", state: updatesNoProxy }, "*");
}, 50);
});
function showTag() {
window.parent.postMessage(
{ type: "trigger-action", state: "showTag" },
"*"
);
}
function setState(newState) {
for (const key in newState) {
if (S[key] !== newState[key]) S[key] = newState[key];
}
}
window.addEventListener("message", event => {
switch (event.data.type) {
case "set-state":
const state = event.data.state;
setState(state);
break;
case "set-theme":
const theme = event.data.theme;
const root = document.querySelector(':root');
root.style.setProperty('--accent-color', theme.colors.accent);
root.style.setProperty('--foreground-color', theme.colors.foreground);
root.style.setProperty('--background-color', theme.colors.background);
break;
default:
break;
}
});
</script>
<body
x-data="state"
class="flex items-start justify-start bg-transparent"
>
<div
class="flex flex-wrap justify-start items-start space-x-2"
>
<template x-for="tag in tags.split(',')">
<div
class="bg-[#613DC7] text-white rounded-full px-4 py-2 cursor-pointer"
@click="viewing = tag.trim(); setTimeout(() => showTag(), 100)"
x-text="tag.trim()"
></div>
</template>
</div>
</body>
<script src="//cdn.jsdelivr.net/npm/@iframe-resizer/child"></script>
</html>
Updated: Succesfully changed, plus styling the text (font size + weight).
<html>
<head>
<script src="//unpkg.com/alpinejs"></script>
</head>
<style>
body {
font-size: 12px;
font-weight: 600;
}
</style>
<script>
const S = Alpine.reactive({
tags: null,
viewing: null,
});
S.init = () => {
window.parent.postMessage(
{ type: "start-component" },
"*"
);
};
Alpine.data("state", () => S);
let updateTimeout = null;
Alpine.effect(() => {
let updates = {};
// Alpine needs to know about all the fields to watch them
if (S.tags !== null) updates.tags = S.tags;
if (S.viewing !== null) updates.viewing = S.viewing;
// Debounce updates to prevent spamming the parent window
if (updateTimeout) {
clearTimeout(updateTimeout);
updateTimeout = undefined;
}
updateTimeout = setTimeout(() => {
const updatesNoProxy = JSON.parse(
JSON.stringify(updates)
);
window.parent.postMessage(
{ type: "set-state", state: updatesNoProxy },
"*"
);
}, 50);
});
function showTag() {
window.parent.postMessage(
{ type: "trigger-action", state: "showTag" },
"*"
);
}
function setState(newState) {
for (const key in newState) {
if (S[key] !== newState[key])
S[key] = newState[key];
}
}
window.addEventListener("message", (event) => {
switch (event.data.type) {
case "set-state":
const state = event.data.state;
setState(state);
break;
case "set-theme":
const theme = event.data.theme;
const root = document.querySelector(":root");
root.style.setProperty(
"--accent-color",
theme.colors.accent
);
root.style.setProperty(
"--foreground-color",
theme.colors.foreground
);
root.style.setProperty(
"--background-color",
theme.colors.background
);
break;
default:
break;
}
});
</script>
<body
x-data="state"
class="flex flex-col items-start justify-start bg-transparent w-full"
>
<div
class="flex flex-wrap items-start space-y-2 w-full"
>
<template x-for="tag in tags.split(',')">
<div
class="bg-[#613DC7] text-white rounded-full px-4 py-2 cursor-pointer mr-2 mb-2"
@click="viewing = tag.trim(); setTimeout(() => showTag(), 100)"
x-text="tag.trim()"
></div>
</template>
</div>
</body>
<script src="//cdn.jsdelivr.net/npm/@iframe-resizer/child"></script>
</html>