picocrank 1.12.5 → 1.13.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "picocrank",
3
- "version": "1.12.5",
3
+ "version": "1.13.1",
4
4
  "description": "A set of zero dependency Vue components built on the Femtocrank global CSS theme.",
5
5
  "main": "vite.config.js",
6
6
  "scripts": {
@@ -1,8 +1,12 @@
1
1
  <template>
2
2
  <header>
3
- <div class = "image-and-title flex-row" :id = "sidebarEnabled ? 'sidebar-button' : null" @click = "sidebarEnabled && emit('toggleSidebar')">
4
- <img :src = "logoUrl" alt = "Logo" class = "logo" />
5
- <h1>{{ title }}</h1>
3
+ <div
4
+ :id = "sidebarEnabled ? 'sidebar-button' : null"
5
+ :class="['image-and-title', 'flex-row', { 'disabled-branding': !showBranding }]"
6
+ @click = "sidebarEnabled && emit('toggleSidebar')"
7
+ >
8
+ <img v-if="showBranding" :src = "logoUrl" alt = "Logo" class = "logo" />
9
+ <h1 v-if="showBranding">{{ title }}</h1>
6
10
 
7
11
  <div class = "fg1" />
8
12
 
@@ -11,6 +15,8 @@
11
15
  </button>
12
16
  </div>
13
17
 
18
+ <TopBar v-if="topBarEnabled" :navigation="navigation" />
19
+
14
20
  <Breadcrumbs v-if="breadcrumbs" />
15
21
 
16
22
  <slot name="toolbar" />
@@ -30,6 +36,7 @@
30
36
  import { Menu01Icon } from "@hugeicons/core-free-icons";
31
37
 
32
38
  import Breadcrumbs from "./Breadcrumbs.vue";
39
+ import TopBar from "./TopBar.vue";
33
40
 
34
41
  const emit = defineEmits(["toggleSidebar"]);
35
42
 
@@ -54,6 +61,18 @@
54
61
  type: Boolean,
55
62
  default: true,
56
63
  },
64
+ showBranding: {
65
+ type: Boolean,
66
+ default: true,
67
+ },
68
+ topBarEnabled: {
69
+ type: Boolean,
70
+ default: false,
71
+ },
72
+ navigation: {
73
+ type: Object,
74
+ default: null,
75
+ },
57
76
  });
58
77
  </script>
59
78
 
@@ -67,6 +86,10 @@ button:hover {
67
86
  background-color: transparent;
68
87
  }
69
88
 
89
+ #sidebar-button.disabled-branding {
90
+ width: auto;
91
+ }
92
+
70
93
  .user-info span {
71
94
  padding-right: 0.5rem;
72
95
  }
@@ -0,0 +1,132 @@
1
+ <template>
2
+ <nav class="topbar">
3
+ <div class="topbar-links flex-row">
4
+ <template v-for="link in navigationLinks" :key="link.name">
5
+ <!-- Render separator as a divider -->
6
+ <div v-if="link.type === 'separator'" class="separator"></div>
7
+ <!-- Render callback link -->
8
+ <a v-else-if="link.type === 'callback'" href="#" @click.prevent="handleLinkClick(() => link.callback())" class="button topbar-link">
9
+ <HugeiconsIcon :icon="link.icon" width="1em" height="1em" />
10
+ <span>{{ link.title }}</span>
11
+ </a>
12
+ <!-- Render HTML content -->
13
+ <div v-else-if="link.type === 'html'" v-html="link.html" class="topbar-html"></div>
14
+ <!-- Render router link -->
15
+ <router-link v-else v-bind="link.props || {}" :to="link.to || link.path" :class="['button', 'topbar-link', { active: isActive(link) }]">
16
+ <HugeiconsIcon :icon="link.icon" width="1em" height="1em" />
17
+ <span>{{ link.title }}</span>
18
+ </router-link>
19
+ </template>
20
+ </div>
21
+ </nav>
22
+ </template>
23
+
24
+ <script setup>
25
+ import { computed, inject } from 'vue'
26
+ import { HugeiconsIcon } from '@hugeicons/vue'
27
+
28
+ const props = defineProps({
29
+ navigation: {
30
+ type: Object,
31
+ default: null
32
+ }
33
+ })
34
+
35
+ // Try to get navigation from inject first, fall back to prop
36
+ const injectedNavigation = inject('navigation', null)
37
+
38
+ // Get navigation object - handle both component ref and direct object
39
+ const navigation = computed(() => {
40
+ const nav = props.navigation || injectedNavigation
41
+ if (!nav) return null
42
+
43
+ // If it's a component ref, access its exposed API
44
+ if (nav.value) {
45
+ return nav.value
46
+ }
47
+
48
+ // Otherwise, assume it's the navigation object directly
49
+ return nav
50
+ })
51
+
52
+ // Get navigation links and isActive function from navigation
53
+ // navigationLinks is a ref, so we return it directly (Vue will unwrap it in template)
54
+ const navigationLinks = computed(() => {
55
+ const nav = navigation.value
56
+ if (!nav || !nav.navigationLinks) {
57
+ return []
58
+ }
59
+ // Return the ref itself - Vue will unwrap it in the template
60
+ return nav.navigationLinks
61
+ })
62
+
63
+ // Get isActive function - create a function that accesses the navigation computed
64
+ function isActive(link) {
65
+ const nav = navigation.value
66
+ if (!nav || !nav.isActive) {
67
+ return false
68
+ }
69
+ return nav.isActive(link)
70
+ }
71
+
72
+ function handleLinkClick(callback = null) {
73
+ if (callback) {
74
+ callback()
75
+ }
76
+ }
77
+ </script>
78
+
79
+ <style scoped>
80
+ .topbar {
81
+ width: 100%;
82
+ }
83
+
84
+ .topbar-links {
85
+ display: flex;
86
+ align-items: center;
87
+ gap: 0.125rem;
88
+ flex-wrap: wrap;
89
+ }
90
+
91
+ .topbar-link {
92
+ display: flex;
93
+ align-items: center;
94
+ gap: 0.375rem;
95
+ padding: 0.5em 0.75em;
96
+ border-radius: 0.25em;
97
+ text-decoration: none;
98
+ color: inherit;
99
+ transition: background-color 0.15s ease;
100
+ white-space: nowrap;
101
+ border: 0;
102
+ font-weight: normal;
103
+ }
104
+
105
+ .topbar-link.active {
106
+ text-decoration: underline;
107
+ font-weight: 500;
108
+ }
109
+
110
+ .topbar-html {
111
+ display: flex;
112
+ align-items: center;
113
+ }
114
+
115
+ .separator {
116
+ width: 1px;
117
+ height: 1.5em;
118
+ background-color: currentColor;
119
+ opacity: 0.3;
120
+ margin: 0 0.125rem;
121
+ }
122
+
123
+ @media (prefers-color-scheme: dark) {
124
+ .topbar-link {
125
+ color: #f8f9fa;
126
+ }
127
+
128
+ .separator {
129
+ opacity: 0.5;
130
+ }
131
+ }
132
+ </style>
package/vue/views/App.vue CHANGED
@@ -1,7 +1,8 @@
1
1
  <template>
2
- <Header username = "Guest" @toggleSidebar="toggleSidebar" title = "PicoCrank" :logoUrl="logoUrl" :sidebarEnabled="sidebarEnabled">
2
+ <Header username = "Guest" @toggleSidebar="toggleSidebar" title = "PicoCrank" :logoUrl="logoUrl" :sidebarEnabled="sidebarEnabled" :navigation="navigation" :topBarEnabled="topBarEnabled" :showBranding="brandingEnabled">
3
3
  <template #toolbar>
4
4
  <QuickSearch
5
+ v-if="quickSearchEnabled"
5
6
  ref="quickSearchRef"
6
7
  placeholder="Search items..."
7
8
  :search-fields="['title', 'name']"
@@ -42,6 +43,9 @@
42
43
  const sidebar = ref(null);
43
44
  const navigation = ref(null);
44
45
  const sidebarEnabled = ref(true);
46
+ const brandingEnabled = ref(true);
47
+ const quickSearchEnabled = ref(true);
48
+ const topBarEnabled = ref(false);
45
49
 
46
50
  function toggleSidebar() {
47
51
  if (sidebar.value) {
@@ -53,9 +57,28 @@
53
57
  sidebarEnabled.value = !sidebarEnabled.value;
54
58
  }
55
59
 
56
- // Provide sidebar state and toggle function for child components
60
+ function toggleBrandingEnabled() {
61
+ brandingEnabled.value = !brandingEnabled.value;
62
+ }
63
+
64
+ function toggleQuickSearchEnabled() {
65
+ quickSearchEnabled.value = !quickSearchEnabled.value;
66
+ }
67
+
68
+ function toggleTopBarEnabled() {
69
+ topBarEnabled.value = !topBarEnabled.value;
70
+ }
71
+
72
+ // Provide sidebar, QuickSearch, and TopBar state and toggle functions for child components
57
73
  provide('sidebarEnabled', sidebarEnabled);
58
74
  provide('toggleSidebarEnabled', toggleSidebarEnabled);
75
+ provide('brandingEnabled', brandingEnabled);
76
+ provide('toggleBrandingEnabled', toggleBrandingEnabled);
77
+
78
+ provide('quickSearchEnabled', quickSearchEnabled);
79
+ provide('toggleQuickSearchEnabled', toggleQuickSearchEnabled);
80
+ provide('topBarEnabled', topBarEnabled);
81
+ provide('toggleTopBarEnabled', toggleTopBarEnabled);
59
82
 
60
83
  onMounted(() => {
61
84
  if (navigation.value) {
@@ -84,15 +107,17 @@
84
107
  sidebar.value.stick();
85
108
  }
86
109
 
87
- quickSearchRef.value.addItem({
88
- id: 'hello-world',
89
- title: 'Hello World',
90
- name: 'hello-world',
91
- description: 'This is a test item',
92
- category: 'Actions',
93
- type: 'callback',
94
- callback: helloWorld
95
- })
110
+ if (quickSearchRef.value) {
111
+ quickSearchRef.value.addItem({
112
+ id: 'hello-world',
113
+ title: 'Hello World',
114
+ name: 'hello-world',
115
+ description: 'This is a test item',
116
+ category: 'Actions',
117
+ type: 'callback',
118
+ callback: helloWorld
119
+ })
120
+ }
96
121
  });
97
122
 
98
123
  function helloWorld() {
@@ -1,102 +1,186 @@
1
1
  <template>
2
2
  <Section
3
3
  title="Form Example"
4
- subtitle="A simple form with various input types"
5
- >
4
+ subtitle="A simple form demonstrating Femtocrank form layout"
5
+ >
6
6
  <template #toolbar>
7
7
  <button @click="resetForm">Reset</button>
8
8
  </template>
9
9
 
10
10
  <form @submit.prevent="handleSubmit">
11
- <div class="form-group">
12
- <label for="name">Name</label>
13
- <input
14
- id="name"
15
- v-model="formData.name"
16
- type="text"
17
- placeholder="Enter your name"
18
- required
19
- />
20
- </div>
21
-
22
- <div class="form-group">
23
- <label for="email">Email</label>
24
- <input
25
- id="email"
26
- v-model="formData.email"
27
- type="email"
28
- placeholder="Enter your email"
29
- required
30
- />
31
- </div>
32
-
33
- <div class="form-group">
34
- <label for="country">Country</label>
35
- <select id="country" v-model="formData.country" required>
36
- <option value="">Select a country</option>
37
- <option value="us">United States</option>
38
- <option value="uk">United Kingdom</option>
39
- <option value="ca">Canada</option>
40
- <option value="au">Australia</option>
41
- <option value="de">Germany</option>
42
- <option value="fr">France</option>
43
- </select>
44
- </div>
45
-
46
- <div class="form-group">
47
- <label for="message">Message</label>
48
- <textarea
49
- id="message"
50
- v-model="formData.message"
51
- placeholder="Enter your message"
52
- rows="4"
53
- ></textarea>
11
+ <!-- Name -->
12
+ <label for="name">Name</label>
13
+ <input
14
+ id="name"
15
+ v-model="formData.name"
16
+ type="text"
17
+ placeholder="Enter your name"
18
+ required
19
+ />
20
+
21
+ <!-- Role (radio group) -->
22
+ <span class="fake-label">Role</span>
23
+ <div class="radio-group">
24
+ <label>
25
+ <input
26
+ type="radio"
27
+ name="role"
28
+ value="sales"
29
+ v-model="formData.role"
30
+ />
31
+ <span>Sales</span>
32
+ </label>
33
+ <label>
34
+ <input
35
+ type="radio"
36
+ name="role"
37
+ value="engineering"
38
+ v-model="formData.role"
39
+ />
40
+ <span>Engineering</span>
41
+ </label>
42
+ <label>
43
+ <input
44
+ type="radio"
45
+ name="role"
46
+ value="hr"
47
+ v-model="formData.role"
48
+ />
49
+ <span>HR</span>
50
+ </label>
54
51
  </div>
55
52
 
56
- <div class="form-group">
53
+ <!-- Salary (select) -->
54
+ <label for="salary">Salary</label>
55
+ <select id="salary" v-model="formData.salary">
56
+ <option value="0">Select a salary</option>
57
+ <option value="10000">£10,000</option>
58
+ <option value="20000">£20,000</option>
59
+ <option value="30000">£30,000</option>
60
+ <option value="40000">£40,000</option>
61
+ <option value="50000">£50,000</option>
62
+ </select>
63
+
64
+ <!-- Email -->
65
+ <label for="email">Email</label>
66
+ <input
67
+ id="email"
68
+ v-model="formData.email"
69
+ type="email"
70
+ placeholder="Enter your email"
71
+ required
72
+ />
73
+
74
+ <!-- Administrator checkbox -->
75
+ <label>Is Administrator?</label>
76
+ <input
77
+ type="checkbox"
78
+ id="is-admin"
79
+ v-model="formData.isAdmin"
80
+ />
81
+
82
+ <!-- Website -->
83
+ <label for="website">Website</label>
84
+ <input
85
+ id="website"
86
+ v-model="formData.website"
87
+ type="url"
88
+ placeholder="https://example.com"
89
+ />
90
+
91
+ <!-- Favourite food (disabled) -->
92
+ <label for="favourite-food">Favourite Food</label>
93
+ <input
94
+ id="favourite-food"
95
+ v-model="formData.favouriteFood"
96
+ type="text"
97
+ placeholder="e.g. Pizza"
98
+ disabled
99
+ />
100
+
101
+ <!-- Favourite colour -->
102
+ <label for="favourite-colour">Favourite Colour</label>
103
+ <input
104
+ id="favourite-colour"
105
+ v-model="formData.favouriteColour"
106
+ type="color"
107
+ />
108
+
109
+ <!-- Favourite number -->
110
+ <label for="favourite-number">Favourite Number</label>
111
+ <input
112
+ id="favourite-number"
113
+ v-model.number="formData.favouriteNumber"
114
+ type="number"
115
+ min="0"
116
+ max="100"
117
+ step="1"
118
+ />
119
+
120
+ <!-- Newsletters (checkbox group) -->
121
+ <span class="fake-label">
122
+ Newsletters
123
+ </span>
124
+ <div>
57
125
  <label>
58
126
  <input
59
- type="checkbox"
60
- v-model="formData.newsletter"
127
+ type="checkbox"
128
+ id="newsletter1"
129
+ v-model="formData.newsletter1"
61
130
  />
62
- Subscribe to newsletter
131
+ <span>Newsletter 1</span>
63
132
  </label>
64
- </div>
65
133
 
66
- <div class="form-group">
67
- <label>Preferred Contact Method</label>
68
- <div class="radio-group">
69
- <label>
70
- <input
71
- type="radio"
72
- v-model="formData.contactMethod"
73
- value="email"
74
- />
75
- Email
76
- </label>
77
- <label>
78
- <input
79
- type="radio"
80
- v-model="formData.contactMethod"
81
- value="phone"
82
- />
83
- Phone
84
- </label>
85
- <label>
86
- <input
87
- type="radio"
88
- v-model="formData.contactMethod"
89
- value="mail"
90
- />
91
- Mail
92
- </label>
93
- </div>
134
+ <label>
135
+ <input
136
+ type="checkbox"
137
+ id="newsletter2"
138
+ v-model="formData.newsletter2"
139
+ />
140
+ <span>Newsletter 2</span>
141
+ </label>
94
142
  </div>
95
143
 
96
- <div class="form-actions">
144
+ <!-- Comments -->
145
+ <label for="comments">Comments</label>
146
+ <textarea
147
+ id="comments"
148
+ v-model="formData.comments"
149
+ ></textarea>
150
+
151
+ <!-- Readonly textarea -->
152
+ <label for="readonly">Readonly</label>
153
+ <textarea
154
+ id="readonly"
155
+ v-model="formData.readonlyText"
156
+ readonly
157
+ ></textarea>
158
+
159
+ <!-- Disabled textarea -->
160
+ <label for="disabled">Disabled</label>
161
+ <textarea
162
+ id="disabled"
163
+ v-model="formData.disabledText"
164
+ disabled
165
+ ></textarea>
166
+
167
+ <!-- Datetime -->
168
+ <label for="datetime">
169
+ Datetime
170
+ </label>
171
+ <input
172
+ id="datetime"
173
+ type="datetime-local"
174
+ v-model="formData.datetime"
175
+ />
176
+
177
+ <!-- Buttons in fieldset to match simple.html -->
178
+ <fieldset>
97
179
  <button type="submit">Submit</button>
98
- <button type="button" @click="resetForm">Clear</button>
99
- </div>
180
+ <button type="button" @click="handleCancel">Cancel</button>
181
+ <button type="reset" @click="resetForm">Reset</button>
182
+ <button type="submit" disabled>Disabled</button>
183
+ </fieldset>
100
184
  </form>
101
185
 
102
186
  <div v-if="submitted" class="form-result">
@@ -112,11 +196,20 @@ import Section from '../components/Section.vue'
112
196
 
113
197
  const formData = ref({
114
198
  name: '',
199
+ role: '',
200
+ salary: '0',
115
201
  email: '',
116
- country: '',
117
- message: '',
118
- newsletter: false,
119
- contactMethod: 'email'
202
+ isAdmin: false,
203
+ website: '',
204
+ favouriteFood: '',
205
+ favouriteColour: '#dee3e7',
206
+ favouriteNumber: 50,
207
+ newsletter1: false,
208
+ newsletter2: false,
209
+ comments: '',
210
+ readonlyText: 'This is a readonly textarea.',
211
+ disabledText: 'This is a disabled textarea.',
212
+ datetime: ''
120
213
  })
121
214
 
122
215
  const submitted = ref(false)
@@ -128,141 +221,29 @@ function handleSubmit() {
128
221
  alert('Form submitted! Check the console and the form result below.')
129
222
  }
130
223
 
224
+ function handleCancel() {
225
+ // For demo purposes, just reset submitted state
226
+ submitted.value = false
227
+ }
228
+
131
229
  function resetForm() {
132
230
  formData.value = {
133
231
  name: '',
232
+ role: '',
233
+ salary: '0',
134
234
  email: '',
135
- country: '',
136
- message: '',
137
- newsletter: false,
138
- contactMethod: 'email'
235
+ isAdmin: false,
236
+ website: '',
237
+ favouriteFood: '',
238
+ favouriteColour: '#dee3e7',
239
+ favouriteNumber: 50,
240
+ newsletter1: false,
241
+ newsletter2: false,
242
+ comments: '',
243
+ readonlyText: 'This is a readonly textarea.',
244
+ disabledText: 'This is a disabled textarea.',
245
+ datetime: ''
139
246
  }
140
247
  submitted.value = false
141
248
  }
142
- </script>
143
-
144
- <style scoped>
145
- .form-group {
146
- margin-bottom: 1.5rem;
147
- }
148
-
149
- .form-group label {
150
- display: block;
151
- margin-bottom: 0.5rem;
152
- font-weight: 500;
153
- }
154
-
155
- .form-group input[type="text"],
156
- .form-group input[type="email"],
157
- .form-group select,
158
- .form-group textarea {
159
- width: 100%;
160
- padding: 0.5rem;
161
- border: 1px solid #ccc;
162
- border-radius: 0.25rem;
163
- font-size: 1rem;
164
- }
165
-
166
- .form-group textarea {
167
- resize: vertical;
168
- font-family: inherit;
169
- }
170
-
171
- .form-group input[type="checkbox"],
172
- .form-group input[type="radio"] {
173
- margin-right: 0.5rem;
174
- }
175
-
176
- .form-group label:has(input[type="checkbox"]) {
177
- display: flex;
178
- align-items: center;
179
- font-weight: normal;
180
- }
181
-
182
- .radio-group {
183
- display: flex;
184
- gap: 1.5rem;
185
- flex-wrap: wrap;
186
- }
187
-
188
- .radio-group label {
189
- display: flex;
190
- align-items: center;
191
- font-weight: normal;
192
- }
193
-
194
- .form-actions {
195
- display: flex;
196
- gap: 1rem;
197
- margin-top: 2rem;
198
- }
199
-
200
- .form-actions button {
201
- padding: 0.75rem 1.5rem;
202
- border: none;
203
- border-radius: 0.25rem;
204
- font-size: 1rem;
205
- cursor: pointer;
206
- }
207
-
208
- .form-actions button[type="submit"] {
209
- background-color: #0366d6;
210
- color: white;
211
- }
212
-
213
- .form-actions button[type="submit"]:hover {
214
- background-color: #0256c2;
215
- }
216
-
217
- .form-actions button[type="button"] {
218
- background-color: #6c757d;
219
- color: white;
220
- }
221
-
222
- .form-actions button[type="button"]:hover {
223
- background-color: #5a6268;
224
- }
225
-
226
- .form-result {
227
- margin-top: 2rem;
228
- padding: 1rem;
229
- background-color: #f8f9fa;
230
- border-radius: 0.25rem;
231
- border: 1px solid #dee2e6;
232
- }
233
-
234
- .form-result h3 {
235
- margin-top: 0;
236
- margin-bottom: 1rem;
237
- }
238
-
239
- .form-result pre {
240
- margin: 0;
241
- padding: 1rem;
242
- background-color: white;
243
- border-radius: 0.25rem;
244
- overflow-x: auto;
245
- }
246
-
247
- @media (prefers-color-scheme: dark) {
248
- .form-group input[type="text"],
249
- .form-group input[type="email"],
250
- .form-group select,
251
- .form-group textarea {
252
- background-color: #333;
253
- border-color: #555;
254
- color: #fff;
255
- }
256
-
257
- .form-result {
258
- background-color: #2d2d2d;
259
- border-color: #444;
260
- }
261
-
262
- .form-result pre {
263
- background-color: #1a1a1a;
264
- color: #fff;
265
- }
266
- }
267
- </style>
268
-
249
+ </script>
@@ -5,14 +5,28 @@
5
5
  <HugeiconsIcon :icon="Menu01Icon" width="1em" height="1em" />
6
6
  {{ sidebarEnabled ? 'Disable Sidebar' : 'Enable Sidebar' }}
7
7
  </button>
8
+ <button @click="toggleBrandingEnabled" :class="brandingEnabled ? 'neutral' : 'good'">
9
+ <HugeiconsIcon :icon="HighlighterIcon" width="1em" height="1em" />
10
+ {{ brandingEnabled ? 'Hide Logo & Title' : 'Show Logo & Title' }}
11
+ </button>
12
+ <div style="display: flex; gap: 1rem; align-items: center;">
13
+ <label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
14
+ <input type="checkbox" :checked="quickSearchEnabled" @change="toggleQuickSearchEnabled" />
15
+ <span>Enable QuickSearch</span>
16
+ </label>
17
+ <label style="display: flex; align-items: center; gap: 0.5rem; cursor: pointer;">
18
+ <input type="checkbox" :checked="topBarEnabled" @change="toggleTopBarEnabled" />
19
+ <span>Enable TopBar</span>
20
+ </label>
21
+ </div>
8
22
  </template>
9
23
  <p>
10
- Welcome to Femtocrank, a web-based tool for analyzing and visualizing the performance of your code.
11
- To get started, you can either upload a file or paste your code directly into the editor.
24
+ Welcome to <strong>PicoCrank</strong>! This is a flexible example application to showcase a modular Vue 3 UI with a focus on ease of navigation, live UI controls, and modern design elements. Use the toolbar above to interactively enable or disable interface features like the sidebar, branding, QuickSearch, and the top navigation bar.
12
25
  </p>
13
26
  <p>
14
- For more information on how to use Femtocrank, please refer to the <a href = "/docs">documentation</a>.
27
+ Explore the sections below to see reusable components in action, including toolbars, buttons, and layout options. PicoCrank is designed to be a starting point for your own rapid Vue projects&mdash;inspect the code and try customizing the UI!
15
28
  </p>
29
+
16
30
  </Section>
17
31
 
18
32
  <Section title = "Lorum" id = "lorem">
@@ -83,7 +97,13 @@
83
97
  import { HighlighterIcon } from '@hugeicons/core-free-icons';
84
98
  import { Menu01Icon } from '@hugeicons/core-free-icons';
85
99
 
86
- // Inject sidebar state and toggle function from App.vue
100
+ // Inject sidebar and branding state and toggle functions from App.vue
87
101
  const sidebarEnabled = inject('sidebarEnabled');
88
102
  const toggleSidebarEnabled = inject('toggleSidebarEnabled');
103
+ const brandingEnabled = inject('brandingEnabled');
104
+ const toggleBrandingEnabled = inject('toggleBrandingEnabled');
105
+ const quickSearchEnabled = inject('quickSearchEnabled');
106
+ const toggleQuickSearchEnabled = inject('toggleQuickSearchEnabled');
107
+ const topBarEnabled = inject('topBarEnabled');
108
+ const toggleTopBarEnabled = inject('toggleTopBarEnabled');
89
109
  </script>