elismasilva commited on
Commit
8c7758f
·
verified ·
1 Parent(s): ab07754

Upload folder using huggingface_hub

Browse files
.gitignore CHANGED
@@ -9,4 +9,5 @@ __tmp/*
9
  .mypycache
10
  .ruff_cache
11
  node_modules
12
- backend/**/templates/
 
 
9
  .mypycache
10
  .ruff_cache
11
  node_modules
12
+ backend/**/templates/
13
+ README_TEMPLATE.md
README.md CHANGED
@@ -10,7 +10,7 @@ app_file: space.py
10
  ---
11
 
12
  # `gradio_taggrouphelper`
13
- <a href="https://pypi.org/project/gradio_taggrouphelper/" target="_blank"><img alt="PyPI - Version" src="https://img.shields.io/pypi/v/gradio_taggrouphelper"></a>
14
 
15
  A fast text generator based on tagged words
16
 
@@ -49,10 +49,65 @@ TAG_DATA = {
49
  ]
50
  }
51
 
52
- with gr.Blocks() as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  gr.Markdown("# Tag Group Helper Demo")
54
  gr.Markdown("Click on the tags below to add them to the prompt textboxes.")
55
-
56
  with gr.Row():
57
  with gr.Column(scale=2): # Give more space to the textboxes
58
  # Create the target Textbox and give it a unique `elem_id`.
@@ -68,14 +123,17 @@ with gr.Blocks() as demo:
68
  lines=5,
69
  elem_id="negative-prompt-textbox" # This ID must be unique
70
  )
71
-
72
- with gr.Column(scale=1): # Give less space to the helpers
73
  # Create an instance of the TagGroupHelper for the Positive Prompt box.
74
  TagGroupHelper(
75
  label="Positive Prompt Keywords",
76
  value={k: v for k, v in TAG_DATA.items() if "Negative" not in k},
77
  target_textbox_id="positive-prompt-textbox",
78
- separator=" "
 
 
 
 
79
  )
80
 
81
  # Create another instance for the Negative Prompt box.
@@ -83,8 +141,10 @@ with gr.Blocks() as demo:
83
  label="Negative Prompt Keywords",
84
  value={"Negative Prompts": TAG_DATA["Negative Prompts"]},
85
  target_textbox_id="negative-prompt-textbox",
86
- min_width=150,
87
- separator=", "
 
 
88
  )
89
 
90
  if __name__ == '__main__':
@@ -124,29 +184,29 @@ typing.Optional[typing.Dict[str, typing.List[str]]][
124
  </tr>
125
 
126
  <tr>
127
- <td align="left"><code>target_textbox_id</code></td>
128
  <td align="left" style="width: 25%;">
129
 
130
  ```python
131
- str | None
132
  ```
133
 
134
  </td>
135
  <td align="left"><code>None</code></td>
136
- <td align="left">The `elem_id` of the `gr.Textbox` component to target. Required.</td>
137
  </tr>
138
 
139
  <tr>
140
- <td align="left"><code>separator</code></td>
141
  <td align="left" style="width: 25%;">
142
 
143
  ```python
144
- str
145
  ```
146
 
147
  </td>
148
- <td align="left"><code>", "</code></td>
149
- <td align="left">The string to use as a separator between tags. Defaults to ", ". Can be set to " " for space separation.</td>
150
  </tr>
151
 
152
  <tr>
@@ -163,29 +223,55 @@ str | None
163
  </tr>
164
 
165
  <tr>
166
- <td align="left"><code>visible</code></td>
167
  <td align="left" style="width: 25%;">
168
 
169
  ```python
170
- bool
171
  ```
172
 
173
  </td>
174
- <td align="left"><code>True</code></td>
175
- <td align="left">If False, the component will be hidden.</td>
176
  </tr>
177
 
178
  <tr>
179
- <td align="left"><code>elem_id</code></td>
180
  <td align="left" style="width: 25%;">
181
 
182
  ```python
183
- str | None
184
  ```
185
 
186
  </td>
187
  <td align="left"><code>None</code></td>
188
- <td align="left">An optional string that is assigned as the id of this component in the HTML DOM.</td>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  </tr>
190
 
191
  <tr>
@@ -206,16 +292,55 @@ int | None
206
  <td align="left" style="width: 25%;">
207
 
208
  ```python
209
- int | None
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  ```
211
 
212
  </td>
213
  <td align="left"><code>None</code></td>
214
- <td align="left">The minimum-width of the component in pixels.</td>
215
  </tr>
216
 
217
  <tr>
218
- <td align="left"><code>container</code></td>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  <td align="left" style="width: 25%;">
220
 
221
  ```python
@@ -224,7 +349,20 @@ bool
224
 
225
  </td>
226
  <td align="left"><code>True</code></td>
227
- <td align="left">If False, the component will not be wrapped in a container.</td>
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  </tr>
229
 
230
  <tr>
 
10
  ---
11
 
12
  # `gradio_taggrouphelper`
13
+ <img alt="Static Badge" src="https://img.shields.io/badge/version%20-%200.0.3%20-%20blue"> <a href="https://huggingface.co/spaces/elismasilva/gradio_taggrouphelper"><img src="https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Demo-blue"></a> <p><span>💻 <a href='https://github.com/DEVAIEXP/gradio_component_taggrouphelper'>Component GitHub Code</a></span></p>
14
 
15
  A fast text generator based on tagged words
16
 
 
49
  ]
50
  }
51
 
52
+ css="""
53
+ body {
54
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
55
+ margin: 0;
56
+ padding: 0;
57
+ }
58
+ .gradio-container {
59
+ border-radius: 15px;
60
+ padding: 30px 40px;
61
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
62
+ margin: 40px 340px;
63
+ }
64
+ .gradio-container h1 {
65
+ text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
66
+ }
67
+ .fillable {
68
+ width: 100% !important;
69
+ max-width: unset !important;
70
+ }
71
+ #examples_container {
72
+ margin: auto;
73
+ width: 90%;
74
+ }
75
+ #examples_row {
76
+ justify-content: center;
77
+ }
78
+ #tips_row{
79
+ padding-left: 20px;
80
+ }
81
+ .sidebar {
82
+ border-radius: 10px;
83
+ padding: 10px;
84
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
85
+ }
86
+ .sidebar .toggle-button {
87
+ background: linear-gradient(90deg, #34d399, #10b981) !important;
88
+ border: none;
89
+ padding: 12px 18px;
90
+ text-transform: uppercase;
91
+ font-weight: bold;
92
+ letter-spacing: 1px;
93
+ border-radius: 5px;
94
+ cursor: pointer;
95
+ transition: transform 0.2s ease-in-out;
96
+ }
97
+ .toggle-button:hover {
98
+ transform: scale(1.05);
99
+ }
100
+ .sidebar .sidebar-content {
101
+ padding-left: 10px !important;
102
+ }
103
+ .sidebar .sidebar-content .column .block div .prose {
104
+ text-align: center;
105
+ }
106
+ """
107
+ with gr.Blocks(theme=gr.themes.Ocean(), css=css) as demo:
108
  gr.Markdown("# Tag Group Helper Demo")
109
  gr.Markdown("Click on the tags below to add them to the prompt textboxes.")
110
+ gr.Markdown("<span>💻 <a href='https://github.com/DEVAIEXP/gradio_component_taggrouphelper'>GitHub Code</a></span>")
111
  with gr.Row():
112
  with gr.Column(scale=2): # Give more space to the textboxes
113
  # Create the target Textbox and give it a unique `elem_id`.
 
123
  lines=5,
124
  elem_id="negative-prompt-textbox" # This ID must be unique
125
  )
126
+ with gr.Sidebar(position="right"):
 
127
  # Create an instance of the TagGroupHelper for the Positive Prompt box.
128
  TagGroupHelper(
129
  label="Positive Prompt Keywords",
130
  value={k: v for k, v in TAG_DATA.items() if "Negative" not in k},
131
  target_textbox_id="positive-prompt-textbox",
132
+ separator=", ",
133
+ interactive=True,
134
+ width=250,
135
+ font_size_scale=90
136
+
137
  )
138
 
139
  # Create another instance for the Negative Prompt box.
 
141
  label="Negative Prompt Keywords",
142
  value={"Negative Prompts": TAG_DATA["Negative Prompts"]},
143
  target_textbox_id="negative-prompt-textbox",
144
+ separator=", ",
145
+ interactive=True,
146
+ width=250,
147
+ font_size_scale=90
148
  )
149
 
150
  if __name__ == '__main__':
 
184
  </tr>
185
 
186
  <tr>
187
+ <td align="left"><code>height</code></td>
188
  <td align="left" style="width: 25%;">
189
 
190
  ```python
191
+ int | None
192
  ```
193
 
194
  </td>
195
  <td align="left"><code>None</code></td>
196
+ <td align="left">The height of the component container in pixels.</td>
197
  </tr>
198
 
199
  <tr>
200
+ <td align="left"><code>width</code></td>
201
  <td align="left" style="width: 25%;">
202
 
203
  ```python
204
+ int | None
205
  ```
206
 
207
  </td>
208
+ <td align="left"><code>None</code></td>
209
+ <td align="left">The width of the component container in pixels.</td>
210
  </tr>
211
 
212
  <tr>
 
223
  </tr>
224
 
225
  <tr>
226
+ <td align="left"><code>font_size_scale</code></td>
227
  <td align="left" style="width: 25%;">
228
 
229
  ```python
230
+ int
231
  ```
232
 
233
  </td>
234
+ <td align="left"><code>100</code></td>
235
+ <td align="left">A percentage to scale the font size of group headers and tags. Defaults to 100.</td>
236
  </tr>
237
 
238
  <tr>
239
+ <td align="left"><code>every</code></td>
240
  <td align="left" style="width: 25%;">
241
 
242
  ```python
243
+ float | None
244
  ```
245
 
246
  </td>
247
  <td align="left"><code>None</code></td>
248
+ <td align="left">If `value` is a callable, run the function 'every' seconds while the client connection is open.</td>
249
+ </tr>
250
+
251
+ <tr>
252
+ <td align="left"><code>show_label</code></td>
253
+ <td align="left" style="width: 25%;">
254
+
255
+ ```python
256
+ bool | None
257
+ ```
258
+
259
+ </td>
260
+ <td align="left"><code>None</code></td>
261
+ <td align="left">If False, the label is not displayed.</td>
262
+ </tr>
263
+
264
+ <tr>
265
+ <td align="left"><code>container</code></td>
266
+ <td align="left" style="width: 25%;">
267
+
268
+ ```python
269
+ bool
270
+ ```
271
+
272
+ </td>
273
+ <td align="left"><code>True</code></td>
274
+ <td align="left">If False, the component will not be wrapped in a container.</td>
275
  </tr>
276
 
277
  <tr>
 
292
  <td align="left" style="width: 25%;">
293
 
294
  ```python
295
+ int
296
+ ```
297
+
298
+ </td>
299
+ <td align="left"><code>160</code></td>
300
+ <td align="left">The minimum width of the component in pixels.</td>
301
+ </tr>
302
+
303
+ <tr>
304
+ <td align="left"><code>interactive</code></td>
305
+ <td align="left" style="width: 25%;">
306
+
307
+ ```python
308
+ bool | None
309
  ```
310
 
311
  </td>
312
  <td align="left"><code>None</code></td>
313
+ <td align="left">if True, will be rendered as an selectable component; if False, editing will be disabled. If not provided, this is inferred based on whether the component is used as an input or output.</td>
314
  </tr>
315
 
316
  <tr>
317
+ <td align="left"><code>target_textbox_id</code></td>
318
+ <td align="left" style="width: 25%;">
319
+
320
+ ```python
321
+ str | None
322
+ ```
323
+
324
+ </td>
325
+ <td align="left"><code>None</code></td>
326
+ <td align="left">The `elem_id` of the `gr.Textbox` component to target. Required.</td>
327
+ </tr>
328
+
329
+ <tr>
330
+ <td align="left"><code>separator</code></td>
331
+ <td align="left" style="width: 25%;">
332
+
333
+ ```python
334
+ str
335
+ ```
336
+
337
+ </td>
338
+ <td align="left"><code>", "</code></td>
339
+ <td align="left">The string to use as a separator between tags. Defaults to ", ". Can be set to " " for space separation.</td>
340
+ </tr>
341
+
342
+ <tr>
343
+ <td align="left"><code>visible</code></td>
344
  <td align="left" style="width: 25%;">
345
 
346
  ```python
 
349
 
350
  </td>
351
  <td align="left"><code>True</code></td>
352
+ <td align="left">If False, the component will be hidden.</td>
353
+ </tr>
354
+
355
+ <tr>
356
+ <td align="left"><code>elem_id</code></td>
357
+ <td align="left" style="width: 25%;">
358
+
359
+ ```python
360
+ str | None
361
+ ```
362
+
363
+ </td>
364
+ <td align="left"><code>None</code></td>
365
+ <td align="left">An optional string that is assigned as the id of this component in the HTML DOM.</td>
366
  </tr>
367
 
368
  <tr>
app.py CHANGED
@@ -1,67 +1,126 @@
1
- #
2
- # demo/app.py
3
- #
4
- import gradio as gr
5
- from gradio_taggrouphelper import TagGroupHelper
6
-
7
- # Example data structure for the tags and groups
8
- TAG_DATA = {
9
- "Quality": [
10
- "best quality", "masterpiece", "high resolution", "4k", "8k",
11
- "sharp focus", "detailed", "photorealistic"
12
- ],
13
- "Lighting": [
14
- "cinematic lighting", "volumetric lighting", "god rays",
15
- "golden hour", "studio lighting", "dramatic lighting"
16
- ],
17
- "Style": [
18
- "anime style", "oil painting", "concept art", "fantasy",
19
- "steampunk", "vaporwave", "line art"
20
- ],
21
- "Negative Prompts": [
22
- "blurry", "noisy", "low resolution", "low quality", "watermark",
23
- "text", "bad anatomy", "extra limbs", "disfigured"
24
- ]
25
- }
26
-
27
- with gr.Blocks() as demo:
28
- gr.Markdown("# Tag Group Helper Demo")
29
- gr.Markdown("Click on the tags below to add them to the prompt textboxes.")
30
- gr.Markdown("<span>💻 <a href='https://github.com/DEVAIEXP/gradio_component_taggrouphelper'>GitHub Code</a></span>")
31
-
32
- with gr.Row():
33
- with gr.Column(scale=2): # Give more space to the textboxes
34
- # Create the target Textbox and give it a unique `elem_id`.
35
- positive_prompt_box = gr.Textbox(
36
- label="Positive Prompt",
37
- placeholder="Click tags from 'Prompt Keywords' to add them here...",
38
- lines=5,
39
- elem_id="positive-prompt-textbox" # This ID must be unique
40
- )
41
- negative_prompt_box = gr.Textbox(
42
- label="Negative Prompt",
43
- placeholder="Click tags from 'Negative Keywords' to add them here...",
44
- lines=5,
45
- elem_id="negative-prompt-textbox" # This ID must be unique
46
- )
47
-
48
- with gr.Column(scale=1): # Give less space to the helpers
49
- # Create an instance of the TagGroupHelper for the Positive Prompt box.
50
- TagGroupHelper(
51
- label="Positive Prompt Keywords",
52
- value={k: v for k, v in TAG_DATA.items() if "Negative" not in k},
53
- target_textbox_id="positive-prompt-textbox",
54
- separator=", "
55
- )
56
-
57
- # Create another instance for the Negative Prompt box.
58
- TagGroupHelper(
59
- label="Negative Prompt Keywords",
60
- value={"Negative Prompts": TAG_DATA["Negative Prompts"]},
61
- target_textbox_id="negative-prompt-textbox",
62
- min_width=150,
63
- separator=", "
64
- )
65
-
66
- if __name__ == '__main__':
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  demo.launch()
 
1
+ #
2
+ # demo/app.py
3
+ #
4
+ import gradio as gr
5
+ from gradio_taggrouphelper import TagGroupHelper
6
+
7
+ # Example data structure for the tags and groups
8
+ TAG_DATA = {
9
+ "Quality": [
10
+ "best quality", "masterpiece", "high resolution", "4k", "8k",
11
+ "sharp focus", "detailed", "photorealistic"
12
+ ],
13
+ "Lighting": [
14
+ "cinematic lighting", "volumetric lighting", "god rays",
15
+ "golden hour", "studio lighting", "dramatic lighting"
16
+ ],
17
+ "Style": [
18
+ "anime style", "oil painting", "concept art", "fantasy",
19
+ "steampunk", "vaporwave", "line art"
20
+ ],
21
+ "Negative Prompts": [
22
+ "blurry", "noisy", "low resolution", "low quality", "watermark",
23
+ "text", "bad anatomy", "extra limbs", "disfigured"
24
+ ]
25
+ }
26
+
27
+ css="""
28
+ body {
29
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
30
+ margin: 0;
31
+ padding: 0;
32
+ }
33
+ .gradio-container {
34
+ border-radius: 15px;
35
+ padding: 30px 40px;
36
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
37
+ margin: 40px 340px;
38
+ }
39
+ .gradio-container h1 {
40
+ text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
41
+ }
42
+ .fillable {
43
+ width: 100% !important;
44
+ max-width: unset !important;
45
+ }
46
+ #examples_container {
47
+ margin: auto;
48
+ width: 90%;
49
+ }
50
+ #examples_row {
51
+ justify-content: center;
52
+ }
53
+ #tips_row{
54
+ padding-left: 20px;
55
+ }
56
+ .sidebar {
57
+ border-radius: 10px;
58
+ padding: 10px;
59
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
60
+ }
61
+ .sidebar .toggle-button {
62
+ background: linear-gradient(90deg, #34d399, #10b981) !important;
63
+ border: none;
64
+ padding: 12px 18px;
65
+ text-transform: uppercase;
66
+ font-weight: bold;
67
+ letter-spacing: 1px;
68
+ border-radius: 5px;
69
+ cursor: pointer;
70
+ transition: transform 0.2s ease-in-out;
71
+ }
72
+ .toggle-button:hover {
73
+ transform: scale(1.05);
74
+ }
75
+ .sidebar .sidebar-content {
76
+ padding-left: 10px !important;
77
+ }
78
+ .sidebar .sidebar-content .column .block div .prose {
79
+ text-align: center;
80
+ }
81
+ """
82
+ with gr.Blocks(theme=gr.themes.Ocean(), css=css) as demo:
83
+ gr.Markdown("# Tag Group Helper Demo")
84
+ gr.Markdown("Click on the tags below to add them to the prompt textboxes.")
85
+ gr.Markdown("<span>💻 <a href='https://github.com/DEVAIEXP/gradio_component_taggrouphelper'>GitHub Code</a></span>")
86
+ with gr.Row():
87
+ with gr.Column(scale=2): # Give more space to the textboxes
88
+ # Create the target Textbox and give it a unique `elem_id`.
89
+ positive_prompt_box = gr.Textbox(
90
+ label="Positive Prompt",
91
+ placeholder="Click tags from 'Prompt Keywords' to add them here...",
92
+ lines=5,
93
+ elem_id="positive-prompt-textbox" # This ID must be unique
94
+ )
95
+ negative_prompt_box = gr.Textbox(
96
+ label="Negative Prompt",
97
+ placeholder="Click tags from 'Negative Keywords' to add them here...",
98
+ lines=5,
99
+ elem_id="negative-prompt-textbox" # This ID must be unique
100
+ )
101
+ with gr.Sidebar(position="right"):
102
+ # Create an instance of the TagGroupHelper for the Positive Prompt box.
103
+ TagGroupHelper(
104
+ label="Positive Prompt Keywords",
105
+ value={k: v for k, v in TAG_DATA.items() if "Negative" not in k},
106
+ target_textbox_id="positive-prompt-textbox",
107
+ separator=", ",
108
+ interactive=True,
109
+ width=250,
110
+ font_size_scale=90
111
+
112
+ )
113
+
114
+ # Create another instance for the Negative Prompt box.
115
+ TagGroupHelper(
116
+ label="Negative Prompt Keywords",
117
+ value={"Negative Prompts": TAG_DATA["Negative Prompts"]},
118
+ target_textbox_id="negative-prompt-textbox",
119
+ separator=", ",
120
+ interactive=True,
121
+ width=250,
122
+ font_size_scale=90
123
+ )
124
+
125
+ if __name__ == '__main__':
126
  demo.launch()
space.py CHANGED
@@ -3,7 +3,7 @@ import gradio as gr
3
  from app import demo as app
4
  import os
5
 
6
- _docs = {'TagGroupHelper': {'description': "A custom component that displays groups of clickable tags to help build prompts.\nWhen a tag is clicked, it's appended to a target Textbox component.\nThis component does not have a submittable value itself.", 'members': {'__init__': {'value': {'type': 'typing.Optional[typing.Dict[str, typing.List[str]]][\n typing.Dict[str, typing.List[str]][\n str, typing.List[str][str]\n ],\n None,\n]', 'default': 'None', 'description': 'A dictionary where keys are group names and values are lists of tags.'}, 'target_textbox_id': {'type': 'str | None', 'default': 'None', 'description': 'The `elem_id` of the `gr.Textbox` component to target. Required.'}, 'separator': {'type': 'str', 'default': '", "', 'description': 'The string to use as a separator between tags. Defaults to ", ". Can be set to " " for space separation.'}, 'label': {'type': 'str | None', 'default': 'None', 'description': 'The label for this component, displayed above the groups.'}, 'visible': {'type': 'bool', 'default': 'True', 'description': 'If False, the component will be hidden.'}, 'elem_id': {'type': 'str | None', 'default': 'None', 'description': 'An optional string that is assigned as the id of this component in the HTML DOM.'}, 'scale': {'type': 'int | None', 'default': 'None', 'description': 'The relative size of the component compared to others in a `gr.Row` or `gr.Column`.'}, 'min_width': {'type': 'int | None', 'default': 'None', 'description': 'The minimum-width of the component in pixels.'}, 'container': {'type': 'bool', 'default': 'True', 'description': 'If False, the component will not be wrapped in a container.'}, 'elem_classes': {'type': 'list[str] | str | None', 'default': 'None', 'description': 'An optional list of strings to assign as CSS classes to the component.'}}, 'postprocess': {'value': {'type': 'typing.Optional[typing.Dict[str, typing.List[str]]][\n typing.Dict[str, typing.List[str]][\n str, typing.List[str][str]\n ],\n None,\n]', 'description': None}}, 'preprocess': {'return': {'type': 'Any', 'description': None}, 'value': None}}, 'events': {}}, '__meta__': {'additional_interfaces': {}, 'user_fn_refs': {'TagGroupHelper': []}}}
7
 
8
  abs_path = os.path.join(os.path.dirname(__file__), "css.css")
9
 
@@ -64,10 +64,65 @@ TAG_DATA = {
64
  ]
65
  }
66
 
67
- with gr.Blocks() as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  gr.Markdown("# Tag Group Helper Demo")
69
  gr.Markdown("Click on the tags below to add them to the prompt textboxes.")
70
-
71
  with gr.Row():
72
  with gr.Column(scale=2): # Give more space to the textboxes
73
  # Create the target Textbox and give it a unique `elem_id`.
@@ -83,14 +138,17 @@ with gr.Blocks() as demo:
83
  lines=5,
84
  elem_id="negative-prompt-textbox" # This ID must be unique
85
  )
86
-
87
- with gr.Column(scale=1): # Give less space to the helpers
88
  # Create an instance of the TagGroupHelper for the Positive Prompt box.
89
  TagGroupHelper(
90
  label="Positive Prompt Keywords",
91
  value={k: v for k, v in TAG_DATA.items() if "Negative" not in k},
92
  target_textbox_id="positive-prompt-textbox",
93
- separator=" "
 
 
 
 
94
  )
95
 
96
  # Create another instance for the Negative Prompt box.
@@ -98,8 +156,10 @@ with gr.Blocks() as demo:
98
  label="Negative Prompt Keywords",
99
  value={"Negative Prompts": TAG_DATA["Negative Prompts"]},
100
  target_textbox_id="negative-prompt-textbox",
101
- min_width=150,
102
- separator=", "
 
 
103
  )
104
 
105
  if __name__ == '__main__':
 
3
  from app import demo as app
4
  import os
5
 
6
+ _docs = {'TagGroupHelper': {'description': "A custom component that displays groups of clickable tags to help build prompts.\nWhen a tag is clicked, it's appended to a target Textbox component.\nThis component does not have a submittable value itself.", 'members': {'__init__': {'value': {'type': 'typing.Optional[typing.Dict[str, typing.List[str]]][\n typing.Dict[str, typing.List[str]][\n str, typing.List[str][str]\n ],\n None,\n]', 'default': 'None', 'description': 'A dictionary where keys are group names and values are lists of tags.'}, 'height': {'type': 'int | None', 'default': 'None', 'description': 'The height of the component container in pixels.'}, 'width': {'type': 'int | None', 'default': 'None', 'description': 'The width of the component container in pixels.'}, 'label': {'type': 'str | None', 'default': 'None', 'description': 'The label for this component, displayed above the groups.'}, 'font_size_scale': {'type': 'int', 'default': '100', 'description': 'A percentage to scale the font size of group headers and tags. Defaults to 100.'}, 'every': {'type': 'float | None', 'default': 'None', 'description': "If `value` is a callable, run the function 'every' seconds while the client connection is open."}, 'show_label': {'type': 'bool | None', 'default': 'None', 'description': 'If False, the label is not displayed.'}, 'container': {'type': 'bool', 'default': 'True', 'description': 'If False, the component will not be wrapped in a container.'}, 'scale': {'type': 'int | None', 'default': 'None', 'description': 'The relative size of the component compared to others in a `gr.Row` or `gr.Column`.'}, 'min_width': {'type': 'int', 'default': '160', 'description': 'The minimum width of the component in pixels.'}, 'interactive': {'type': 'bool | None', 'default': 'None', 'description': 'if True, will be rendered as an selectable component; if False, editing will be disabled. If not provided, this is inferred based on whether the component is used as an input or output.'}, 'target_textbox_id': {'type': 'str | None', 'default': 'None', 'description': 'The `elem_id` of the `gr.Textbox` component to target. Required.'}, 'separator': {'type': 'str', 'default': '", "', 'description': 'The string to use as a separator between tags. Defaults to ", ". Can be set to " " for space separation.'}, 'visible': {'type': 'bool', 'default': 'True', 'description': 'If False, the component will be hidden.'}, 'elem_id': {'type': 'str | None', 'default': 'None', 'description': 'An optional string that is assigned as the id of this component in the HTML DOM.'}, 'elem_classes': {'type': 'list[str] | str | None', 'default': 'None', 'description': 'An optional list of strings to assign as CSS classes to the component.'}}, 'postprocess': {'value': {'type': 'typing.Optional[typing.Dict[str, typing.List[str]]][\n typing.Dict[str, typing.List[str]][\n str, typing.List[str][str]\n ],\n None,\n]', 'description': None}}, 'preprocess': {'return': {'type': 'Any', 'description': None}, 'value': None}}, 'events': {}}, '__meta__': {'additional_interfaces': {}, 'user_fn_refs': {'TagGroupHelper': []}}}
7
 
8
  abs_path = os.path.join(os.path.dirname(__file__), "css.css")
9
 
 
64
  ]
65
  }
66
 
67
+ css=\"\"\"
68
+ body {
69
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
70
+ margin: 0;
71
+ padding: 0;
72
+ }
73
+ .gradio-container {
74
+ border-radius: 15px;
75
+ padding: 30px 40px;
76
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
77
+ margin: 40px 340px;
78
+ }
79
+ .gradio-container h1 {
80
+ text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
81
+ }
82
+ .fillable {
83
+ width: 100% !important;
84
+ max-width: unset !important;
85
+ }
86
+ #examples_container {
87
+ margin: auto;
88
+ width: 90%;
89
+ }
90
+ #examples_row {
91
+ justify-content: center;
92
+ }
93
+ #tips_row{
94
+ padding-left: 20px;
95
+ }
96
+ .sidebar {
97
+ border-radius: 10px;
98
+ padding: 10px;
99
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
100
+ }
101
+ .sidebar .toggle-button {
102
+ background: linear-gradient(90deg, #34d399, #10b981) !important;
103
+ border: none;
104
+ padding: 12px 18px;
105
+ text-transform: uppercase;
106
+ font-weight: bold;
107
+ letter-spacing: 1px;
108
+ border-radius: 5px;
109
+ cursor: pointer;
110
+ transition: transform 0.2s ease-in-out;
111
+ }
112
+ .toggle-button:hover {
113
+ transform: scale(1.05);
114
+ }
115
+ .sidebar .sidebar-content {
116
+ padding-left: 10px !important;
117
+ }
118
+ .sidebar .sidebar-content .column .block div .prose {
119
+ text-align: center;
120
+ }
121
+ \"\"\"
122
+ with gr.Blocks(theme=gr.themes.Ocean(), css=css) as demo:
123
  gr.Markdown("# Tag Group Helper Demo")
124
  gr.Markdown("Click on the tags below to add them to the prompt textboxes.")
125
+ gr.Markdown("<span>💻 <a href='https://github.com/DEVAIEXP/gradio_component_taggrouphelper'>GitHub Code</a></span>")
126
  with gr.Row():
127
  with gr.Column(scale=2): # Give more space to the textboxes
128
  # Create the target Textbox and give it a unique `elem_id`.
 
138
  lines=5,
139
  elem_id="negative-prompt-textbox" # This ID must be unique
140
  )
141
+ with gr.Sidebar(position="right"):
 
142
  # Create an instance of the TagGroupHelper for the Positive Prompt box.
143
  TagGroupHelper(
144
  label="Positive Prompt Keywords",
145
  value={k: v for k, v in TAG_DATA.items() if "Negative" not in k},
146
  target_textbox_id="positive-prompt-textbox",
147
+ separator=", ",
148
+ interactive=True,
149
+ width=250,
150
+ font_size_scale=90
151
+
152
  )
153
 
154
  # Create another instance for the Negative Prompt box.
 
156
  label="Negative Prompt Keywords",
157
  value={"Negative Prompts": TAG_DATA["Negative Prompts"]},
158
  target_textbox_id="negative-prompt-textbox",
159
+ separator=", ",
160
+ interactive=True,
161
+ width=250,
162
+ font_size_scale=90
163
  )
164
 
165
  if __name__ == '__main__':
src/.gitignore CHANGED
@@ -9,4 +9,5 @@ __tmp/*
9
  .mypycache
10
  .ruff_cache
11
  node_modules
12
- backend/**/templates/
 
 
9
  .mypycache
10
  .ruff_cache
11
  node_modules
12
+ backend/**/templates/
13
+ README_TEMPLATE.md
src/README.md CHANGED
@@ -10,7 +10,7 @@ app_file: space.py
10
  ---
11
 
12
  # `gradio_taggrouphelper`
13
- <a href="https://pypi.org/project/gradio_taggrouphelper/" target="_blank"><img alt="PyPI - Version" src="https://img.shields.io/pypi/v/gradio_taggrouphelper"></a>
14
 
15
  A fast text generator based on tagged words
16
 
@@ -49,10 +49,65 @@ TAG_DATA = {
49
  ]
50
  }
51
 
52
- with gr.Blocks() as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  gr.Markdown("# Tag Group Helper Demo")
54
  gr.Markdown("Click on the tags below to add them to the prompt textboxes.")
55
-
56
  with gr.Row():
57
  with gr.Column(scale=2): # Give more space to the textboxes
58
  # Create the target Textbox and give it a unique `elem_id`.
@@ -68,14 +123,17 @@ with gr.Blocks() as demo:
68
  lines=5,
69
  elem_id="negative-prompt-textbox" # This ID must be unique
70
  )
71
-
72
- with gr.Column(scale=1): # Give less space to the helpers
73
  # Create an instance of the TagGroupHelper for the Positive Prompt box.
74
  TagGroupHelper(
75
  label="Positive Prompt Keywords",
76
  value={k: v for k, v in TAG_DATA.items() if "Negative" not in k},
77
  target_textbox_id="positive-prompt-textbox",
78
- separator=" "
 
 
 
 
79
  )
80
 
81
  # Create another instance for the Negative Prompt box.
@@ -83,8 +141,10 @@ with gr.Blocks() as demo:
83
  label="Negative Prompt Keywords",
84
  value={"Negative Prompts": TAG_DATA["Negative Prompts"]},
85
  target_textbox_id="negative-prompt-textbox",
86
- min_width=150,
87
- separator=", "
 
 
88
  )
89
 
90
  if __name__ == '__main__':
@@ -124,29 +184,29 @@ typing.Optional[typing.Dict[str, typing.List[str]]][
124
  </tr>
125
 
126
  <tr>
127
- <td align="left"><code>target_textbox_id</code></td>
128
  <td align="left" style="width: 25%;">
129
 
130
  ```python
131
- str | None
132
  ```
133
 
134
  </td>
135
  <td align="left"><code>None</code></td>
136
- <td align="left">The `elem_id` of the `gr.Textbox` component to target. Required.</td>
137
  </tr>
138
 
139
  <tr>
140
- <td align="left"><code>separator</code></td>
141
  <td align="left" style="width: 25%;">
142
 
143
  ```python
144
- str
145
  ```
146
 
147
  </td>
148
- <td align="left"><code>", "</code></td>
149
- <td align="left">The string to use as a separator between tags. Defaults to ", ". Can be set to " " for space separation.</td>
150
  </tr>
151
 
152
  <tr>
@@ -163,29 +223,55 @@ str | None
163
  </tr>
164
 
165
  <tr>
166
- <td align="left"><code>visible</code></td>
167
  <td align="left" style="width: 25%;">
168
 
169
  ```python
170
- bool
171
  ```
172
 
173
  </td>
174
- <td align="left"><code>True</code></td>
175
- <td align="left">If False, the component will be hidden.</td>
176
  </tr>
177
 
178
  <tr>
179
- <td align="left"><code>elem_id</code></td>
180
  <td align="left" style="width: 25%;">
181
 
182
  ```python
183
- str | None
184
  ```
185
 
186
  </td>
187
  <td align="left"><code>None</code></td>
188
- <td align="left">An optional string that is assigned as the id of this component in the HTML DOM.</td>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  </tr>
190
 
191
  <tr>
@@ -206,16 +292,55 @@ int | None
206
  <td align="left" style="width: 25%;">
207
 
208
  ```python
209
- int | None
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  ```
211
 
212
  </td>
213
  <td align="left"><code>None</code></td>
214
- <td align="left">The minimum-width of the component in pixels.</td>
215
  </tr>
216
 
217
  <tr>
218
- <td align="left"><code>container</code></td>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  <td align="left" style="width: 25%;">
220
 
221
  ```python
@@ -224,7 +349,20 @@ bool
224
 
225
  </td>
226
  <td align="left"><code>True</code></td>
227
- <td align="left">If False, the component will not be wrapped in a container.</td>
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  </tr>
229
 
230
  <tr>
 
10
  ---
11
 
12
  # `gradio_taggrouphelper`
13
+ <img alt="Static Badge" src="https://img.shields.io/badge/version%20-%200.0.3%20-%20blue"> <a href="https://huggingface.co/spaces/elismasilva/gradio_taggrouphelper"><img src="https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Demo-blue"></a> <p><span>💻 <a href='https://github.com/DEVAIEXP/gradio_component_taggrouphelper'>Component GitHub Code</a></span></p>
14
 
15
  A fast text generator based on tagged words
16
 
 
49
  ]
50
  }
51
 
52
+ css="""
53
+ body {
54
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
55
+ margin: 0;
56
+ padding: 0;
57
+ }
58
+ .gradio-container {
59
+ border-radius: 15px;
60
+ padding: 30px 40px;
61
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
62
+ margin: 40px 340px;
63
+ }
64
+ .gradio-container h1 {
65
+ text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
66
+ }
67
+ .fillable {
68
+ width: 100% !important;
69
+ max-width: unset !important;
70
+ }
71
+ #examples_container {
72
+ margin: auto;
73
+ width: 90%;
74
+ }
75
+ #examples_row {
76
+ justify-content: center;
77
+ }
78
+ #tips_row{
79
+ padding-left: 20px;
80
+ }
81
+ .sidebar {
82
+ border-radius: 10px;
83
+ padding: 10px;
84
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
85
+ }
86
+ .sidebar .toggle-button {
87
+ background: linear-gradient(90deg, #34d399, #10b981) !important;
88
+ border: none;
89
+ padding: 12px 18px;
90
+ text-transform: uppercase;
91
+ font-weight: bold;
92
+ letter-spacing: 1px;
93
+ border-radius: 5px;
94
+ cursor: pointer;
95
+ transition: transform 0.2s ease-in-out;
96
+ }
97
+ .toggle-button:hover {
98
+ transform: scale(1.05);
99
+ }
100
+ .sidebar .sidebar-content {
101
+ padding-left: 10px !important;
102
+ }
103
+ .sidebar .sidebar-content .column .block div .prose {
104
+ text-align: center;
105
+ }
106
+ """
107
+ with gr.Blocks(theme=gr.themes.Ocean(), css=css) as demo:
108
  gr.Markdown("# Tag Group Helper Demo")
109
  gr.Markdown("Click on the tags below to add them to the prompt textboxes.")
110
+ gr.Markdown("<span>💻 <a href='https://github.com/DEVAIEXP/gradio_component_taggrouphelper'>GitHub Code</a></span>")
111
  with gr.Row():
112
  with gr.Column(scale=2): # Give more space to the textboxes
113
  # Create the target Textbox and give it a unique `elem_id`.
 
123
  lines=5,
124
  elem_id="negative-prompt-textbox" # This ID must be unique
125
  )
126
+ with gr.Sidebar(position="right"):
 
127
  # Create an instance of the TagGroupHelper for the Positive Prompt box.
128
  TagGroupHelper(
129
  label="Positive Prompt Keywords",
130
  value={k: v for k, v in TAG_DATA.items() if "Negative" not in k},
131
  target_textbox_id="positive-prompt-textbox",
132
+ separator=", ",
133
+ interactive=True,
134
+ width=250,
135
+ font_size_scale=90
136
+
137
  )
138
 
139
  # Create another instance for the Negative Prompt box.
 
141
  label="Negative Prompt Keywords",
142
  value={"Negative Prompts": TAG_DATA["Negative Prompts"]},
143
  target_textbox_id="negative-prompt-textbox",
144
+ separator=", ",
145
+ interactive=True,
146
+ width=250,
147
+ font_size_scale=90
148
  )
149
 
150
  if __name__ == '__main__':
 
184
  </tr>
185
 
186
  <tr>
187
+ <td align="left"><code>height</code></td>
188
  <td align="left" style="width: 25%;">
189
 
190
  ```python
191
+ int | None
192
  ```
193
 
194
  </td>
195
  <td align="left"><code>None</code></td>
196
+ <td align="left">The height of the component container in pixels.</td>
197
  </tr>
198
 
199
  <tr>
200
+ <td align="left"><code>width</code></td>
201
  <td align="left" style="width: 25%;">
202
 
203
  ```python
204
+ int | None
205
  ```
206
 
207
  </td>
208
+ <td align="left"><code>None</code></td>
209
+ <td align="left">The width of the component container in pixels.</td>
210
  </tr>
211
 
212
  <tr>
 
223
  </tr>
224
 
225
  <tr>
226
+ <td align="left"><code>font_size_scale</code></td>
227
  <td align="left" style="width: 25%;">
228
 
229
  ```python
230
+ int
231
  ```
232
 
233
  </td>
234
+ <td align="left"><code>100</code></td>
235
+ <td align="left">A percentage to scale the font size of group headers and tags. Defaults to 100.</td>
236
  </tr>
237
 
238
  <tr>
239
+ <td align="left"><code>every</code></td>
240
  <td align="left" style="width: 25%;">
241
 
242
  ```python
243
+ float | None
244
  ```
245
 
246
  </td>
247
  <td align="left"><code>None</code></td>
248
+ <td align="left">If `value` is a callable, run the function 'every' seconds while the client connection is open.</td>
249
+ </tr>
250
+
251
+ <tr>
252
+ <td align="left"><code>show_label</code></td>
253
+ <td align="left" style="width: 25%;">
254
+
255
+ ```python
256
+ bool | None
257
+ ```
258
+
259
+ </td>
260
+ <td align="left"><code>None</code></td>
261
+ <td align="left">If False, the label is not displayed.</td>
262
+ </tr>
263
+
264
+ <tr>
265
+ <td align="left"><code>container</code></td>
266
+ <td align="left" style="width: 25%;">
267
+
268
+ ```python
269
+ bool
270
+ ```
271
+
272
+ </td>
273
+ <td align="left"><code>True</code></td>
274
+ <td align="left">If False, the component will not be wrapped in a container.</td>
275
  </tr>
276
 
277
  <tr>
 
292
  <td align="left" style="width: 25%;">
293
 
294
  ```python
295
+ int
296
+ ```
297
+
298
+ </td>
299
+ <td align="left"><code>160</code></td>
300
+ <td align="left">The minimum width of the component in pixels.</td>
301
+ </tr>
302
+
303
+ <tr>
304
+ <td align="left"><code>interactive</code></td>
305
+ <td align="left" style="width: 25%;">
306
+
307
+ ```python
308
+ bool | None
309
  ```
310
 
311
  </td>
312
  <td align="left"><code>None</code></td>
313
+ <td align="left">if True, will be rendered as an selectable component; if False, editing will be disabled. If not provided, this is inferred based on whether the component is used as an input or output.</td>
314
  </tr>
315
 
316
  <tr>
317
+ <td align="left"><code>target_textbox_id</code></td>
318
+ <td align="left" style="width: 25%;">
319
+
320
+ ```python
321
+ str | None
322
+ ```
323
+
324
+ </td>
325
+ <td align="left"><code>None</code></td>
326
+ <td align="left">The `elem_id` of the `gr.Textbox` component to target. Required.</td>
327
+ </tr>
328
+
329
+ <tr>
330
+ <td align="left"><code>separator</code></td>
331
+ <td align="left" style="width: 25%;">
332
+
333
+ ```python
334
+ str
335
+ ```
336
+
337
+ </td>
338
+ <td align="left"><code>", "</code></td>
339
+ <td align="left">The string to use as a separator between tags. Defaults to ", ". Can be set to " " for space separation.</td>
340
+ </tr>
341
+
342
+ <tr>
343
+ <td align="left"><code>visible</code></td>
344
  <td align="left" style="width: 25%;">
345
 
346
  ```python
 
349
 
350
  </td>
351
  <td align="left"><code>True</code></td>
352
+ <td align="left">If False, the component will be hidden.</td>
353
+ </tr>
354
+
355
+ <tr>
356
+ <td align="left"><code>elem_id</code></td>
357
+ <td align="left" style="width: 25%;">
358
+
359
+ ```python
360
+ str | None
361
+ ```
362
+
363
+ </td>
364
+ <td align="left"><code>None</code></td>
365
+ <td align="left">An optional string that is assigned as the id of this component in the HTML DOM.</td>
366
  </tr>
367
 
368
  <tr>
src/backend/gradio_taggrouphelper/taggrouphelper.py CHANGED
@@ -14,14 +14,20 @@ class TagGroupHelper(Component):
14
  self,
15
  value: Dict[str, List[str]] | None = None,
16
  *,
 
 
 
 
 
 
 
 
 
 
17
  target_textbox_id: str | None = None,
18
  separator: str = ", ",
19
- label: str | None = None,
20
  visible: bool = True,
21
- elem_id: str | None = None,
22
- scale: int | None = None,
23
- min_width: int | None = None,
24
- container: bool = True,
25
  elem_classes: list[str] | str | None = None,
26
 
27
  **kwargs,
@@ -31,14 +37,20 @@ class TagGroupHelper(Component):
31
 
32
  Parameters:
33
  value: A dictionary where keys are group names and values are lists of tags.
 
 
 
 
 
 
 
 
 
 
34
  target_textbox_id: The `elem_id` of the `gr.Textbox` component to target. Required.
35
  separator: The string to use as a separator between tags. Defaults to ", ". Can be set to " " for space separation.
36
- label: The label for this component, displayed above the groups.
37
  visible: If False, the component will be hidden.
38
- elem_id: An optional string that is assigned as the id of this component in the HTML DOM.
39
- scale: The relative size of the component compared to others in a `gr.Row` or `gr.Column`.
40
- min_width: The minimum-width of the component in pixels.
41
- container: If False, the component will not be wrapped in a container.
42
  elem_classes: An optional list of strings to assign as CSS classes to the component.
43
  """
44
  if target_textbox_id is None:
@@ -46,13 +58,19 @@ class TagGroupHelper(Component):
46
 
47
  self.target_textbox_id = target_textbox_id
48
  self.separator = separator
 
 
 
49
 
50
  # Call the parent constructor with all the arguments it understands.
51
  super().__init__(
52
  label=label,
53
  visible=visible,
54
  elem_id=elem_id,
55
- value=value,
 
 
 
56
  scale=scale,
57
  min_width=min_width,
58
  container=container,
 
14
  self,
15
  value: Dict[str, List[str]] | None = None,
16
  *,
17
+ height: int | None = None,
18
+ width: int | None = None,
19
+ label: str | None = None,
20
+ font_size_scale: int = 100,
21
+ every: float | None = None,
22
+ show_label: bool | None = None,
23
+ container: bool = True,
24
+ scale: int | None = None,
25
+ min_width: int = 160,
26
+ interactive: bool | None = None,
27
  target_textbox_id: str | None = None,
28
  separator: str = ", ",
 
29
  visible: bool = True,
30
+ elem_id: str | None = None,
 
 
 
31
  elem_classes: list[str] | str | None = None,
32
 
33
  **kwargs,
 
37
 
38
  Parameters:
39
  value: A dictionary where keys are group names and values are lists of tags.
40
+ height: The height of the component container in pixels.
41
+ width: The width of the component container in pixels.
42
+ label: The label for this component, displayed above the groups.
43
+ font_size_scale: A percentage to scale the font size of group headers and tags. Defaults to 100.
44
+ every: If `value` is a callable, run the function 'every' seconds while the client connection is open.
45
+ show_label: If False, the label is not displayed.
46
+ container: If False, the component will not be wrapped in a container.
47
+ scale: The relative size of the component compared to others in a `gr.Row` or `gr.Column`.
48
+ min_width: The minimum width of the component in pixels.
49
+ interactive: if True, will be rendered as an selectable component; if False, editing will be disabled. If not provided, this is inferred based on whether the component is used as an input or output.
50
  target_textbox_id: The `elem_id` of the `gr.Textbox` component to target. Required.
51
  separator: The string to use as a separator between tags. Defaults to ", ". Can be set to " " for space separation.
 
52
  visible: If False, the component will be hidden.
53
+ elem_id: An optional string that is assigned as the id of this component in the HTML DOM.
 
 
 
54
  elem_classes: An optional list of strings to assign as CSS classes to the component.
55
  """
56
  if target_textbox_id is None:
 
58
 
59
  self.target_textbox_id = target_textbox_id
60
  self.separator = separator
61
+ self.width = width
62
+ self.height = height
63
+ self.font_size_scale = font_size_scale
64
 
65
  # Call the parent constructor with all the arguments it understands.
66
  super().__init__(
67
  label=label,
68
  visible=visible,
69
  elem_id=elem_id,
70
+ value=value,
71
+ every=every,
72
+ show_label=show_label,
73
+ interactive=interactive,
74
  scale=scale,
75
  min_width=min_width,
76
  container=container,
src/backend/gradio_taggrouphelper/templates/component/index.js CHANGED
The diff for this file is too large to render. See raw diff
 
src/backend/gradio_taggrouphelper/templates/component/style.css CHANGED
The diff for this file is too large to render. See raw diff
 
src/demo/app.py CHANGED
@@ -24,10 +24,65 @@ TAG_DATA = {
24
  ]
25
  }
26
 
27
- with gr.Blocks() as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  gr.Markdown("# Tag Group Helper Demo")
29
  gr.Markdown("Click on the tags below to add them to the prompt textboxes.")
30
-
31
  with gr.Row():
32
  with gr.Column(scale=2): # Give more space to the textboxes
33
  # Create the target Textbox and give it a unique `elem_id`.
@@ -43,14 +98,17 @@ with gr.Blocks() as demo:
43
  lines=5,
44
  elem_id="negative-prompt-textbox" # This ID must be unique
45
  )
46
-
47
- with gr.Column(scale=1): # Give less space to the helpers
48
  # Create an instance of the TagGroupHelper for the Positive Prompt box.
49
  TagGroupHelper(
50
  label="Positive Prompt Keywords",
51
  value={k: v for k, v in TAG_DATA.items() if "Negative" not in k},
52
  target_textbox_id="positive-prompt-textbox",
53
- separator=" "
 
 
 
 
54
  )
55
 
56
  # Create another instance for the Negative Prompt box.
@@ -58,8 +116,10 @@ with gr.Blocks() as demo:
58
  label="Negative Prompt Keywords",
59
  value={"Negative Prompts": TAG_DATA["Negative Prompts"]},
60
  target_textbox_id="negative-prompt-textbox",
61
- min_width=150,
62
- separator=", "
 
 
63
  )
64
 
65
  if __name__ == '__main__':
 
24
  ]
25
  }
26
 
27
+ css="""
28
+ body {
29
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
30
+ margin: 0;
31
+ padding: 0;
32
+ }
33
+ .gradio-container {
34
+ border-radius: 15px;
35
+ padding: 30px 40px;
36
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
37
+ margin: 40px 340px;
38
+ }
39
+ .gradio-container h1 {
40
+ text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
41
+ }
42
+ .fillable {
43
+ width: 100% !important;
44
+ max-width: unset !important;
45
+ }
46
+ #examples_container {
47
+ margin: auto;
48
+ width: 90%;
49
+ }
50
+ #examples_row {
51
+ justify-content: center;
52
+ }
53
+ #tips_row{
54
+ padding-left: 20px;
55
+ }
56
+ .sidebar {
57
+ border-radius: 10px;
58
+ padding: 10px;
59
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
60
+ }
61
+ .sidebar .toggle-button {
62
+ background: linear-gradient(90deg, #34d399, #10b981) !important;
63
+ border: none;
64
+ padding: 12px 18px;
65
+ text-transform: uppercase;
66
+ font-weight: bold;
67
+ letter-spacing: 1px;
68
+ border-radius: 5px;
69
+ cursor: pointer;
70
+ transition: transform 0.2s ease-in-out;
71
+ }
72
+ .toggle-button:hover {
73
+ transform: scale(1.05);
74
+ }
75
+ .sidebar .sidebar-content {
76
+ padding-left: 10px !important;
77
+ }
78
+ .sidebar .sidebar-content .column .block div .prose {
79
+ text-align: center;
80
+ }
81
+ """
82
+ with gr.Blocks(theme=gr.themes.Ocean(), css=css) as demo:
83
  gr.Markdown("# Tag Group Helper Demo")
84
  gr.Markdown("Click on the tags below to add them to the prompt textboxes.")
85
+ gr.Markdown("<span>💻 <a href='https://github.com/DEVAIEXP/gradio_component_taggrouphelper'>GitHub Code</a></span>")
86
  with gr.Row():
87
  with gr.Column(scale=2): # Give more space to the textboxes
88
  # Create the target Textbox and give it a unique `elem_id`.
 
98
  lines=5,
99
  elem_id="negative-prompt-textbox" # This ID must be unique
100
  )
101
+ with gr.Sidebar(position="right"):
 
102
  # Create an instance of the TagGroupHelper for the Positive Prompt box.
103
  TagGroupHelper(
104
  label="Positive Prompt Keywords",
105
  value={k: v for k, v in TAG_DATA.items() if "Negative" not in k},
106
  target_textbox_id="positive-prompt-textbox",
107
+ separator=", ",
108
+ interactive=True,
109
+ width=250,
110
+ font_size_scale=90
111
+
112
  )
113
 
114
  # Create another instance for the Negative Prompt box.
 
116
  label="Negative Prompt Keywords",
117
  value={"Negative Prompts": TAG_DATA["Negative Prompts"]},
118
  target_textbox_id="negative-prompt-textbox",
119
+ separator=", ",
120
+ interactive=True,
121
+ width=250,
122
+ font_size_scale=90
123
  )
124
 
125
  if __name__ == '__main__':
src/demo/space.py CHANGED
@@ -3,7 +3,7 @@ import gradio as gr
3
  from app import demo as app
4
  import os
5
 
6
- _docs = {'TagGroupHelper': {'description': "A custom component that displays groups of clickable tags to help build prompts.\nWhen a tag is clicked, it's appended to a target Textbox component.\nThis component does not have a submittable value itself.", 'members': {'__init__': {'value': {'type': 'typing.Optional[typing.Dict[str, typing.List[str]]][\n typing.Dict[str, typing.List[str]][\n str, typing.List[str][str]\n ],\n None,\n]', 'default': 'None', 'description': 'A dictionary where keys are group names and values are lists of tags.'}, 'target_textbox_id': {'type': 'str | None', 'default': 'None', 'description': 'The `elem_id` of the `gr.Textbox` component to target. Required.'}, 'separator': {'type': 'str', 'default': '", "', 'description': 'The string to use as a separator between tags. Defaults to ", ". Can be set to " " for space separation.'}, 'label': {'type': 'str | None', 'default': 'None', 'description': 'The label for this component, displayed above the groups.'}, 'visible': {'type': 'bool', 'default': 'True', 'description': 'If False, the component will be hidden.'}, 'elem_id': {'type': 'str | None', 'default': 'None', 'description': 'An optional string that is assigned as the id of this component in the HTML DOM.'}, 'scale': {'type': 'int | None', 'default': 'None', 'description': 'The relative size of the component compared to others in a `gr.Row` or `gr.Column`.'}, 'min_width': {'type': 'int | None', 'default': 'None', 'description': 'The minimum-width of the component in pixels.'}, 'container': {'type': 'bool', 'default': 'True', 'description': 'If False, the component will not be wrapped in a container.'}, 'elem_classes': {'type': 'list[str] | str | None', 'default': 'None', 'description': 'An optional list of strings to assign as CSS classes to the component.'}}, 'postprocess': {'value': {'type': 'typing.Optional[typing.Dict[str, typing.List[str]]][\n typing.Dict[str, typing.List[str]][\n str, typing.List[str][str]\n ],\n None,\n]', 'description': None}}, 'preprocess': {'return': {'type': 'Any', 'description': None}, 'value': None}}, 'events': {}}, '__meta__': {'additional_interfaces': {}, 'user_fn_refs': {'TagGroupHelper': []}}}
7
 
8
  abs_path = os.path.join(os.path.dirname(__file__), "css.css")
9
 
@@ -64,10 +64,65 @@ TAG_DATA = {
64
  ]
65
  }
66
 
67
- with gr.Blocks() as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  gr.Markdown("# Tag Group Helper Demo")
69
  gr.Markdown("Click on the tags below to add them to the prompt textboxes.")
70
-
71
  with gr.Row():
72
  with gr.Column(scale=2): # Give more space to the textboxes
73
  # Create the target Textbox and give it a unique `elem_id`.
@@ -83,14 +138,17 @@ with gr.Blocks() as demo:
83
  lines=5,
84
  elem_id="negative-prompt-textbox" # This ID must be unique
85
  )
86
-
87
- with gr.Column(scale=1): # Give less space to the helpers
88
  # Create an instance of the TagGroupHelper for the Positive Prompt box.
89
  TagGroupHelper(
90
  label="Positive Prompt Keywords",
91
  value={k: v for k, v in TAG_DATA.items() if "Negative" not in k},
92
  target_textbox_id="positive-prompt-textbox",
93
- separator=" "
 
 
 
 
94
  )
95
 
96
  # Create another instance for the Negative Prompt box.
@@ -98,8 +156,10 @@ with gr.Blocks() as demo:
98
  label="Negative Prompt Keywords",
99
  value={"Negative Prompts": TAG_DATA["Negative Prompts"]},
100
  target_textbox_id="negative-prompt-textbox",
101
- min_width=150,
102
- separator=", "
 
 
103
  )
104
 
105
  if __name__ == '__main__':
 
3
  from app import demo as app
4
  import os
5
 
6
+ _docs = {'TagGroupHelper': {'description': "A custom component that displays groups of clickable tags to help build prompts.\nWhen a tag is clicked, it's appended to a target Textbox component.\nThis component does not have a submittable value itself.", 'members': {'__init__': {'value': {'type': 'typing.Optional[typing.Dict[str, typing.List[str]]][\n typing.Dict[str, typing.List[str]][\n str, typing.List[str][str]\n ],\n None,\n]', 'default': 'None', 'description': 'A dictionary where keys are group names and values are lists of tags.'}, 'height': {'type': 'int | None', 'default': 'None', 'description': 'The height of the component container in pixels.'}, 'width': {'type': 'int | None', 'default': 'None', 'description': 'The width of the component container in pixels.'}, 'label': {'type': 'str | None', 'default': 'None', 'description': 'The label for this component, displayed above the groups.'}, 'font_size_scale': {'type': 'int', 'default': '100', 'description': 'A percentage to scale the font size of group headers and tags. Defaults to 100.'}, 'every': {'type': 'float | None', 'default': 'None', 'description': "If `value` is a callable, run the function 'every' seconds while the client connection is open."}, 'show_label': {'type': 'bool | None', 'default': 'None', 'description': 'If False, the label is not displayed.'}, 'container': {'type': 'bool', 'default': 'True', 'description': 'If False, the component will not be wrapped in a container.'}, 'scale': {'type': 'int | None', 'default': 'None', 'description': 'The relative size of the component compared to others in a `gr.Row` or `gr.Column`.'}, 'min_width': {'type': 'int', 'default': '160', 'description': 'The minimum width of the component in pixels.'}, 'interactive': {'type': 'bool | None', 'default': 'None', 'description': 'if True, will be rendered as an selectable component; if False, editing will be disabled. If not provided, this is inferred based on whether the component is used as an input or output.'}, 'target_textbox_id': {'type': 'str | None', 'default': 'None', 'description': 'The `elem_id` of the `gr.Textbox` component to target. Required.'}, 'separator': {'type': 'str', 'default': '", "', 'description': 'The string to use as a separator between tags. Defaults to ", ". Can be set to " " for space separation.'}, 'visible': {'type': 'bool', 'default': 'True', 'description': 'If False, the component will be hidden.'}, 'elem_id': {'type': 'str | None', 'default': 'None', 'description': 'An optional string that is assigned as the id of this component in the HTML DOM.'}, 'elem_classes': {'type': 'list[str] | str | None', 'default': 'None', 'description': 'An optional list of strings to assign as CSS classes to the component.'}}, 'postprocess': {'value': {'type': 'typing.Optional[typing.Dict[str, typing.List[str]]][\n typing.Dict[str, typing.List[str]][\n str, typing.List[str][str]\n ],\n None,\n]', 'description': None}}, 'preprocess': {'return': {'type': 'Any', 'description': None}, 'value': None}}, 'events': {}}, '__meta__': {'additional_interfaces': {}, 'user_fn_refs': {'TagGroupHelper': []}}}
7
 
8
  abs_path = os.path.join(os.path.dirname(__file__), "css.css")
9
 
 
64
  ]
65
  }
66
 
67
+ css=\"\"\"
68
+ body {
69
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
70
+ margin: 0;
71
+ padding: 0;
72
+ }
73
+ .gradio-container {
74
+ border-radius: 15px;
75
+ padding: 30px 40px;
76
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
77
+ margin: 40px 340px;
78
+ }
79
+ .gradio-container h1 {
80
+ text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
81
+ }
82
+ .fillable {
83
+ width: 100% !important;
84
+ max-width: unset !important;
85
+ }
86
+ #examples_container {
87
+ margin: auto;
88
+ width: 90%;
89
+ }
90
+ #examples_row {
91
+ justify-content: center;
92
+ }
93
+ #tips_row{
94
+ padding-left: 20px;
95
+ }
96
+ .sidebar {
97
+ border-radius: 10px;
98
+ padding: 10px;
99
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
100
+ }
101
+ .sidebar .toggle-button {
102
+ background: linear-gradient(90deg, #34d399, #10b981) !important;
103
+ border: none;
104
+ padding: 12px 18px;
105
+ text-transform: uppercase;
106
+ font-weight: bold;
107
+ letter-spacing: 1px;
108
+ border-radius: 5px;
109
+ cursor: pointer;
110
+ transition: transform 0.2s ease-in-out;
111
+ }
112
+ .toggle-button:hover {
113
+ transform: scale(1.05);
114
+ }
115
+ .sidebar .sidebar-content {
116
+ padding-left: 10px !important;
117
+ }
118
+ .sidebar .sidebar-content .column .block div .prose {
119
+ text-align: center;
120
+ }
121
+ \"\"\"
122
+ with gr.Blocks(theme=gr.themes.Ocean(), css=css) as demo:
123
  gr.Markdown("# Tag Group Helper Demo")
124
  gr.Markdown("Click on the tags below to add them to the prompt textboxes.")
125
+ gr.Markdown("<span>💻 <a href='https://github.com/DEVAIEXP/gradio_component_taggrouphelper'>GitHub Code</a></span>")
126
  with gr.Row():
127
  with gr.Column(scale=2): # Give more space to the textboxes
128
  # Create the target Textbox and give it a unique `elem_id`.
 
138
  lines=5,
139
  elem_id="negative-prompt-textbox" # This ID must be unique
140
  )
141
+ with gr.Sidebar(position="right"):
 
142
  # Create an instance of the TagGroupHelper for the Positive Prompt box.
143
  TagGroupHelper(
144
  label="Positive Prompt Keywords",
145
  value={k: v for k, v in TAG_DATA.items() if "Negative" not in k},
146
  target_textbox_id="positive-prompt-textbox",
147
+ separator=", ",
148
+ interactive=True,
149
+ width=250,
150
+ font_size_scale=90
151
+
152
  )
153
 
154
  # Create another instance for the Negative Prompt box.
 
156
  label="Negative Prompt Keywords",
157
  value={"Negative Prompts": TAG_DATA["Negative Prompts"]},
158
  target_textbox_id="negative-prompt-textbox",
159
+ separator=", ",
160
+ interactive=True,
161
+ width=250,
162
+ font_size_scale=90
163
  )
164
 
165
  if __name__ == '__main__':
src/frontend/Index.svelte CHANGED
@@ -8,12 +8,17 @@
8
  export let target_textbox_id: string;
9
  export let separator: string = ", ";
10
  export let label: string;
 
 
11
  export let visible: boolean = true;
12
  export let elem_id: string = "";
13
  export let elem_classes: string[] = [];
14
  export let container: boolean = true;
15
  export let scale: number | null = null;
16
  export let min_width: number | undefined = undefined;
 
 
 
17
  export let loading_status: LoadingStatus;
18
  export let gradio: Gradio<{ clear_status: LoadingStatus; }>;
19
 
@@ -67,7 +72,7 @@
67
  </script>
68
 
69
  <!-- The main structure uses the standard Gradio <Block> component. -->
70
- <Block {visible} {elem_id} {elem_classes} {container} {scale} {min_width}>
71
  {#if loading_status}
72
  <StatusTracker
73
  autoscroll={gradio.autoscroll}
@@ -77,10 +82,16 @@
77
  />
78
  {/if}
79
 
80
- {#if label}
81
  <span class="label">{label}</span>
82
  {/if}
83
- <div class="container">
 
 
 
 
 
 
84
  <!-- We iterate over the 'value' prop, which contains our tag groups -->
85
  {#if value}
86
  {#each Object.entries(value) as [groupName, tags]}
@@ -98,6 +109,7 @@
98
  class="tag-button"
99
  style="background-color: {tagColors[i % tagColors.length]};"
100
  on:click={() => addTagToPrompt(tag)}
 
101
  >
102
  {tag}
103
  </button>
@@ -115,7 +127,10 @@
115
  border: 1px solid var(--border-color-primary);
116
  border-radius: var(--radius-lg);
117
  padding: 8px;
118
- background: var(--background-fill-secondary);
 
 
 
119
  }
120
  .label {
121
  display: block;
@@ -135,15 +150,15 @@
135
  display: flex;
136
  justify-content: space-between;
137
  align-items: center;
138
- width: 100%;
139
- padding: 8px 12px;
140
  background-color: var(--neutral-100, #f3f4f6);
141
  color: var(--neutral-700, #374151);
142
  border: 1px solid var(--border-color-primary);
143
  border-radius: var(--radius-md);
144
  text-align: left;
145
  cursor: pointer;
146
- font-size: 1rem;
147
  transition: background-color 0.2s;
148
  }
149
  .group-header:hover {
@@ -154,7 +169,7 @@
154
  font-weight: 600;
155
  }
156
  .group-toggle-icon {
157
- font-size: 1.2rem;
158
  font-weight: bold;
159
  }
160
  .tags-container {
@@ -162,12 +177,13 @@
162
  flex-wrap: wrap;
163
  gap: 8px;
164
  padding: 12px 8px;
 
165
  }
166
- .tag-button {
167
- padding: 4px 10px;
168
  border: 1px solid #d1d5db;
169
  border-radius: 12px;
170
- font-size: 0.875rem;
171
  cursor: pointer;
172
  transition: filter 0.2s;
173
  color: #1f2937;
 
8
  export let target_textbox_id: string;
9
  export let separator: string = ", ";
10
  export let label: string;
11
+ export let font_size_scale: number = 100;
12
+ export let show_label: boolean = true;
13
  export let visible: boolean = true;
14
  export let elem_id: string = "";
15
  export let elem_classes: string[] = [];
16
  export let container: boolean = true;
17
  export let scale: number | null = null;
18
  export let min_width: number | undefined = undefined;
19
+ export let height: number | undefined = undefined;
20
+ export let width: number | undefined = undefined;
21
+ export let interactive: boolean;
22
  export let loading_status: LoadingStatus;
23
  export let gradio: Gradio<{ clear_status: LoadingStatus; }>;
24
 
 
72
  </script>
73
 
74
  <!-- The main structure uses the standard Gradio <Block> component. -->
75
+ <Block {visible} {elem_id} {elem_classes} {container} {scale} {min_width} height={height || undefined}>
76
  {#if loading_status}
77
  <StatusTracker
78
  autoscroll={gradio.autoscroll}
 
82
  />
83
  {/if}
84
 
85
+ {#if label && show_label}
86
  <span class="label">{label}</span>
87
  {/if}
88
+ <div
89
+ class="container"
90
+ style:width={width ? `${width}px` : undefined}
91
+ style:height={height ? `${height}px` : undefined}
92
+ style:overflow-y={height ? 'auto' : undefined}
93
+ style="--font-scale: {font_size_scale / 100};"
94
+ >
95
  <!-- We iterate over the 'value' prop, which contains our tag groups -->
96
  {#if value}
97
  {#each Object.entries(value) as [groupName, tags]}
 
109
  class="tag-button"
110
  style="background-color: {tagColors[i % tagColors.length]};"
111
  on:click={() => addTagToPrompt(tag)}
112
+ disabled={!interactive}
113
  >
114
  {tag}
115
  </button>
 
127
  border: 1px solid var(--border-color-primary);
128
  border-radius: var(--radius-lg);
129
  padding: 8px;
130
+ background: var(--background-fill-secondary);
131
+ display: flex;
132
+ flex-direction: column;
133
+ height: 100%;
134
  }
135
  .label {
136
  display: block;
 
150
  display: flex;
151
  justify-content: space-between;
152
  align-items: center;
153
+ width: 100%;
154
+ padding: calc(8px * var(--font-scale)) 12px;
155
  background-color: var(--neutral-100, #f3f4f6);
156
  color: var(--neutral-700, #374151);
157
  border: 1px solid var(--border-color-primary);
158
  border-radius: var(--radius-md);
159
  text-align: left;
160
  cursor: pointer;
161
+ font-size: calc(1rem * var(--font-scale));
162
  transition: background-color 0.2s;
163
  }
164
  .group-header:hover {
 
169
  font-weight: 600;
170
  }
171
  .group-toggle-icon {
172
+ font-size: calc(1.2rem * var(--font-scale));
173
  font-weight: bold;
174
  }
175
  .tags-container {
 
177
  flex-wrap: wrap;
178
  gap: 8px;
179
  padding: 12px 8px;
180
+ overflow-y: auto;
181
  }
182
+ .tag-button {
183
+ padding: calc(4px * var(--font-scale)) calc(10px * var(--font-scale));
184
  border: 1px solid #d1d5db;
185
  border-radius: 12px;
186
+ font-size: calc(0.875rem * var(--font-scale));
187
  cursor: pointer;
188
  transition: filter 0.2s;
189
  color: #1f2937;
src/pyproject.toml CHANGED
@@ -8,7 +8,7 @@ build-backend = "hatchling.build"
8
 
9
  [project]
10
  name = "gradio_taggrouphelper"
11
- version = "0.0.2"
12
  description = "A fast text generator based on tagged words"
13
  readme = "README.md"
14
  license = "apache-2.0"
 
8
 
9
  [project]
10
  name = "gradio_taggrouphelper"
11
+ version = "0.0.3"
12
  description = "A fast text generator based on tagged words"
13
  readme = "README.md"
14
  license = "apache-2.0"