feat: add snippets for all form types and add docs links#34
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
| </a> | ||
| <a | ||
| href="https://coder.com" | ||
| href="https://coder.com/docs/admin/templates/extending-templates/parameters" |
There was a problem hiding this comment.
Nit: for accessibility, whenever you have an external link, you want to add some screen reader text to make sure saying that the link opens in a new tab
It doesn't have to be much. It can be something like:
<span className="sr-only> (link opens in new tab)</span>| const nextInOrder = | ||
| parameters.reduce( | ||
| (highestOrder, parameter) => | ||
| highestOrder < parameter.order ? parameter.order : highestOrder, | ||
| 0, | ||
| ) + 1; |
There was a problem hiding this comment.
Nit: I'm generally not a fan of .reduce in JS, but I think it's fine here, since we're just working with primitive values, and actually have true function purity
Still, I'm wondering if we could do this:
const nextInOrder = 1 + Math.max(0, ...parameters.map((p) => p.order));Feels like the Math.max is more clear about the intent
There was a problem hiding this comment.
I was not aware that Math.max was a variadic function!
| setCode( | ||
| `${code.trimEnd()}\n\n${snippet(nameCount > 0 ? `${name}-${nameCount}` : name, nextInOrder)}\n`, | ||
| ); |
There was a problem hiding this comment.
I feel like this line of code is doing a lot, especially since we have to mindful of all the newlines. Could we refactor it to split up the steps?
const nextInOrder = 1 + Math.max(0, ...parameters.map((p) => p.order));
const newName = nameCount > 0 ? `${name}-${nameCount}` : name;
const newSnippet = snippet(newName, nextInOrder);
setCode(`${code.trimEnd()}\n\n${newSnippet}\n`);| ({ name, label, icon: Icon, snippet }, index) => ( | ||
| <DropdownMenuItem | ||
| key={index} |
There was a problem hiding this comment.
DropdownMenuItem looks stateful, which means that using array indices could eventually scramble up state during JSX reconciliation if we're not careful
If names aren't unique, I feel like it'd be better to find a way to generate a unique ID as a snippet is getting added
There was a problem hiding this comment.
The snippets array doesn't change, it's a set list the user can pick from. Unless you're talking about onAddSnippet depending on state and that causing some weird interaction I'm not aware of I think it's fine.
| </div> | ||
| <a | ||
| href="#todo" | ||
| href="https://coder.com/docs/admin/templates/extending-templates/parameters" |
There was a problem hiding this comment.
Same note here about links that open in new tabs
| type Snippet = { | ||
| name: string; | ||
| label: string; | ||
| icon: typeof RadioIcon; |
There was a problem hiding this comment.
Nit: this can be redefined via the LucideIcon type
There was a problem hiding this comment.
I had tried that but I think I used the Icon type which didn't work. Will give LucideIcon a go
| name = "an-input" | ||
| description = "What is the name of your project?" | ||
| order = 4 | ||
| export type SnippetFunc = (name?: string, order?: number) => string; |
There was a problem hiding this comment.
Is making both parameters optional really the right move? I feel like you'd almost always want to have these be defined, and in that case, making them required reduces the risk of misuse
There was a problem hiding this comment.
Good catch. I think I had some clever idea around this but it never actually came to fruition.
| const copyTimeoutId = useRef<ReturnType<typeof setTimeout> | undefined>( | ||
| undefined, | ||
| ); |
There was a problem hiding this comment.
We don't need this ref here. The timeout ID state can live entirely in the effect
No description provided.