pict-section-inlinedocumentation 0.0.1
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.
- package/README.md +107 -0
- package/docs/.nojekyll +0 -0
- package/docs/README.md +83 -0
- package/docs/_cover.md +15 -0
- package/docs/_sidebar.md +24 -0
- package/docs/_topbar.md +8 -0
- package/docs/_version.json +7 -0
- package/docs/api-reference.md +185 -0
- package/docs/architecture.md +103 -0
- package/docs/css/docuserve.css +327 -0
- package/docs/embedding-level1-sidebar.md +92 -0
- package/docs/embedding-level2-routes.md +86 -0
- package/docs/embedding-level3-tooltips.md +97 -0
- package/docs/embedding-level4-autogen.md +126 -0
- package/docs/index.html +39 -0
- package/docs/overview.md +42 -0
- package/docs/quickstart.md +95 -0
- package/docs/reference.md +73 -0
- package/docs/retold-catalog.json +181 -0
- package/docs/retold-keyword-index.json +4374 -0
- package/example_applications/basic/docs/README.md +40 -0
- package/example_applications/basic/docs/_sidebar.md +4 -0
- package/example_applications/basic/docs/_topics.json +10 -0
- package/example_applications/basic/docs/advanced-topics.md +47 -0
- package/example_applications/basic/docs/getting-started.md +70 -0
- package/example_applications/basic/index.html +100 -0
- package/example_applications/bookshop/.quackage.json +10 -0
- package/example_applications/bookshop/Pict-Application-Bookshop-Configuration.json +15 -0
- package/example_applications/bookshop/Pict-Application-Bookshop.js +218 -0
- package/example_applications/bookshop/data/BookshopData.json +65 -0
- package/example_applications/bookshop/data/pict_documentation_topics.json +46 -0
- package/example_applications/bookshop/docs/_sidebar.md +6 -0
- package/example_applications/bookshop/docs/book-detail.md +21 -0
- package/example_applications/bookshop/docs/book-list.md +21 -0
- package/example_applications/bookshop/docs/search-filter.md +18 -0
- package/example_applications/bookshop/docs/store.md +29 -0
- package/example_applications/bookshop/docs/welcome.md +23 -0
- package/example_applications/bookshop/html/index.html +236 -0
- package/example_applications/bookshop/package.json +34 -0
- package/example_applications/bookshop/views/PictView-Bookshop-BookList.js +324 -0
- package/example_applications/bookshop/views/PictView-Bookshop-HelpToggle.js +44 -0
- package/example_applications/bookshop/views/PictView-Bookshop-Store.js +271 -0
- package/package.json +55 -0
- package/source/Pict-Section-InlineDocumentation.js +10 -0
- package/source/providers/Pict-Provider-InlineDocumentation.js +1995 -0
- package/source/views/Pict-View-InlineDocumentation-Content.js +542 -0
- package/source/views/Pict-View-InlineDocumentation-Layout.js +206 -0
- package/source/views/Pict-View-InlineDocumentation-Nav.js +475 -0
- package/source/views/Pict-View-InlineDocumentation-TopicManager.js +1623 -0
- package/test/Browser_Integration_tests.js +1449 -0
- package/test/Pict-Section-InlineDocumentation_test.js +1285 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Searching & Filtering
|
|
2
|
+
|
|
3
|
+
The bookshop provides a genre filter to help you find books in specific categories.
|
|
4
|
+
|
|
5
|
+
## Genre Filter
|
|
6
|
+
|
|
7
|
+
The dropdown at the top of the book catalog lets you filter by genre:
|
|
8
|
+
|
|
9
|
+
- **All Genres** — Shows every book in the catalog
|
|
10
|
+
- **Software Engineering** — Books about coding practices and software design
|
|
11
|
+
- **Distributed Systems** — Books about scalable system architecture
|
|
12
|
+
- **Computer Science** — Foundational CS theory and algorithms
|
|
13
|
+
|
|
14
|
+
## How It Works
|
|
15
|
+
|
|
16
|
+
When you select a genre, the book list instantly updates to show only books in that category. The filter selection is preserved when you navigate to a book detail page and back.
|
|
17
|
+
|
|
18
|
+
> Future versions will include full-text search across titles, authors, and descriptions.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# The Store Page
|
|
2
|
+
|
|
3
|
+
The store page is the detail view for a specific book. It provides all the information you need to make a purchase decision.
|
|
4
|
+
|
|
5
|
+
## Layout
|
|
6
|
+
|
|
7
|
+
The store page uses a two-column layout:
|
|
8
|
+
|
|
9
|
+
1. **Left column** — Book cover image
|
|
10
|
+
2. **Right column** — Book metadata, description, and action buttons
|
|
11
|
+
|
|
12
|
+
## Pricing
|
|
13
|
+
|
|
14
|
+
All prices are displayed in **USD** and include applicable tax. The price shown on the store page is the final price — no hidden fees at checkout.
|
|
15
|
+
|
|
16
|
+
## Availability
|
|
17
|
+
|
|
18
|
+
Books can have one of two statuses:
|
|
19
|
+
|
|
20
|
+
| Status | Meaning |
|
|
21
|
+
|--------|---------|
|
|
22
|
+
| **In Stock** | The book is available for purchase |
|
|
23
|
+
| **Out of Stock** | The book is currently unavailable |
|
|
24
|
+
|
|
25
|
+
Out of stock titles may be restocked periodically. Check back later or browse similar titles in the catalog.
|
|
26
|
+
|
|
27
|
+
## Returning to the Catalog
|
|
28
|
+
|
|
29
|
+
Click the **Back to Catalog** button at the top of the store page to return to the full book list. Your genre filter selection will be preserved.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Welcome to the Bookshop
|
|
2
|
+
|
|
3
|
+
Welcome to the Pict Bookshop example application. This app demonstrates how inline documentation can be embedded alongside your application views to provide contextual help.
|
|
4
|
+
|
|
5
|
+
## Getting Around
|
|
6
|
+
|
|
7
|
+
- **Book Catalog** — Browse the full list of available titles
|
|
8
|
+
- **Store Page** — Click on any book to see details and purchase options
|
|
9
|
+
- **Help** — Press **F1** or click the circled **?** icons to get contextual help
|
|
10
|
+
|
|
11
|
+
## Quick Tips
|
|
12
|
+
|
|
13
|
+
> Press **F1** at any time to toggle the help panel. The help content changes based on which part of the application you are viewing.
|
|
14
|
+
|
|
15
|
+
Each section of the application has a small **?** button next to its header. Clicking it opens the help panel with documentation specific to that section.
|
|
16
|
+
|
|
17
|
+
## Navigation
|
|
18
|
+
|
|
19
|
+
| Key | Action |
|
|
20
|
+
|-----|--------|
|
|
21
|
+
| F1 | Toggle help panel |
|
|
22
|
+
| Click ? | Open contextual help for that section |
|
|
23
|
+
| Click book | View book details and store page |
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Bookshop - Pict Example</title>
|
|
7
|
+
<!-- PICT Dynamic View CSS Container -->
|
|
8
|
+
<style id="PICT-CSS"></style>
|
|
9
|
+
<!-- Red Rock Mesa Theme -->
|
|
10
|
+
<style>
|
|
11
|
+
*, *::before, *::after { box-sizing: border-box; }
|
|
12
|
+
body { margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; background: #FAEDCD; color: #264653; }
|
|
13
|
+
|
|
14
|
+
/* --- Header Bar --- */
|
|
15
|
+
.pict-example-header { display: flex; align-items: stretch; background: #264653; border-bottom: 3px solid #E76F51; position: fixed; top: 0; left: 0; right: 0; z-index: 100; }
|
|
16
|
+
.pict-example-badge { background: #E76F51; color: #fff; padding: 0.6rem 1rem; font-size: 0.7rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.1em; display: flex; align-items: center; gap: 0.5rem; }
|
|
17
|
+
.pict-example-badge svg { width: 14px; height: 14px; fill: #fff; flex-shrink: 0; }
|
|
18
|
+
.pict-example-app-name { padding: 0.6rem 1rem; color: #FAEDCD; font-size: 1.1rem; font-weight: 600; display: flex; align-items: center; }
|
|
19
|
+
.pict-example-module { margin-left: auto; padding: 0.6rem 1rem; color: #D4A373; font-size: 0.75rem; display: flex; align-items: center; letter-spacing: 0.03em; }
|
|
20
|
+
.pict-example-header-help-btn {
|
|
21
|
+
display: flex; align-items: center; justify-content: center;
|
|
22
|
+
padding: 0 1rem; cursor: pointer; color: #D4A373;
|
|
23
|
+
font-size: 0.85rem; font-weight: 600; gap: 0.4em;
|
|
24
|
+
transition: color 0.15s; border: none; background: transparent;
|
|
25
|
+
}
|
|
26
|
+
.pict-example-header-help-btn:hover { color: #FAEDCD; }
|
|
27
|
+
.pict-example-header-help-btn .help-icon {
|
|
28
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
29
|
+
width: 20px; height: 20px; border-radius: 50%;
|
|
30
|
+
border: 2px solid currentColor; font-size: 0.75em; font-weight: 800;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* --- Layout --- */
|
|
34
|
+
.pict-example-layout { display: flex; margin-top: 44px; min-height: calc(100vh - 44px); }
|
|
35
|
+
|
|
36
|
+
/* --- Content Area --- */
|
|
37
|
+
.pict-example-content {
|
|
38
|
+
flex: 1; padding: 1.5rem; transition: margin-right 0.25s ease;
|
|
39
|
+
}
|
|
40
|
+
.pict-example-content.help-open {
|
|
41
|
+
margin-right: 380px;
|
|
42
|
+
}
|
|
43
|
+
#Bookshop-Content-Container {
|
|
44
|
+
background: #fff;
|
|
45
|
+
border: 1px solid #D4A373;
|
|
46
|
+
border-top: 4px solid #E76F51;
|
|
47
|
+
border-radius: 6px;
|
|
48
|
+
padding: 1.25rem;
|
|
49
|
+
box-shadow: 0 2px 8px rgba(38,70,83,0.08);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* --- Help Panel (slide-in from right) --- */
|
|
53
|
+
#Bookshop-Help-Panel {
|
|
54
|
+
position: fixed;
|
|
55
|
+
top: 44px;
|
|
56
|
+
right: 0;
|
|
57
|
+
bottom: 0;
|
|
58
|
+
width: 380px;
|
|
59
|
+
min-width: 320px;
|
|
60
|
+
background: #FDFCFA;
|
|
61
|
+
border-left: 1px solid #D4A373;
|
|
62
|
+
box-shadow: -2px 0 12px rgba(38,70,83,0.08);
|
|
63
|
+
transform: translateX(100%);
|
|
64
|
+
transition: transform 0.25s ease;
|
|
65
|
+
z-index: 50;
|
|
66
|
+
display: flex;
|
|
67
|
+
flex-direction: column;
|
|
68
|
+
overflow: hidden;
|
|
69
|
+
}
|
|
70
|
+
#Bookshop-Help-Panel.visible {
|
|
71
|
+
transform: translateX(0);
|
|
72
|
+
}
|
|
73
|
+
.bookshop-help-panel-header {
|
|
74
|
+
display: flex;
|
|
75
|
+
align-items: center;
|
|
76
|
+
padding: 0.6em 1em;
|
|
77
|
+
background: #264653;
|
|
78
|
+
color: #FAEDCD;
|
|
79
|
+
font-weight: 600;
|
|
80
|
+
font-size: 0.9em;
|
|
81
|
+
flex-shrink: 0;
|
|
82
|
+
}
|
|
83
|
+
.bookshop-help-panel-header span { flex: 1; }
|
|
84
|
+
.bookshop-help-panel-close {
|
|
85
|
+
background: transparent;
|
|
86
|
+
border: none;
|
|
87
|
+
color: #D4A373;
|
|
88
|
+
font-size: 1.2em;
|
|
89
|
+
cursor: pointer;
|
|
90
|
+
padding: 0 0.3em;
|
|
91
|
+
line-height: 1;
|
|
92
|
+
}
|
|
93
|
+
.bookshop-help-panel-close:hover { color: #FAEDCD; }
|
|
94
|
+
#InlineDoc-Container {
|
|
95
|
+
flex: 1;
|
|
96
|
+
overflow: hidden;
|
|
97
|
+
min-height: 0;
|
|
98
|
+
}
|
|
99
|
+
/* Override the inline doc border/background within the help panel */
|
|
100
|
+
#Bookshop-Help-Panel .pict-inline-doc {
|
|
101
|
+
border: none;
|
|
102
|
+
border-radius: 0;
|
|
103
|
+
height: 100%;
|
|
104
|
+
}
|
|
105
|
+
/* Force compact (horizontal nav) mode inside the narrow help panel */
|
|
106
|
+
#Bookshop-Help-Panel .pict-inline-doc {
|
|
107
|
+
flex-direction: column;
|
|
108
|
+
}
|
|
109
|
+
#Bookshop-Help-Panel .pict-inline-doc-nav-container {
|
|
110
|
+
width: 100%;
|
|
111
|
+
min-width: 0;
|
|
112
|
+
max-width: none;
|
|
113
|
+
border-right: none;
|
|
114
|
+
border-bottom: 1px solid #E5DED4;
|
|
115
|
+
overflow-y: visible;
|
|
116
|
+
overflow-x: auto;
|
|
117
|
+
max-height: none;
|
|
118
|
+
}
|
|
119
|
+
#Bookshop-Help-Panel .pict-inline-doc-nav {
|
|
120
|
+
padding: 0.4em 0.5em;
|
|
121
|
+
display: flex;
|
|
122
|
+
flex-wrap: wrap;
|
|
123
|
+
align-items: center;
|
|
124
|
+
gap: 0.15em 0.3em;
|
|
125
|
+
}
|
|
126
|
+
#Bookshop-Help-Panel .pict-inline-doc-nav-group {
|
|
127
|
+
display: flex;
|
|
128
|
+
flex-wrap: wrap;
|
|
129
|
+
align-items: center;
|
|
130
|
+
margin-bottom: 0;
|
|
131
|
+
gap: 0.1em 0.2em;
|
|
132
|
+
}
|
|
133
|
+
#Bookshop-Help-Panel .pict-inline-doc-nav-group-header {
|
|
134
|
+
padding: 0.2em 0.5em;
|
|
135
|
+
font-size: 0.75em;
|
|
136
|
+
white-space: nowrap;
|
|
137
|
+
}
|
|
138
|
+
#Bookshop-Help-Panel .pict-inline-doc-nav-group-toggle {
|
|
139
|
+
display: none;
|
|
140
|
+
}
|
|
141
|
+
#Bookshop-Help-Panel .pict-inline-doc-nav-group-items {
|
|
142
|
+
display: flex !important;
|
|
143
|
+
flex-wrap: wrap;
|
|
144
|
+
gap: 0.1em;
|
|
145
|
+
}
|
|
146
|
+
#Bookshop-Help-Panel .pict-inline-doc-nav-item {
|
|
147
|
+
padding: 0.2em 0.5em;
|
|
148
|
+
font-size: 0.8em;
|
|
149
|
+
border-left: none;
|
|
150
|
+
border-radius: 3px;
|
|
151
|
+
white-space: nowrap;
|
|
152
|
+
}
|
|
153
|
+
#Bookshop-Help-Panel .pict-inline-doc-nav-item.active {
|
|
154
|
+
border-left: none;
|
|
155
|
+
background: #2E7D74;
|
|
156
|
+
color: #fff;
|
|
157
|
+
}
|
|
158
|
+
#Bookshop-Help-Panel .pict-inline-doc-nav-topic-badge {
|
|
159
|
+
margin: 0 0.3em;
|
|
160
|
+
padding: 0.15em 0.5em;
|
|
161
|
+
font-size: 0.75em;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/* --- F1 hint --- */
|
|
165
|
+
.bookshop-f1-hint {
|
|
166
|
+
position: fixed;
|
|
167
|
+
bottom: 1em;
|
|
168
|
+
right: 1em;
|
|
169
|
+
background: #264653;
|
|
170
|
+
color: #D4A373;
|
|
171
|
+
padding: 0.3em 0.7em;
|
|
172
|
+
border-radius: 4px;
|
|
173
|
+
font-size: 0.75em;
|
|
174
|
+
opacity: 0.7;
|
|
175
|
+
z-index: 10;
|
|
176
|
+
}
|
|
177
|
+
</style>
|
|
178
|
+
<script src="./pict.js" type="text/javascript"></script>
|
|
179
|
+
<script type="text/javascript">Pict.safeOnDocumentReady(() => { Pict.safeLoadPictApplication(BookshopExample, 2)});</script>
|
|
180
|
+
</head>
|
|
181
|
+
<body>
|
|
182
|
+
<!-- Header Bar -->
|
|
183
|
+
<div class="pict-example-header">
|
|
184
|
+
<div class="pict-example-badge">
|
|
185
|
+
<svg viewBox="0 0 16 16"><polygon points="8,1 10,6 16,6 11,9.5 13,15 8,11.5 3,15 5,9.5 0,6 6,6"/></svg>
|
|
186
|
+
Pict Example
|
|
187
|
+
</div>
|
|
188
|
+
<div class="pict-example-app-name">Bookshop</div>
|
|
189
|
+
<div class="pict-example-module">pict-section-inlinedocumentation</div>
|
|
190
|
+
<button class="pict-example-header-help-btn" id="Bookshop-Header-HelpBtn">
|
|
191
|
+
<span class="help-icon">?</span>
|
|
192
|
+
Help
|
|
193
|
+
</button>
|
|
194
|
+
</div>
|
|
195
|
+
|
|
196
|
+
<!-- Layout -->
|
|
197
|
+
<div class="pict-example-layout">
|
|
198
|
+
<div class="pict-example-content" id="Bookshop-Content-Area">
|
|
199
|
+
<div id="Bookshop-Content-Container"></div>
|
|
200
|
+
</div>
|
|
201
|
+
</div>
|
|
202
|
+
|
|
203
|
+
<!-- Help Panel (slide-in from right) -->
|
|
204
|
+
<div id="Bookshop-Help-Panel">
|
|
205
|
+
<div class="bookshop-help-panel-header">
|
|
206
|
+
<span>Help</span>
|
|
207
|
+
<button class="bookshop-help-panel-close" id="Bookshop-Help-CloseBtn">✕</button>
|
|
208
|
+
</div>
|
|
209
|
+
<div id="InlineDoc-Container"></div>
|
|
210
|
+
</div>
|
|
211
|
+
|
|
212
|
+
<!-- F1 hint -->
|
|
213
|
+
<div class="bookshop-f1-hint">Press F1 for help</div>
|
|
214
|
+
|
|
215
|
+
<!-- Load the Application -->
|
|
216
|
+
<script src="./bookshop_example.js" type="text/javascript"></script>
|
|
217
|
+
|
|
218
|
+
<!-- Wire header help button and close button -->
|
|
219
|
+
<script>
|
|
220
|
+
document.getElementById('Bookshop-Header-HelpBtn').addEventListener('click', function ()
|
|
221
|
+
{
|
|
222
|
+
if (window._Pict && window._Pict.PictApplication)
|
|
223
|
+
{
|
|
224
|
+
window._Pict.PictApplication.toggleHelp();
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
document.getElementById('Bookshop-Help-CloseBtn').addEventListener('click', function ()
|
|
228
|
+
{
|
|
229
|
+
if (window._Pict && window._Pict.PictApplication)
|
|
230
|
+
{
|
|
231
|
+
window._Pict.PictApplication.toggleHelp();
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
</script>
|
|
235
|
+
</body>
|
|
236
|
+
</html>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "bookshop_example",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Bookshop example demonstrating inline contextual documentation with pict-section-inlinedocumentation",
|
|
5
|
+
"main": "Pict-Application-Bookshop.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "node Pict-Application-Bookshop.js",
|
|
8
|
+
"build": "npx quack build && npx quack copy"
|
|
9
|
+
},
|
|
10
|
+
"author": "steven",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"devDependencies": {},
|
|
13
|
+
"copyFilesSettings": {
|
|
14
|
+
"whenFileExists": "overwrite"
|
|
15
|
+
},
|
|
16
|
+
"copyFiles": [
|
|
17
|
+
{
|
|
18
|
+
"from": "./html/*",
|
|
19
|
+
"to": "./dist/"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"from": "../../node_modules/pict/dist/*",
|
|
23
|
+
"to": "./dist/"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"from": "./docs/*",
|
|
27
|
+
"to": "./dist/docs/"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"from": "./data/pict_documentation_topics.json",
|
|
31
|
+
"to": "./dist/docs/"
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
const libPictView = require('pict-view');
|
|
2
|
+
|
|
3
|
+
const _ViewConfiguration =
|
|
4
|
+
{
|
|
5
|
+
ViewIdentifier: "Bookshop-BookList",
|
|
6
|
+
|
|
7
|
+
DefaultRenderable: "Bookshop-BookList-Display",
|
|
8
|
+
DefaultDestinationAddress: "#Bookshop-Content-Container",
|
|
9
|
+
|
|
10
|
+
AutoRender: false,
|
|
11
|
+
|
|
12
|
+
CSS: /*css*/`
|
|
13
|
+
.bookshop-section-header {
|
|
14
|
+
display: flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
gap: 0.5em;
|
|
17
|
+
margin-bottom: 1em;
|
|
18
|
+
}
|
|
19
|
+
.bookshop-section-title {
|
|
20
|
+
font-size: 1.5em;
|
|
21
|
+
font-weight: 700;
|
|
22
|
+
color: #264653;
|
|
23
|
+
margin: 0;
|
|
24
|
+
}
|
|
25
|
+
.bookshop-help-btn {
|
|
26
|
+
display: inline-flex;
|
|
27
|
+
align-items: center;
|
|
28
|
+
justify-content: center;
|
|
29
|
+
width: 22px;
|
|
30
|
+
height: 22px;
|
|
31
|
+
border-radius: 50%;
|
|
32
|
+
border: 2px solid #D4A373;
|
|
33
|
+
background: transparent;
|
|
34
|
+
color: #D4A373;
|
|
35
|
+
font-size: 0.75em;
|
|
36
|
+
font-weight: 700;
|
|
37
|
+
cursor: pointer;
|
|
38
|
+
line-height: 1;
|
|
39
|
+
padding: 0;
|
|
40
|
+
transition: background 0.15s, color 0.15s;
|
|
41
|
+
flex-shrink: 0;
|
|
42
|
+
}
|
|
43
|
+
.bookshop-help-btn:hover {
|
|
44
|
+
background: #D4A373;
|
|
45
|
+
color: #fff;
|
|
46
|
+
}
|
|
47
|
+
.bookshop-filter-bar {
|
|
48
|
+
margin-bottom: 1.25em;
|
|
49
|
+
display: flex;
|
|
50
|
+
align-items: center;
|
|
51
|
+
gap: 0.75em;
|
|
52
|
+
}
|
|
53
|
+
.bookshop-filter-bar label {
|
|
54
|
+
font-size: 0.85em;
|
|
55
|
+
font-weight: 600;
|
|
56
|
+
color: #5E5549;
|
|
57
|
+
}
|
|
58
|
+
.bookshop-filter-bar select {
|
|
59
|
+
padding: 0.35em 0.7em;
|
|
60
|
+
border: 1px solid #D4A373;
|
|
61
|
+
border-radius: 4px;
|
|
62
|
+
font-size: 0.85em;
|
|
63
|
+
background: #fff;
|
|
64
|
+
color: #264653;
|
|
65
|
+
}
|
|
66
|
+
.bookshop-book-grid {
|
|
67
|
+
display: grid;
|
|
68
|
+
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
|
69
|
+
gap: 1.25em;
|
|
70
|
+
}
|
|
71
|
+
.bookshop-book-card {
|
|
72
|
+
display: flex;
|
|
73
|
+
gap: 1em;
|
|
74
|
+
padding: 1em;
|
|
75
|
+
background: #fff;
|
|
76
|
+
border: 1px solid #E5DED4;
|
|
77
|
+
border-radius: 6px;
|
|
78
|
+
cursor: pointer;
|
|
79
|
+
transition: box-shadow 0.15s, border-color 0.15s;
|
|
80
|
+
}
|
|
81
|
+
.bookshop-book-card:hover {
|
|
82
|
+
border-color: #D4A373;
|
|
83
|
+
box-shadow: 0 2px 8px rgba(38,70,83,0.1);
|
|
84
|
+
}
|
|
85
|
+
.bookshop-book-cover {
|
|
86
|
+
width: 80px;
|
|
87
|
+
height: 120px;
|
|
88
|
+
border-radius: 4px;
|
|
89
|
+
object-fit: cover;
|
|
90
|
+
flex-shrink: 0;
|
|
91
|
+
background: #F0ECE4;
|
|
92
|
+
}
|
|
93
|
+
.bookshop-book-info {
|
|
94
|
+
flex: 1;
|
|
95
|
+
min-width: 0;
|
|
96
|
+
}
|
|
97
|
+
.bookshop-book-title {
|
|
98
|
+
font-weight: 600;
|
|
99
|
+
font-size: 1em;
|
|
100
|
+
color: #264653;
|
|
101
|
+
margin: 0 0 0.2em;
|
|
102
|
+
}
|
|
103
|
+
.bookshop-book-author {
|
|
104
|
+
font-size: 0.85em;
|
|
105
|
+
color: #8A7F72;
|
|
106
|
+
margin: 0 0 0.4em;
|
|
107
|
+
}
|
|
108
|
+
.bookshop-book-genre {
|
|
109
|
+
display: inline-block;
|
|
110
|
+
font-size: 0.7em;
|
|
111
|
+
padding: 0.15em 0.5em;
|
|
112
|
+
background: #E8E3D8;
|
|
113
|
+
color: #5E5549;
|
|
114
|
+
border-radius: 3px;
|
|
115
|
+
margin-bottom: 0.4em;
|
|
116
|
+
}
|
|
117
|
+
.bookshop-book-price {
|
|
118
|
+
font-weight: 700;
|
|
119
|
+
color: #2E7D74;
|
|
120
|
+
font-size: 1.05em;
|
|
121
|
+
}
|
|
122
|
+
.bookshop-book-stock {
|
|
123
|
+
font-size: 0.75em;
|
|
124
|
+
margin-left: 0.5em;
|
|
125
|
+
}
|
|
126
|
+
.bookshop-book-stock.in-stock {
|
|
127
|
+
color: #2E7D74;
|
|
128
|
+
}
|
|
129
|
+
.bookshop-book-stock.out-of-stock {
|
|
130
|
+
color: #E76F51;
|
|
131
|
+
}
|
|
132
|
+
`,
|
|
133
|
+
|
|
134
|
+
Templates:
|
|
135
|
+
[
|
|
136
|
+
{
|
|
137
|
+
Hash: "Bookshop-BookList-Template",
|
|
138
|
+
Template: /*html*/`<div id="Bookshop-BookList-Body"></div>`
|
|
139
|
+
}
|
|
140
|
+
],
|
|
141
|
+
|
|
142
|
+
Renderables:
|
|
143
|
+
[
|
|
144
|
+
{
|
|
145
|
+
RenderableHash: "Bookshop-BookList-Display",
|
|
146
|
+
TemplateHash: "Bookshop-BookList-Template",
|
|
147
|
+
DestinationAddress: "#Bookshop-Content-Container",
|
|
148
|
+
RenderMethod: "replace"
|
|
149
|
+
}
|
|
150
|
+
]
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
class BookshopBookListView extends libPictView
|
|
154
|
+
{
|
|
155
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
156
|
+
{
|
|
157
|
+
super(pFable, pOptions, pServiceHash);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
onAfterRender()
|
|
161
|
+
{
|
|
162
|
+
this._renderBookList();
|
|
163
|
+
return super.onAfterRender();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
_renderBookList()
|
|
167
|
+
{
|
|
168
|
+
if (typeof document === 'undefined')
|
|
169
|
+
{
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
let tmpContainer = document.getElementById('Bookshop-BookList-Body');
|
|
174
|
+
if (!tmpContainer)
|
|
175
|
+
{
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
let tmpState = this.pict.AppData.Bookshop;
|
|
180
|
+
let tmpBooks = tmpState.Books || [];
|
|
181
|
+
let tmpGenreFilter = tmpState.GenreFilter || '';
|
|
182
|
+
|
|
183
|
+
// Collect unique genres
|
|
184
|
+
let tmpGenres = [];
|
|
185
|
+
for (let i = 0; i < tmpBooks.length; i++)
|
|
186
|
+
{
|
|
187
|
+
if (tmpGenres.indexOf(tmpBooks[i].Genre) < 0)
|
|
188
|
+
{
|
|
189
|
+
tmpGenres.push(tmpBooks[i].Genre);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
tmpGenres.sort();
|
|
193
|
+
|
|
194
|
+
// Filter books by genre
|
|
195
|
+
let tmpFilteredBooks = tmpBooks;
|
|
196
|
+
if (tmpGenreFilter)
|
|
197
|
+
{
|
|
198
|
+
tmpFilteredBooks = tmpBooks.filter((pBook) => { return pBook.Genre === tmpGenreFilter; });
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
let tmpHTML = '';
|
|
202
|
+
|
|
203
|
+
// Section header with help button
|
|
204
|
+
tmpHTML += '<div class="bookshop-section-header">';
|
|
205
|
+
tmpHTML += '<h2 class="bookshop-section-title" data-d-tooltip="catalog-title">Book Catalog</h2>';
|
|
206
|
+
tmpHTML += '<span data-d-tooltip="catalog-info" data-d-tooltip-icon></span>';
|
|
207
|
+
tmpHTML += '<button class="bookshop-help-btn" id="Bookshop-Help-BookList" title="Help: Book Catalog">?</button>';
|
|
208
|
+
tmpHTML += '</div>';
|
|
209
|
+
|
|
210
|
+
// Filter bar with help button
|
|
211
|
+
tmpHTML += '<div class="bookshop-filter-bar">';
|
|
212
|
+
tmpHTML += '<label data-d-tooltip="genre-filter">Genre:</label>';
|
|
213
|
+
tmpHTML += '<select id="Bookshop-GenreFilter">';
|
|
214
|
+
tmpHTML += '<option value="">All Genres</option>';
|
|
215
|
+
for (let g = 0; g < tmpGenres.length; g++)
|
|
216
|
+
{
|
|
217
|
+
let tmpSelected = (tmpGenreFilter === tmpGenres[g]) ? ' selected' : '';
|
|
218
|
+
tmpHTML += '<option value="' + tmpGenres[g] + '"' + tmpSelected + '>' + tmpGenres[g] + '</option>';
|
|
219
|
+
}
|
|
220
|
+
tmpHTML += '</select>';
|
|
221
|
+
tmpHTML += '<span data-d-tooltip="filter-info" data-d-tooltip-icon></span>';
|
|
222
|
+
tmpHTML += '<button class="bookshop-help-btn" id="Bookshop-Help-Search" title="Help: Search & Filter">?</button>';
|
|
223
|
+
tmpHTML += '</div>';
|
|
224
|
+
|
|
225
|
+
// Book grid
|
|
226
|
+
tmpHTML += '<div class="bookshop-book-grid">';
|
|
227
|
+
for (let i = 0; i < tmpFilteredBooks.length; i++)
|
|
228
|
+
{
|
|
229
|
+
let tmpBook = tmpFilteredBooks[i];
|
|
230
|
+
let tmpStockClass = tmpBook.InStock ? 'in-stock' : 'out-of-stock';
|
|
231
|
+
let tmpStockText = tmpBook.InStock ? 'In Stock' : 'Out of Stock';
|
|
232
|
+
|
|
233
|
+
tmpHTML += '<div class="bookshop-book-card" data-book-id="' + tmpBook.IDBook + '">';
|
|
234
|
+
tmpHTML += '<img class="bookshop-book-cover" src="' + tmpBook.Cover + '" alt="' + tmpBook.Title + '">';
|
|
235
|
+
tmpHTML += '<div class="bookshop-book-info">';
|
|
236
|
+
tmpHTML += '<p class="bookshop-book-title">' + tmpBook.Title + '</p>';
|
|
237
|
+
tmpHTML += '<p class="bookshop-book-author">' + tmpBook.Author + '</p>';
|
|
238
|
+
tmpHTML += '<span class="bookshop-book-genre" data-d-tooltip="book-genre">' + tmpBook.Genre + '</span>';
|
|
239
|
+
tmpHTML += '<div>';
|
|
240
|
+
tmpHTML += '<span class="bookshop-book-price" data-d-tooltip="book-price">$' + tmpBook.Price.toFixed(2) + '</span>';
|
|
241
|
+
tmpHTML += '<span class="bookshop-book-stock ' + tmpStockClass + '" data-d-tooltip="stock-status">' + tmpStockText + '</span>';
|
|
242
|
+
tmpHTML += '</div>';
|
|
243
|
+
tmpHTML += '</div>';
|
|
244
|
+
tmpHTML += '</div>';
|
|
245
|
+
}
|
|
246
|
+
tmpHTML += '</div>';
|
|
247
|
+
|
|
248
|
+
tmpContainer.innerHTML = tmpHTML;
|
|
249
|
+
|
|
250
|
+
// Wire click handlers
|
|
251
|
+
this._wireHandlers(tmpContainer);
|
|
252
|
+
|
|
253
|
+
// Scan for tooltip placeholders
|
|
254
|
+
let tmpDocProvider = this.pict.providers['Pict-InlineDocumentation'];
|
|
255
|
+
if (tmpDocProvider)
|
|
256
|
+
{
|
|
257
|
+
tmpDocProvider.scanTooltips();
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
_wireHandlers(pContainer)
|
|
262
|
+
{
|
|
263
|
+
let tmpApp = this.pict.PictApplication;
|
|
264
|
+
|
|
265
|
+
// Book cards
|
|
266
|
+
let tmpCards = pContainer.querySelectorAll('.bookshop-book-card');
|
|
267
|
+
for (let i = 0; i < tmpCards.length; i++)
|
|
268
|
+
{
|
|
269
|
+
let tmpCard = tmpCards[i];
|
|
270
|
+
tmpCard.addEventListener('click', () =>
|
|
271
|
+
{
|
|
272
|
+
let tmpID = parseInt(tmpCard.getAttribute('data-book-id'));
|
|
273
|
+
if (tmpApp)
|
|
274
|
+
{
|
|
275
|
+
tmpApp.showBook(tmpID);
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Genre filter
|
|
281
|
+
let tmpSelect = pContainer.querySelector('#Bookshop-GenreFilter');
|
|
282
|
+
if (tmpSelect)
|
|
283
|
+
{
|
|
284
|
+
tmpSelect.addEventListener('change', () =>
|
|
285
|
+
{
|
|
286
|
+
if (tmpApp)
|
|
287
|
+
{
|
|
288
|
+
tmpApp.filterByGenre(tmpSelect.value);
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Help buttons
|
|
294
|
+
let tmpHelpBookList = pContainer.querySelector('#Bookshop-Help-BookList');
|
|
295
|
+
if (tmpHelpBookList)
|
|
296
|
+
{
|
|
297
|
+
tmpHelpBookList.addEventListener('click', (pEvent) =>
|
|
298
|
+
{
|
|
299
|
+
pEvent.stopPropagation();
|
|
300
|
+
if (tmpApp)
|
|
301
|
+
{
|
|
302
|
+
tmpApp.showHelp('BOOKSHOP-BOOKLIST');
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
let tmpHelpSearch = pContainer.querySelector('#Bookshop-Help-Search');
|
|
308
|
+
if (tmpHelpSearch)
|
|
309
|
+
{
|
|
310
|
+
tmpHelpSearch.addEventListener('click', (pEvent) =>
|
|
311
|
+
{
|
|
312
|
+
pEvent.stopPropagation();
|
|
313
|
+
if (tmpApp)
|
|
314
|
+
{
|
|
315
|
+
tmpApp.showHelp('BOOKSHOP-SEARCH');
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
module.exports = BookshopBookListView;
|
|
323
|
+
|
|
324
|
+
module.exports.default_configuration = _ViewConfiguration;
|