glib-web 4.39.1 → 4.39.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,215 @@
1
+ json.title @component['class_name']
2
+
3
+ page = json_ui_page json
4
+
5
+ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
6
+ # Back button
7
+ scroll.button \
8
+ text: "← Back to #{@category.titleize}",
9
+ styleClasses: ['btn-outline-secondary', 'btn-sm'],
10
+ onClick: ->(action) do
11
+ action.windows_open url: json_ui_api_url(category: @category)
12
+ end
13
+
14
+ scroll.spacer height: 16
15
+
16
+ # Title
17
+ scroll.panels_horizontal align: 'middle', childViews: ->(title_row) do
18
+ title_row.h1 text: @component['class_name']
19
+
20
+ if @component['extends']
21
+ title_row.spacer width: 12
22
+ title_row.h5 text: "extends #{@component['extends']}", styleClass: 'text-muted'
23
+ end
24
+ end
25
+
26
+ # Deprecated warning
27
+ if @component['deprecated']
28
+ scroll.spacer height: 16
29
+ scroll.panels_vertical \
30
+ padding: { all: 16 },
31
+ backgroundColor: '#fff3cd',
32
+ styleClasses: ['rounded'],
33
+ childViews: ->(warning) do
34
+ warning.h5 text: '⚠️ Deprecated', color: '#856404'
35
+ deprecation_text = @component['deprecated'] == true ? 'This component is deprecated and should not be used in new code.' : @component['deprecated']
36
+ warning.p text: deprecation_text, color: '#856404'
37
+ end
38
+ end
39
+
40
+ scroll.spacer height: 24
41
+
42
+ # Description
43
+ if @component['description']
44
+ scroll.h3 text: 'Description'
45
+ @component['description'].split("\n\n").each do |paragraph|
46
+ scroll.p text: paragraph.strip, styleClass: 'lead'
47
+ end
48
+ scroll.spacer height: 32
49
+ end
50
+
51
+ # Properties
52
+ if @component['properties'] && @component['properties'].any?
53
+ scroll.h2 text: 'Properties'
54
+ scroll.spacer height: 16
55
+
56
+ @component['properties'].each do |prop_name, prop|
57
+ scroll.panels_vertical \
58
+ padding: { all: 16 },
59
+ styleClasses: ['card', 'rounded'],
60
+ childViews: ->(prop_card) do
61
+ # Property name and badges
62
+ prop_card.panels_horizontal align: 'middle', childViews: ->(header) do
63
+ header.h5 text: prop_name, styleClass: 'font-monospace'
64
+ header.spacer width: 8
65
+
66
+ # Type badge
67
+ type_color = case prop['type']
68
+ when 'string', 'text' then '#0d6efd'
69
+ when 'int', 'float' then '#198754'
70
+ when 'bool' then '#0dcaf0'
71
+ when 'action' then '#ffc107'
72
+ when 'views', 'panels_builder' then '#6c757d'
73
+ when 'hash', 'array' then '#212529'
74
+ else '#f8f9fa'
75
+ end
76
+
77
+ header.label text: prop['type'], backgroundColor: type_color, styleClasses: ['badge'], color: '#ffffff'
78
+
79
+ if prop['required']
80
+ header.spacer width: 4
81
+ header.label text: 'required', backgroundColor: '#dc3545', styleClasses: ['badge'], color: '#ffffff'
82
+ end
83
+
84
+ if prop['deprecated']
85
+ header.spacer width: 4
86
+ header.label text: 'deprecated', backgroundColor: '#ffc107', styleClasses: ['badge']
87
+ end
88
+ end
89
+
90
+ # Description
91
+ if prop['description']
92
+ prop_card.spacer height: 8
93
+ prop['description'].split("\n").each do |line|
94
+ prop_card.p text: line.strip
95
+ end
96
+ end
97
+
98
+ # Hash options
99
+ if prop['options'] && prop['options']['optional']
100
+ prop_card.spacer height: 8
101
+ prop_card.label text: 'Optional hash keys:', styleClass: 'text-muted'
102
+ prop_card.label text: prop['options']['optional'].join(', '), styleClass: 'font-monospace'
103
+ end
104
+
105
+ # Examples
106
+ if prop['examples'] && prop['examples'].any?
107
+ prop_card.spacer height: 8
108
+ prop_card.label text: 'Example:', styleClasses: ['text-muted', 'font-weight-bold']
109
+ prop['examples'].each do |example|
110
+ prop_card.panels_vertical \
111
+ padding: { all: 12 },
112
+ backgroundColor: '#f6f8fa',
113
+ styleClasses: ['rounded'],
114
+ childViews: ->(code_block) do
115
+ code_block.label text: example, styleClass: 'font-monospace'
116
+ end
117
+ end
118
+ end
119
+
120
+ # Notes
121
+ if prop['notes'] && prop['notes'].any?
122
+ prop_card.spacer height: 8
123
+ prop_card.panels_vertical \
124
+ padding: { all: 12 },
125
+ backgroundColor: '#cfe2ff',
126
+ styleClasses: ['rounded'],
127
+ childViews: ->(note_block) do
128
+ note_block.label text: 'Note:', styleClasses: ['font-weight-bold'], color: '#084298'
129
+ prop['notes'].each do |note|
130
+ note_block.label text: note, color: '#084298'
131
+ end
132
+ end
133
+ end
134
+
135
+ # Deprecation
136
+ if prop['deprecated']
137
+ prop_card.spacer height: 8
138
+ prop_card.panels_vertical \
139
+ padding: { all: 12 },
140
+ backgroundColor: '#fff3cd',
141
+ styleClasses: ['rounded'],
142
+ childViews: ->(dep_block) do
143
+ dep_block.label text: 'Deprecated:', styleClasses: ['font-weight-bold'], color: '#856404'
144
+ dep_block.label text: prop['deprecated'], color: '#856404'
145
+ end
146
+ end
147
+ end
148
+
149
+ scroll.spacer height: 12
150
+ end
151
+
152
+ scroll.spacer height: 32
153
+ end
154
+
155
+ # Examples
156
+ if @component['examples'] && @component['examples'].any?
157
+ scroll.h2 text: 'Examples'
158
+ scroll.spacer height: 16
159
+
160
+ @component['examples'].each_with_index do |example, index|
161
+ scroll.panels_vertical \
162
+ styleClasses: ['card'],
163
+ childViews: ->(example_card) do
164
+ # Header
165
+ example_card.panels_vertical \
166
+ padding: { all: 12 },
167
+ backgroundColor: '#f8f9fa',
168
+ childViews: ->(header) do
169
+ header.h5 text: example['label'] || "Example #{index + 1}"
170
+ end
171
+
172
+ # Code
173
+ example_card.panels_vertical \
174
+ padding: { all: 16 },
175
+ backgroundColor: '#f6f8fa',
176
+ childViews: ->(code_block) do
177
+ example['code'].split("\n").each do |line|
178
+ code_block.label text: line, styleClass: 'font-monospace'
179
+ end
180
+ end
181
+ end
182
+
183
+ scroll.spacer height: 12
184
+ end
185
+
186
+ scroll.spacer height: 32
187
+ end
188
+
189
+ # References
190
+ if @component['references'] && @component['references'].any?
191
+ scroll.h2 text: 'References'
192
+ scroll.spacer height: 16
193
+
194
+ scroll.panels_vertical styleClasses: ['card'], childViews: ->(refs) do
195
+ @component['references'].each do |ref|
196
+ refs.panels_vertical padding: { all: 12 }, childViews: ->(ref_item) do
197
+ if ref['url']
198
+ ref_item.button \
199
+ text: ref['url'],
200
+ styleClasses: ['btn-link', 'text-start'],
201
+ onClick: ->(action) do
202
+ action.windows_open url: ref['url']
203
+ end
204
+
205
+ if ref['description']
206
+ ref_item.label text: ref['description'], styleClasses: ['text-muted', 'text-small']
207
+ end
208
+ else
209
+ ref_item.label text: ref['text'], styleClass: 'font-monospace'
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
215
+ end
@@ -0,0 +1,103 @@
1
+ json.title 'Glib Component API Documentation'
2
+
3
+ page = json_ui_page json
4
+
5
+ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
6
+ # Header
7
+ scroll.panels_vertical \
8
+ padding: { top: 32, bottom: 32 },
9
+ backgroundColor: '#667eea',
10
+ align: 'center',
11
+ childViews: ->(header) do
12
+ header.h1 text: 'Glib Component API', color: '#ffffff'
13
+ header.p text: 'Interactive documentation for all Glib UI components', color: '#ffffff'
14
+ header.label text: 'Auto-generated from YARD comments in source code', color: '#e0e0e0', styleClass: 'text-small'
15
+ end
16
+
17
+ scroll.spacer height: 32
18
+
19
+ # Title
20
+ scroll.h2 text: 'Component Categories'
21
+ scroll.p text: 'Browse components by category', styleClass: 'text-muted'
22
+
23
+ scroll.spacer height: 16
24
+
25
+ if @categories.empty?
26
+ # Warning message
27
+ scroll.panels_vertical \
28
+ padding: { all: 16 },
29
+ backgroundColor: '#fff3cd',
30
+ styleClasses: ['rounded'],
31
+ childViews: ->(warning) do
32
+ warning.h4 text: 'No Documentation Found', color: '#856404'
33
+ warning.p text: 'Component documentation has not been generated yet.'
34
+ warning.p text: 'Run bin/generate_component_docs to generate documentation.', styleClass: 'code'
35
+ end
36
+ else
37
+ # Categories grid
38
+ scroll.panels_responsive width: 'matchParent', childViews: ->(responsive) do
39
+ @categories.each do |category|
40
+ responsive.panels_column \
41
+ lg: { cols: 4 },
42
+ md: { cols: 6 },
43
+ xs: { cols: 12 },
44
+ childViews: ->(col) do
45
+ col.panels_vertical \
46
+ padding: { all: 16 },
47
+ styleClasses: ['card', 'rounded'],
48
+ onClick: ->(action) do
49
+ action.windows_open url: json_ui_api_url(category: category['key'])
50
+ end,
51
+ childViews: ->(card) do
52
+ # Title with badge
53
+ card.panels_horizontal \
54
+ align: 'middle',
55
+ childViews: ->(title_row) do
56
+ title_row.h5 text: category['name']
57
+ title_row.spacer width: 8
58
+ title_row.label \
59
+ text: "#{category['component_count']} components",
60
+ styleClasses: ['badge', 'bg-primary']
61
+ end
62
+
63
+ card.spacer height: 8
64
+
65
+ # Source file
66
+ if category['source_file']
67
+ card.label \
68
+ text: File.basename(category['source_file']),
69
+ styleClasses: ['text-muted', 'text-small', 'font-monospace']
70
+ end
71
+
72
+ card.spacer height: 12
73
+
74
+ # Button
75
+ card.button \
76
+ text: 'View Components →',
77
+ styleClasses: ['btn-outline-primary', 'btn-sm']
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ scroll.spacer height: 48
85
+
86
+ # About section
87
+ scroll.h3 text: 'About This Documentation'
88
+ scroll.panels_vertical styleClasses: ['card'], padding: { all: 16 }, childViews: ->(about) do
89
+ about.p text: 'This documentation is automatically generated from YARD comments in the Glib source code. Each component includes:'
90
+
91
+ about.panels_ul childViews: ->(ul) do
92
+ ul.label text: 'Description - What the component does and when to use it'
93
+ ul.label text: 'Properties - All available properties with types and descriptions'
94
+ ul.label text: 'Examples - Real code examples showing how to use the component'
95
+ ul.label text: 'References - Links to external documentation and garage examples'
96
+ end
97
+
98
+ about.spacer height: 8
99
+ about.label \
100
+ text: 'For more information, see doc/components/README.md and doc/common/component_documentation_guidelines.md',
101
+ styleClasses: ['text-muted', 'text-small']
102
+ end
103
+ end
@@ -0,0 +1,111 @@
1
+ json.title "#{@category.titleize} Components"
2
+
3
+ page = json_ui_page json
4
+
5
+ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
6
+ # Back button
7
+ scroll.button \
8
+ text: '← Back to Categories',
9
+ styleClasses: ['btn-outline-secondary', 'btn-sm'],
10
+ onClick: ->(action) do
11
+ action.windows_open url: json_ui_api_url
12
+ end
13
+
14
+ scroll.spacer height: 16
15
+
16
+ # Title
17
+ scroll.h2 text: "#{@category.titleize} Components"
18
+
19
+ # Metadata
20
+ if @doc['meta']
21
+ scroll.panels_vertical \
22
+ padding: { all: 12 },
23
+ backgroundColor: '#f8f9fa',
24
+ styleClasses: ['rounded'],
25
+ childViews: ->(meta) do
26
+ meta.label \
27
+ text: "Source: #{@doc['meta']['source_file']}",
28
+ styleClasses: ['text-muted', 'text-small', 'font-monospace']
29
+
30
+ if @doc['meta']['generated_at']
31
+ generated_time = Time.parse(@doc['meta']['generated_at']).strftime('%Y-%m-%d %H:%M') rescue @doc['meta']['generated_at']
32
+ meta.label \
33
+ text: "Generated: #{generated_time}",
34
+ styleClasses: ['text-muted', 'text-small']
35
+ end
36
+ end
37
+ end
38
+
39
+ scroll.spacer height: 24
40
+
41
+ # Component cards
42
+ @components.sort.each do |key, component|
43
+ scroll.panels_vertical \
44
+ id: key,
45
+ padding: { all: 16 },
46
+ styleClasses: ['card', 'rounded'],
47
+ childViews: ->(card) do
48
+ # Title
49
+ card.panels_horizontal align: 'middle', childViews: ->(title_row) do
50
+ title_row.h4 text: component['class_name']
51
+
52
+ if component['extends']
53
+ title_row.spacer width: 8
54
+ title_row.label \
55
+ text: "extends #{component['extends']}",
56
+ styleClasses: ['text-muted']
57
+ end
58
+ end
59
+
60
+ # Deprecated warning
61
+ if component['deprecated']
62
+ card.spacer height: 8
63
+ card.panels_vertical \
64
+ padding: { all: 12 },
65
+ backgroundColor: '#fff3cd',
66
+ styleClasses: ['rounded'],
67
+ childViews: ->(warning) do
68
+ warning.label text: '⚠️ Deprecated', color: '#856404', styleClass: 'font-weight-bold'
69
+ deprecation_text = component['deprecated'] == true ? 'This component is deprecated' : component['deprecated']
70
+ warning.label text: deprecation_text, color: '#856404'
71
+ end
72
+ end
73
+
74
+ # Description
75
+ if component['description']
76
+ card.spacer height: 12
77
+ component['description'].split("\n\n").each do |paragraph|
78
+ card.p text: paragraph.strip
79
+ end
80
+ end
81
+
82
+ card.spacer height: 12
83
+
84
+ # Metadata and View Details button
85
+ card.panels_horizontal align: 'middle', childViews: ->(actions) do
86
+ actions.button \
87
+ text: 'View Details →',
88
+ styleClasses: ['btn-outline-primary', 'btn-sm'],
89
+ onClick: ->(action) do
90
+ action.windows_open url: json_ui_api_url(category: @category, component: key)
91
+ end
92
+
93
+ if component['properties']
94
+ actions.spacer width: 12
95
+ actions.label \
96
+ text: "#{component['properties'].size} #{'property'.pluralize(component['properties'].size)}",
97
+ styleClasses: ['text-muted']
98
+ end
99
+
100
+ if component['examples']
101
+ actions.spacer width: 12
102
+ actions.label \
103
+ text: "#{component['examples'].size} #{'example'.pluralize(component['examples'].size)}",
104
+ styleClasses: ['text-muted']
105
+ end
106
+ end
107
+ end
108
+
109
+ scroll.spacer height: 16
110
+ end
111
+ end
@@ -3,49 +3,73 @@ json.title 'Lists'
3
3
  json_ui_page json do |page|
4
4
  render "#{@path_prefix}/nav_menu", json: json, page: page
5
5
 
6
- page.list firstSection: ->(section) do
7
- section.header padding: { top: 12, left: 16, right: 16, bottom: 12 }, childViews: ->(header) do
8
- header.h3 text: 'Section Header'
6
+ page.list(
7
+ firstSection: ->(section) do
8
+ section.header(
9
+ padding: { top: 12, left: 16, right: 16, bottom: 12 },
10
+ childViews: ->(header) do
11
+ header.h3 text: 'Section Header'
12
+ end
13
+ )
14
+ section.rows(
15
+ builder: ->(template) do
16
+ template.thumbnail(
17
+ title: 'Click me',
18
+ onClick: ->(action) do
19
+ action.windows_open url: json_ui_garage_url(path: 'home/blank')
20
+ end,
21
+ accessory: ->(accessory) do
22
+ accessory.header(
23
+ width: 'matchParent',
24
+ backgroundColor: '#b3bac2',
25
+ padding: { top: 10, bottom: 10, left: 10, right: 10 },
26
+ childViews: ->(bottom) do
27
+ bottom.label text: 'Custom row header'
28
+ end
29
+ )
30
+ accessory.footer(
31
+ width: 'matchParent',
32
+ backgroundColor: '#b3bac2',
33
+ padding: { top: 10, bottom: 10, left: 10, right: 10 },
34
+ childViews: ->(bottom) do
35
+ bottom.label text: 'Custom row footer'
36
+ end
37
+ )
38
+ end
39
+ )
40
+ template.thumbnail title: 'Item with icon and subtitle', subtitle: 'Item subtitle', icon: 'facebook'
41
+ template.thumbnail(
42
+ title: 'Item with chips',
43
+ chips: ->(menu) do
44
+ menu.button text: 'Finished', styleClass: 'info'
45
+ menu.button props: { text: 'Succeeded', styleClass: 'success' }
46
+ end
47
+ )
48
+ template.thumbnail(
49
+ title: 'Item with thumbnail image',
50
+ subtitle: 'Item subtitle',
51
+ imageUrl: glib_json_image_standard_url,
52
+ )
53
+ template.featured(
54
+ title: 'Featured with featured image',
55
+ subtitle: 'Item subtitle',
56
+ imageUrl: glib_json_image_standard_url
57
+ )
58
+ template.thumbnail(
59
+ title: 'Item with **formatted** text',
60
+ subtitle: 'Item *subtitle*',
61
+ textFormat: :markdown
62
+ )
63
+ # TODO
64
+ # template.thumbnail title: 'Item with accessories (Experimental)', subtitle: 'Item subtitle', accessoryViews: ->(thumbnail) do
65
+ # thumbnail.panels_horizontal childViews: ->(horizontal) do
66
+ # horizontal.chip text: 'finished'
67
+ # horizontal.spacer width: 10
68
+ # horizontal.chip text: 'succeeded'
69
+ # end
70
+ # end
71
+ end
72
+ )
9
73
  end
10
-
11
- section.rows builder: ->(template) do
12
- template.thumbnail title: 'Click me', onClick: ->(action) do
13
- action.windows_open url: json_ui_garage_url(path: 'home/blank')
14
- end,
15
- accessory: ->(accessory) do
16
- accessory.header \
17
- width: 'matchParent',
18
- backgroundColor: '#b3bac2',
19
- padding: { top: 10, bottom: 10, left: 10, right: 10 },
20
- childViews: ->(bottom) do
21
- bottom.label text: 'Custom row header'
22
- end
23
- accessory.footer \
24
- width: 'matchParent',
25
- backgroundColor: '#b3bac2',
26
- padding: { top: 10, bottom: 10, left: 10, right: 10 },
27
- childViews: ->(bottom) do
28
- bottom.label text: 'Custom row footer'
29
- end
30
- end
31
- template.thumbnail title: 'Item with icon and subtitle', subtitle: 'Item subtitle', icon: 'facebook'
32
- template.thumbnail title: 'Item with chips', chips: ->(menu) do
33
- menu.button text: 'Finished', styleClass: 'info'
34
- menu.button props: { text: 'Succeeded', styleClass: 'success' }
35
- end
36
-
37
- template.thumbnail title: 'Item with thumbnail image', subtitle: 'Item subtitle', imageUrl: glib_json_image_standard_url
38
- template.featured title: 'Featured with featured image', subtitle: 'Item subtitle', imageUrl: glib_json_image_standard_url
39
-
40
- # TODO
41
- # template.thumbnail title: 'Item with accessories (Experimental)', subtitle: 'Item subtitle', accessoryViews: ->(thumbnail) do
42
- # thumbnail.panels_horizontal childViews: ->(horizontal) do
43
- # horizontal.chip text: 'finished'
44
- # horizontal.spacer width: 10
45
- # horizontal.chip text: 'succeeded'
46
- # end
47
- # end
48
-
49
- end
50
- end
74
+ )
51
75
  end
@@ -27,6 +27,8 @@ json_ui_page json do |page|
27
27
  "\n" +
28
28
  '~~Strikethrough~~' + "\n" +
29
29
  "\n" +
30
+ '<u>Underlined</u>' + "\n" +
31
+ "\n" +
30
32
  'https://www.google.com' + "\n"
31
33
 
32
34
  scroll.spacer height: 20
data/config/routes.rb CHANGED
@@ -6,6 +6,10 @@ Glib::Web::Engine.routes.draw do
6
6
  delete 'json_ui_garage', to: 'home#json_ui_garage'
7
7
  post 'chat', to: 'home#chat'
8
8
 
9
+ get 'json_ui_api', to: 'api_docs#index'
10
+ get 'json_ui_api/:category', to: 'api_docs#show', as: :json_ui_api_category
11
+ get 'json_ui_api/:category/:component', to: 'api_docs#component', as: :json_ui_api_component
12
+
9
13
  resources :glib_direct_uploads, only: [:create]
10
14
  resources :blob_url_generators, only: [:create]
11
15
  resources :errors, only: [:create]