I managed to create a fully functional custom component using only AI. I was looking for a solution to publish data from Google Sheets on a website. Currently, I can specify which data to retrieve, which data to display, and how to style the header and rows (font, color, alignment, style, padding, background color, and line color). It took a lot of trial and error, but I got it to work. The only issue I’m still facing is that the display isn’t responsive yet. If a solution is found for this, I’ll be able to use it in the design of published websites.
Hey @Bartje,
The controls with dots by them will “just work” responsively. It’s magic!
However, I think you’re talking about your table… If this is the case you’ll probably need to add some tailwind classes to your template html to get it to display how you want at each size - this is something we can probably help you with!
If you paste your Template code below we can take a look…
Hey Dan,
Ok. This is the code: In the meantime, I’m looking into automatically generating a card layout for each row of Google Sheets data. That’s another possible solution. It’s coming together quickly, and with some luck, it should work as well! ![]()
<div id="{{uniqueId}}">
@if(edit)
<table class="table-auto w-full border-collapse">
<thead>
<tr>
<th class="{{headerFont}} {{headerBgColor}} {{headerTextColor}} {{headerBorderColor}} {{headerBorderWidth}} {{headerBorderRadius}} {{headeralignment}} {{headingTextStyles}} {{headerthemeSpacing}}">Kolom 1</th>
<th class="{{headerFont}} {{headerBgColor}} {{headerTextColor}} {{headerBorderColor}} {{headerBorderWidth}} {{headerBorderRadius}} {{headeralignment}} {{headingTextStyles}} {{headerthemeSpacing}}">Kolom 2</th>
<th class="{{headerFont}} {{headerBgColor}} {{headerTextColor}} {{headerBorderColor}} {{headerBorderWidth}} {{headerBorderRadius}} {{headeralignment}} {{headingTextStyles}} {{headerthemeSpacing}}">Kolom 3</th>
</tr>
</thead>
<tbody>
<tr>
<td class="{{rowFont}} {{rowBgColor}} {{rowTextColor}} {{rowBorderColor}} {{rowBorderWidth}} {{rowBorderRadius}} {{rowalignment}} {{rowTextStyles}} {{themeSpacing}}">Voorbeeld data 1A</td>
<td class="{{rowFont}} {{rowBgColor}} {{rowTextColor}} {{rowBorderColor}} {{rowBorderWidth}} {{rowBorderRadius}} {{rowalignment}} {{rowTextStyles}} {{themeSpacing}}">Voorbeeld data 1B</td>
<td class="{{rowFont}} {{rowBgColor}} {{rowTextColor}} {{rowBorderColor}} {{rowBorderWidth}} {{rowBorderRadius}} {{rowalignment}} {{rowTextStyles}} {{themeSpacing}}">Voorbeeld data 1C</td>
</tr>
<tr>
<td class="{{rowFont}} {{rowBgColor}} {{rowTextColor}} {{rowBorderColor}} {{rowBorderWidth}} {{rowBorderRadius}} {{rowalignment}} {{rowTextStyles}} {{themeSpacing}}">Voorbeeld data 2A</td>
<td class="{{rowFont}} {{rowBgColor}} {{rowTextColor}} {{rowBorderColor}} {{rowBorderWidth}} {{rowBorderRadius}} {{rowalignment}} {{rowTextStyles}} {{themeSpacing}}">Voorbeeld data 2B</td>
<td class="{{rowFont}} {{rowBgColor}} {{rowTextColor}} {{rowBorderColor}} {{rowBorderWidth}} {{rowBorderRadius}} {{rowalignment}} {{rowTextStyles}} {{themeSpacing}}">Voorbeeld data 2C</td>
</tr>
<tr>
<td class="{{rowFont}} {{rowBgColor}} {{rowTextColor}} {{rowBorderColor}} {{rowBorderWidth}} {{rowBorderRadius}} {{rowalignment}} {{rowTextStyles}} {{themeSpacing}}">Voorbeeld data 3A</td>
<td class="{{rowFont}} {{rowBgColor}} {{rowTextColor}} {{rowBorderColor}} {{rowBorderWidth}} {{rowBorderRadius}} {{rowalignment}} {{rowTextStyles}} {{themeSpacing}}">Voorbeeld data 3B</td>
<td class="{{rowFont}} {{rowBgColor}} {{rowTextColor}} {{rowBorderColor}} {{rowBorderWidth}} {{rowBorderRadius}} {{rowalignment}} {{rowTextStyles}} {{themeSpacing}}">Voorbeeld data 3C</td>
</tr>
</tbody>
</table>
@else
<!-- Data wordt hier weergegeven -->
@endif
</div>
<script>
async function fetchSheetData() {
const sheetId = "{{sheetIdField}}";
const sheetName = "{{sheetNameField}}";
const range = "{{cellRangeField}}";
const apiKey = "{{apiKeyField}}";
const elementId = "{{uniqueId}}";
const element = document.getElementById(elementId);
const columnsToExclude = "{{columnsToExclude}}".split(',').map(col => parseInt(col.trim(), 10) - 1);
const maxRows = parseInt("{{maxRows}}", 10) || 10;
const columnOrderInput = "{{columnOrder}}".trim();
const columnOrder = columnOrderInput ? columnOrderInput.split(',').map(col => parseInt(col.trim(), 10) - 1) : null;
const headerClasses = [
"{{headerFont}}" || "font-heading",
"{{headerBgColor}}" || "bg-gray-200",
"{{headerTextColor}}" || "text-black",
"{{headerBorderColor}}" || "border-blue-500",
"{{headerBorderWidth}}" || "border-2",
"{{headerBorderRadius}}" || "rounded-md",
"{{headeralignment}}" || "text-center",
"{{headingTextStyles}}" || "text-base",
"{{headerthemeSpacing}}" || "p-4",
].join(' ');
const rowClasses = [
"{{rowFont}}" || "font-body",
"{{rowBgColor}}" || "bg-white",
"{{rowTextColor}}" || "text-black",
"{{rowBorderColor}}" || "border-gray-300",
"{{rowBorderWidth}}" || "border",
"{{rowBorderRadius}}" || "rounded-none",
"{{rowalignment}}" || "text-center",
"{{rowTextStyles}}" || "text-base",
"{{themeSpacing}}" || "p-4",
].join(' ');
const url = `https://sheets.googleapis.com/v4/spreadsheets/${sheetId}/values/${sheetName}!${range}?key=${apiKey}`;
console.log("Fetching data from URL:", url);
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error("Failed to fetch data. Check your API key and sheet permissions.");
}
const data = await response.json();
console.log("Fetched Data:", data);
if (data.values && data.values.length > 0) {
let tableHTML = `<table class="table-auto w-full border-collapse">`;
const headers = data.values[0];
const columnIndices = columnOrder || headers.map((_, index) => index);
tableHTML += `<thead><tr>`;
columnIndices.forEach(index => {
if (!columnsToExclude.includes(index)) {
tableHTML += `<th class="${headerClasses}">${headers[index]}</th>`;
}
});
tableHTML += `</tr></thead>`;
tableHTML += `<tbody>`;
data.values.slice(1, maxRows + 1).forEach(row => {
tableHTML += `<tr>`;
columnIndices.forEach(index => {
if (!columnsToExclude.includes(index)) {
tableHTML += `<td class="${rowClasses}">${row[index] || ''}</td>`;
}
});
tableHTML += `</tr>`;
});
tableHTML += `</tbody></table>`;
element.innerHTML = tableHTML;
} else {
element.textContent = "No data found.";
}
} catch (error) {
console.error("Error fetching data:", error);
element.textContent = "Error fetching data.";
}
}
document.addEventListener("DOMContentLoaded", fetchSheetData);
</script>
Okay, so it depends what you want to happen at each break point, I see you have everything set up quite nicely for setting fonts sizes…
If you just want the text to be smaller on mobile you can already do that with the responsive controls in the inspector.
I only copied and pasted from Claude and/or ChatGPT
. But indeed, simply adjusting the text size (using the dots) is the solution. Sometimes, things in Elements might work so simply that we end up overcomplicating them. ![]()
