mirror of
https://github.com/webstudio-is/webstudio.git
synced 2026-11-03 02:27:57 +09:00
## Description - Provide a key variable next to collection item to access array index or object key - Add .length autocomplete for arrays - Add coercion rules when validating bindings, so you can bind a number to a text attribute or textContent without errors/warnings ## Steps for reproduction 1. click button 2. expect xyz ## Code Review - [ ] hi @kof, I need you to do - conceptual review (architecture, feature-correctness) - detailed review (read every line) - test it on preview ## Before requesting a review - [ ] made a self-review - [ ] added inline comments where things may be not obvious (the "why", not "what") ## Before merging - [ ] tested locally and on preview environment (preview dev login: 0000) - [ ] updated [test cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md) document - [ ] added tests - [ ] if any new env variables are added, added them to `.env` file
53 lines
1.5 KiB
TypeScript
53 lines
1.5 KiB
TypeScript
/**
|
|
* Shared collection iteration logic for both builder and published sites.
|
|
*
|
|
* Collections support both arrays and objects:
|
|
* - Arrays: [item1, item2] -> entries are [["0", item1], ["1", item2]]
|
|
* - Objects: {key1: val1, key2: val2} -> entries are [["key1", val1], ["key2", val2]]
|
|
*
|
|
* Using Object.entries() unifies both cases since arrays are objects with numeric keys.
|
|
*/
|
|
|
|
/**
|
|
* Normalize collection data to entries format [key, value][].
|
|
* Returns empty array if data is not iterable.
|
|
* For arrays, keys are converted to numbers.
|
|
*/
|
|
export const getCollectionEntries = (
|
|
data: unknown
|
|
): Array<[string | number, unknown]> => {
|
|
if (data === null || data === undefined) {
|
|
return [];
|
|
}
|
|
if (typeof data !== "object") {
|
|
return [];
|
|
}
|
|
const entries = Object.entries(data);
|
|
// Convert string indices to numbers for arrays
|
|
if (Array.isArray(data)) {
|
|
return entries.map(([key, value]) => [Number(key), value]);
|
|
}
|
|
return entries;
|
|
};
|
|
|
|
/**
|
|
* Template for generated code that iterates over collections.
|
|
* Used by component-generator.ts to ensure consistency.
|
|
*/
|
|
export const generateCollectionIterationCode = ({
|
|
dataExpression,
|
|
keyVariable,
|
|
itemVariable,
|
|
}: {
|
|
dataExpression: string;
|
|
keyVariable: string;
|
|
itemVariable: string;
|
|
}) => {
|
|
return `Object.entries(
|
|
// @ts-ignore
|
|
${dataExpression} ?? {}
|
|
).map(([_key, ${itemVariable}]: any) => {
|
|
const ${keyVariable} = Array.isArray(${dataExpression}) ? Number(_key) : _key;
|
|
return`;
|
|
};
|