Skip to content

Commit 84132a2

Browse files
adnaanclaude
andauthored
fix(templates): improve standalone kit templates for modal and textarea support (#45)
* fix(templates): improve standalone kit templates for modal and textarea support - Add IsTextarea check to render text fields as <textarea> instead of <input> - Convert server-state modals ({{if .IsAdding}}) to client-side modals using lvt-modal-open/close attributes for proper modal functionality - Add close button (X) to both add and edit modal headers - Fix edit form field accessor to use camelCase instead of title The standalone templates (template.tmpl.tmpl) are used when generating resources in single kit mode. Previously they had several issues: 1. Text fields were rendered as <input type="text"> instead of <textarea> 2. Add modal used non-existent server state (IsAdding) causing modal to never open 3. Modal headers lacked close buttons unlike the component-based templates Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: add comment explaining IsTextarea vs string field rendering Address Claude bot review suggestion to document the IsTextarea check for future maintainers. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent bd536bf commit 84132a2

2 files changed

Lines changed: 44 additions & 26 deletions

File tree

internal/kits/system/multi/templates/resource/template.tmpl.tmpl

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
</div>
5050

5151
<!-- Add Button -->
52-
<button[[if ne (buttonClass .CSSFramework "primary") ""]] class="[[buttonClass .CSSFramework "primary"]]"[[end]] lvt-click="open_add">
52+
<button[[if ne (buttonClass .CSSFramework "primary") ""]] class="[[buttonClass .CSSFramework "primary"]]"[[end]] lvt-modal-open="add-modal">
5353
+ Add [[.ResourceName]]
5454
</button>
5555
</div>
@@ -60,16 +60,18 @@
6060
[[- end]]
6161

6262
<!-- Add Modal -->
63-
{{if .IsAdding}}
64-
<div style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; z-index: 1000;">
63+
<div id="add-modal" hidden aria-hidden="true" role="dialog" data-modal-backdrop data-modal-id="add-modal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; z-index: 1000;">
6564
[[- if needsArticle .CSSFramework]]
6665
<article style="max-width: 600px; width: 90%; max-height: 90vh; overflow-y: auto;">
6766
[[- else if ne (boxClass .CSSFramework) ""]]
6867
<div class="[[boxClass .CSSFramework]]" style="max-width: 600px; width: 90%; max-height: 90vh; overflow-y: auto; background: white;">
6968
[[- else]]
7069
<div style="background: white; border-radius: 8px; padding: 2rem; max-width: 600px; width: 90%; max-height: 90vh; overflow-y: auto;">
7170
[[- end]]
72-
<h2[[if ne (subtitleClass .CSSFramework) ""]] class="[[subtitleClass .CSSFramework]]"[[end]]>Add New [[.ResourceName]]</h2>
71+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
72+
<h2[[if ne (subtitleClass .CSSFramework) ""]] class="[[subtitleClass .CSSFramework]]"[[end]] style="margin: 0;">Add New [[.ResourceName]]</h2>
73+
<button type="button" lvt-modal-close="add-modal" style="background: none; border: none; font-size: 1.5rem; cursor: pointer; padding: 0; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;" aria-label="Close">&times;</button>
74+
</div>
7375

7476
{{if .lvt.HasError "_general"}}
7577
<div style="margin-bottom: 1rem; padding: 0.75rem; background-color: #fee; border: 1px solid #fcc; border-radius: 0.25rem; color: #c00;">
@@ -81,7 +83,10 @@
8183
[[- range .Fields]]
8284
<div[[if ne (fieldClass $.CSSFramework) ""]] class="[[fieldClass $.CSSFramework]]"[[end]]>
8385
<label[[if ne (labelClass $.CSSFramework) ""]] class="[[labelClass $.CSSFramework]]"[[end]]>[[.Name | title]]</label>
84-
[[- if eq .GoType "string"]]
86+
[[/* Use textarea for text/longtext types, input for regular strings */]]
87+
[[- if .IsTextarea]]
88+
<textarea[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] name="[[.Name]]" placeholder="Enter [[.Name]]" rows="5" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}></textarea>
89+
[[- else if eq .GoType "string"]]
8590
<input[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] type="text" name="[[.Name]]" placeholder="Enter [[.Name]]" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
8691
[[- else if eq .GoType "int64"]]
8792
<input[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] type="number" name="[[.Name]]" placeholder="Enter [[.Name]]" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
@@ -100,7 +105,7 @@
100105
[[- end]]
101106
<div[[if ne (fieldClass .CSSFramework) ""]] class="[[fieldClass .CSSFramework]]"[[end]]>
102107
<button[[if ne (buttonClass .CSSFramework "primary") ""]] class="[[buttonClass .CSSFramework "primary"]]"[[end]] type="submit" lvt-disable-with="Adding...">Add [[.ResourceName]]</button>
103-
<button[[if ne (buttonClass .CSSFramework "secondary") ""]] class="[[buttonClass .CSSFramework "secondary"]]"[[end]] type="button" lvt-click="cancel_add">Cancel</button>
108+
<button[[if ne (buttonClass .CSSFramework "secondary") ""]] class="[[buttonClass .CSSFramework "secondary"]]"[[end]] type="button" lvt-modal-close="add-modal">Cancel</button>
104109
</div>
105110
</form>
106111
[[- if needsArticle .CSSFramework]]
@@ -109,7 +114,6 @@
109114
</div>
110115
[[- end]]
111116
</div>
112-
{{end}}
113117

114118
<!-- Edit Modal -->
115119
{{if ne .EditingID 0}}
@@ -121,7 +125,10 @@
121125
[[- else]]
122126
<div style="background: white; border-radius: 8px; padding: 2rem; max-width: 600px; width: 90%; max-height: 90vh; overflow-y: auto;">
123127
[[- end]]
124-
<h2[[if ne (subtitleClass .CSSFramework) ""]] class="[[subtitleClass .CSSFramework]]"[[end]]>Edit [[.ResourceName]]</h2>
128+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
129+
<h2[[if ne (subtitleClass .CSSFramework) ""]] class="[[subtitleClass .CSSFramework]]"[[end]] style="margin: 0;">Edit [[.ResourceName]]</h2>
130+
<button type="button" lvt-click="cancel_edit" style="background: none; border: none; font-size: 1.5rem; cursor: pointer; padding: 0; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;" aria-label="Close">&times;</button>
131+
</div>
125132

126133
{{if .lvt.HasError "_general"}}
127134
<div style="margin-bottom: 1rem; padding: 0.75rem; background-color: #fee; border: 1px solid #fcc; border-radius: 0.25rem; color: #c00;">
@@ -134,17 +141,19 @@
134141
[[- range .Fields]]
135142
<div[[if ne (fieldClass $.CSSFramework) ""]] class="[[fieldClass $.CSSFramework]]"[[end]]>
136143
<label[[if ne (labelClass $.CSSFramework) ""]] class="[[labelClass $.CSSFramework]]"[[end]]>[[.Name | title]]</label>
137-
[[- if eq .GoType "string"]]
138-
<input[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] type="text" name="[[.Name]]" placeholder="Enter [[.Name]]" value="{{.Editing[[$.ResourceName]].[[.Name | title]]}}" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
144+
[[- if .IsTextarea]]
145+
<textarea[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] name="[[.Name]]" placeholder="Enter [[.Name]]" rows="5" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>{{.Editing[[$.ResourceName]].[[.Name | camelCase]]}}</textarea>
146+
[[- else if eq .GoType "string"]]
147+
<input[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] type="text" name="[[.Name]]" placeholder="Enter [[.Name]]" value="{{.Editing[[$.ResourceName]].[[.Name | camelCase]]}}" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
139148
[[- else if eq .GoType "int64"]]
140-
<input[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] type="number" name="[[.Name]]" placeholder="Enter [[.Name]]" value="{{.Editing[[$.ResourceName]].[[.Name | title]]}}" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
149+
<input[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] type="number" name="[[.Name]]" placeholder="Enter [[.Name]]" value="{{.Editing[[$.ResourceName]].[[.Name | camelCase]]}}" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
141150
[[- else if eq .GoType "bool"]]
142151
<label[[if ne (checkboxClass $.CSSFramework) ""]] class="[[checkboxClass $.CSSFramework]]"[[end]]>
143-
<input type="checkbox" name="[[.Name]]" value="true" {{if .Editing[[$.ResourceName]].[[.Name | title]]}}checked{{end}} {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
152+
<input type="checkbox" name="[[.Name]]" value="true" {{if .Editing[[$.ResourceName]].[[.Name | camelCase]]}}checked{{end}} {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
144153
[[.Name | title]]
145154
</label>
146155
[[- else if eq .GoType "float64"]]
147-
<input[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] type="number" step="0.01" name="[[.Name]]" placeholder="Enter [[.Name]]" value="{{.Editing[[$.ResourceName]].[[.Name | title]]}}" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
156+
<input[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] type="number" step="0.01" name="[[.Name]]" placeholder="Enter [[.Name]]" value="{{.Editing[[$.ResourceName]].[[.Name | camelCase]]}}" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
148157
[[- end]]
149158
{{if .lvt.HasError "[[.Name]]"}}
150159
<small style="color: #c00; font-size: 0.875rem;">{{.lvt.Error "[[.Name]]"}}</small>

internal/kits/system/single/templates/resource/template.tmpl.tmpl

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
</div>
5050

5151
<!-- Add Button -->
52-
<button[[if ne (buttonClass .CSSFramework "primary") ""]] class="[[buttonClass .CSSFramework "primary"]]"[[end]] lvt-click="open_add">
52+
<button[[if ne (buttonClass .CSSFramework "primary") ""]] class="[[buttonClass .CSSFramework "primary"]]"[[end]] lvt-modal-open="add-modal">
5353
+ Add [[.ResourceName]]
5454
</button>
5555
</div>
@@ -60,16 +60,18 @@
6060
[[- end]]
6161

6262
<!-- Add Modal -->
63-
{{if .IsAdding}}
64-
<div style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; z-index: 1000;">
63+
<div id="add-modal" hidden aria-hidden="true" role="dialog" data-modal-backdrop data-modal-id="add-modal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; z-index: 1000;">
6564
[[- if needsArticle .CSSFramework]]
6665
<article style="max-width: 600px; width: 90%; max-height: 90vh; overflow-y: auto;">
6766
[[- else if ne (boxClass .CSSFramework) ""]]
6867
<div class="[[boxClass .CSSFramework]]" style="max-width: 600px; width: 90%; max-height: 90vh; overflow-y: auto; background: white;">
6968
[[- else]]
7069
<div style="background: white; border-radius: 8px; padding: 2rem; max-width: 600px; width: 90%; max-height: 90vh; overflow-y: auto;">
7170
[[- end]]
72-
<h2[[if ne (subtitleClass .CSSFramework) ""]] class="[[subtitleClass .CSSFramework]]"[[end]]>Add New [[.ResourceName]]</h2>
71+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
72+
<h2[[if ne (subtitleClass .CSSFramework) ""]] class="[[subtitleClass .CSSFramework]]"[[end]] style="margin: 0;">Add New [[.ResourceName]]</h2>
73+
<button type="button" lvt-modal-close="add-modal" style="background: none; border: none; font-size: 1.5rem; cursor: pointer; padding: 0; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;" aria-label="Close">&times;</button>
74+
</div>
7375

7476
{{if .lvt.HasError "_general"}}
7577
<div style="margin-bottom: 1rem; padding: 0.75rem; background-color: #fee; border: 1px solid #fcc; border-radius: 0.25rem; color: #c00;">
@@ -81,7 +83,10 @@
8183
[[- range .Fields]]
8284
<div[[if ne (fieldClass $.CSSFramework) ""]] class="[[fieldClass $.CSSFramework]]"[[end]]>
8385
<label[[if ne (labelClass $.CSSFramework) ""]] class="[[labelClass $.CSSFramework]]"[[end]]>[[.Name | title]]</label>
84-
[[- if eq .GoType "string"]]
86+
[[/* Use textarea for text/longtext types, input for regular strings */]]
87+
[[- if .IsTextarea]]
88+
<textarea[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] name="[[.Name]]" placeholder="Enter [[.Name]]" rows="5" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}></textarea>
89+
[[- else if eq .GoType "string"]]
8590
<input[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] type="text" name="[[.Name]]" placeholder="Enter [[.Name]]" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
8691
[[- else if eq .GoType "int64"]]
8792
<input[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] type="number" name="[[.Name]]" placeholder="Enter [[.Name]]" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
@@ -100,7 +105,7 @@
100105
[[- end]]
101106
<div[[if ne (fieldClass .CSSFramework) ""]] class="[[fieldClass .CSSFramework]]"[[end]]>
102107
<button[[if ne (buttonClass .CSSFramework "primary") ""]] class="[[buttonClass .CSSFramework "primary"]]"[[end]] type="submit" lvt-disable-with="Adding...">Add [[.ResourceName]]</button>
103-
<button[[if ne (buttonClass .CSSFramework "secondary") ""]] class="[[buttonClass .CSSFramework "secondary"]]"[[end]] type="button" lvt-click="cancel_add">Cancel</button>
108+
<button[[if ne (buttonClass .CSSFramework "secondary") ""]] class="[[buttonClass .CSSFramework "secondary"]]"[[end]] type="button" lvt-modal-close="add-modal">Cancel</button>
104109
</div>
105110
</form>
106111
[[- if needsArticle .CSSFramework]]
@@ -109,7 +114,6 @@
109114
</div>
110115
[[- end]]
111116
</div>
112-
{{end}}
113117

114118
<!-- Edit Modal -->
115119
{{if ne .EditingID ""}}
@@ -121,7 +125,10 @@
121125
[[- else]]
122126
<div style="background: white; border-radius: 8px; padding: 2rem; max-width: 600px; width: 90%; max-height: 90vh; overflow-y: auto;">
123127
[[- end]]
124-
<h2[[if ne (subtitleClass .CSSFramework) ""]] class="[[subtitleClass .CSSFramework]]"[[end]]>Edit [[.ResourceName]]</h2>
128+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem;">
129+
<h2[[if ne (subtitleClass .CSSFramework) ""]] class="[[subtitleClass .CSSFramework]]"[[end]] style="margin: 0;">Edit [[.ResourceName]]</h2>
130+
<button type="button" lvt-click="cancel_edit" style="background: none; border: none; font-size: 1.5rem; cursor: pointer; padding: 0; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;" aria-label="Close">&times;</button>
131+
</div>
125132

126133
{{if .lvt.HasError "_general"}}
127134
<div style="margin-bottom: 1rem; padding: 0.75rem; background-color: #fee; border: 1px solid #fcc; border-radius: 0.25rem; color: #c00;">
@@ -134,17 +141,19 @@
134141
[[- range .Fields]]
135142
<div[[if ne (fieldClass $.CSSFramework) ""]] class="[[fieldClass $.CSSFramework]]"[[end]]>
136143
<label[[if ne (labelClass $.CSSFramework) ""]] class="[[labelClass $.CSSFramework]]"[[end]]>[[.Name | title]]</label>
137-
[[- if eq .GoType "string"]]
138-
<input[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] type="text" name="[[.Name]]" placeholder="Enter [[.Name]]" value="{{.Editing[[$.ResourceName]].[[.Name | title]]}}" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
144+
[[- if .IsTextarea]]
145+
<textarea[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] name="[[.Name]]" placeholder="Enter [[.Name]]" rows="5" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>{{.Editing[[$.ResourceName]].[[.Name | camelCase]]}}</textarea>
146+
[[- else if eq .GoType "string"]]
147+
<input[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] type="text" name="[[.Name]]" placeholder="Enter [[.Name]]" value="{{.Editing[[$.ResourceName]].[[.Name | camelCase]]}}" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
139148
[[- else if eq .GoType "int64"]]
140-
<input[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] type="number" name="[[.Name]]" placeholder="Enter [[.Name]]" value="{{.Editing[[$.ResourceName]].[[.Name | title]]}}" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
149+
<input[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] type="number" name="[[.Name]]" placeholder="Enter [[.Name]]" value="{{.Editing[[$.ResourceName]].[[.Name | camelCase]]}}" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
141150
[[- else if eq .GoType "bool"]]
142151
<label[[if ne (checkboxClass $.CSSFramework) ""]] class="[[checkboxClass $.CSSFramework]]"[[end]]>
143-
<input type="checkbox" name="[[.Name]]" value="true" {{if .Editing[[$.ResourceName]].[[.Name | title]]}}checked{{end}} {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
152+
<input type="checkbox" name="[[.Name]]" value="true" {{if .Editing[[$.ResourceName]].[[.Name | camelCase]]}}checked{{end}} {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
144153
[[.Name | title]]
145154
</label>
146155
[[- else if eq .GoType "float64"]]
147-
<input[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] type="number" step="0.01" name="[[.Name]]" placeholder="Enter [[.Name]]" value="{{.Editing[[$.ResourceName]].[[.Name | title]]}}" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
156+
<input[[if ne (inputClass $.CSSFramework) ""]] class="[[inputClass $.CSSFramework]]"[[end]] type="number" step="0.01" name="[[.Name]]" placeholder="Enter [[.Name]]" value="{{.Editing[[$.ResourceName]].[[.Name | camelCase]]}}" required {{if .lvt.HasError "[[.Name]]"}}aria-invalid="true"{{end}}>
148157
[[- end]]
149158
{{if .lvt.HasError "[[.Name]]"}}
150159
<small style="color: #c00; font-size: 0.875rem;">{{.lvt.Error "[[.Name]]"}}</small>

0 commit comments

Comments
 (0)