picocrank 1.10.0 → 1.11.0

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,337 @@
1
+ <template>
2
+ <Section title="Tabs Example" subtitle="A flexible tabbed control component with support for multiple tab panes">
3
+ <template #toolbar>
4
+ <button @click="addRandomTab" class="good">Add Tab</button>
5
+ <button @click="removeLastTab" class="bad" :disabled="tabs.length <= 1">Remove Tab</button>
6
+ </template>
7
+
8
+ <div class="tabs-example-container">
9
+ <h3>Basic Tabs</h3>
10
+ <Tabs :tabs="basicTabs" @tab-change="onTabChange">
11
+ <template #tab-0>
12
+ <div class="tab-content">
13
+ <h4>Overview</h4>
14
+ <p>
15
+ This is the Overview tab. It contains general information about the current topic.
16
+ You can place any content here, including forms, tables, images, or other components.
17
+ </p>
18
+ <ul>
19
+ <li>First item in the overview</li>
20
+ <li>Second item with more details</li>
21
+ <li>Third item explaining features</li>
22
+ </ul>
23
+ </div>
24
+ </template>
25
+ <template #tab-1>
26
+ <div class="tab-content">
27
+ <h4>Details</h4>
28
+ <p>
29
+ The Details tab provides in-depth information. This section can be used to display
30
+ comprehensive data, specifications, or detailed descriptions.
31
+ </p>
32
+ <div class="details-grid">
33
+ <div class="detail-item">
34
+ <strong>Property 1:</strong> Value 1
35
+ </div>
36
+ <div class="detail-item">
37
+ <strong>Property 2:</strong> Value 2
38
+ </div>
39
+ <div class="detail-item">
40
+ <strong>Property 3:</strong> Value 3
41
+ </div>
42
+ <div class="detail-item">
43
+ <strong>Property 4:</strong> Value 4
44
+ </div>
45
+ </div>
46
+ </div>
47
+ </template>
48
+ <template #tab-2>
49
+ <div class="tab-content">
50
+ <h4>Settings</h4>
51
+ <p>Configure your preferences and settings in this tab.</p>
52
+ <form class="settings-form">
53
+ <div class="form-group">
54
+ <label for="setting1">Setting 1:</label>
55
+ <input id="setting1" type="text" v-model="settings.setting1" placeholder="Enter value" />
56
+ </div>
57
+ <div class="form-group">
58
+ <label for="setting2">Setting 2:</label>
59
+ <select id="setting2" v-model="settings.setting2">
60
+ <option value="option1">Option 1</option>
61
+ <option value="option2">Option 2</option>
62
+ <option value="option3">Option 3</option>
63
+ </select>
64
+ </div>
65
+ <div class="form-group">
66
+ <label>
67
+ <input type="checkbox" v-model="settings.enabled" />
68
+ Enable feature
69
+ </label>
70
+ </div>
71
+ <button type="button" class="good" @click="saveSettings">Save Settings</button>
72
+ </form>
73
+ </div>
74
+ </template>
75
+ </Tabs>
76
+
77
+ <h3>Dynamic Tabs</h3>
78
+ <Tabs :tabs="tabs" :default-tab="0" @tab-change="onDynamicTabChange">
79
+ <template v-for="(tab, index) in tabs" :key="tab.id" #[`tab-${index}`]>
80
+ <div class="tab-content">
81
+ <h4>{{ tab.label }}</h4>
82
+ <p>{{ tab.content }}</p>
83
+ <div class="tab-info">
84
+ <p><strong>Tab ID:</strong> {{ tab.id }}</p>
85
+ <p><strong>Created:</strong> {{ tab.created }}</p>
86
+ </div>
87
+ </div>
88
+ </template>
89
+ </Tabs>
90
+
91
+ <h3>Tabs with Icons</h3>
92
+ <Tabs :tabs="iconTabs" @tab-change="onTabChange">
93
+ <template #tab-home>
94
+ <div class="tab-content">
95
+ <h4>Home</h4>
96
+ <p>Welcome to the home section. This tab demonstrates the use of icons in tab labels.</p>
97
+ </div>
98
+ </template>
99
+ <template #tab-profile>
100
+ <div class="tab-content">
101
+ <h4>Profile</h4>
102
+ <p>View and edit your profile information here.</p>
103
+ <div class="profile-card">
104
+ <div class="profile-avatar">JD</div>
105
+ <div class="profile-info">
106
+ <h5>John Doe</h5>
107
+ <p>john.doe@example.com</p>
108
+ </div>
109
+ </div>
110
+ </div>
111
+ </template>
112
+ <template #tab-settings>
113
+ <div class="tab-content">
114
+ <h4>Settings</h4>
115
+ <p>Manage your application settings and preferences.</p>
116
+ </div>
117
+ </template>
118
+ </Tabs>
119
+ </div>
120
+ </Section>
121
+ </template>
122
+
123
+ <script setup>
124
+ import { ref, reactive } from 'vue';
125
+ import Section from '../components/Section.vue';
126
+ import Tabs from '../components/Tabs.vue';
127
+ // Icons are optional - set to null if not available
128
+ // You can import specific icons from @hugeicons/core-free-icons if available
129
+ // Example: import { HomeIcon, UserIcon, SettingsIcon } from '@hugeicons/core-free-icons';
130
+
131
+ const basicTabs = ref([
132
+ { id: 0, label: 'Overview' },
133
+ { id: 1, label: 'Details' },
134
+ { id: 2, label: 'Settings' }
135
+ ]);
136
+
137
+ const iconTabs = ref([
138
+ { id: 'home', label: 'Home', icon: null }, // Add icon from @hugeicons/core-free-icons if available
139
+ { id: 'profile', label: 'Profile', icon: null }, // Add icon from @hugeicons/core-free-icons if available
140
+ { id: 'settings', label: 'Settings', icon: null } // Add icon from @hugeicons/core-free-icons if available
141
+ ]);
142
+
143
+ const tabs = ref([
144
+ {
145
+ id: 0,
146
+ label: 'Tab 1',
147
+ content: 'This is the first dynamically created tab. You can add or remove tabs programmatically.',
148
+ created: new Date().toLocaleTimeString()
149
+ },
150
+ {
151
+ id: 1,
152
+ label: 'Tab 2',
153
+ content: 'This is the second tab. Notice how the tabs can be added and removed dynamically.',
154
+ created: new Date().toLocaleTimeString()
155
+ }
156
+ ]);
157
+
158
+ const settings = reactive({
159
+ setting1: '',
160
+ setting2: 'option1',
161
+ enabled: false
162
+ });
163
+
164
+ let tabCounter = 2;
165
+
166
+ function onTabChange(tab, tabId) {
167
+ console.log('Tab changed:', tab, tabId);
168
+ }
169
+
170
+ function onDynamicTabChange(tab, tabId) {
171
+ console.log('Dynamic tab changed:', tab, tabId);
172
+ }
173
+
174
+ function addRandomTab() {
175
+ const tabNames = ['Alpha', 'Beta', 'Gamma', 'Delta', 'Epsilon', 'Zeta', 'Eta', 'Theta'];
176
+ const randomName = tabNames[Math.floor(Math.random() * tabNames.length)];
177
+
178
+ tabs.value.push({
179
+ id: tabCounter++,
180
+ label: randomName,
181
+ content: `This is the ${randomName} tab, dynamically added at ${new Date().toLocaleTimeString()}.`,
182
+ created: new Date().toLocaleTimeString()
183
+ });
184
+ }
185
+
186
+ function removeLastTab() {
187
+ if (tabs.value.length > 1) {
188
+ tabs.value.pop();
189
+ }
190
+ }
191
+
192
+ function saveSettings() {
193
+ alert('Settings saved! (This is just a demo)');
194
+ console.log('Settings:', settings);
195
+ }
196
+ </script>
197
+
198
+ <style scoped>
199
+ .tabs-example-container {
200
+ display: flex;
201
+ flex-direction: column;
202
+ gap: 2rem;
203
+ }
204
+
205
+ .tabs-example-container h3 {
206
+ margin: 0 0 1rem 0;
207
+ font-size: 1.3em;
208
+ font-weight: 600;
209
+ border-bottom: 1px solid var(--border-color, #e1e5e9);
210
+ padding-bottom: 0.5rem;
211
+ }
212
+
213
+ .tab-content {
214
+ display: flex;
215
+ flex-direction: column;
216
+ gap: 1rem;
217
+ }
218
+
219
+ .tab-content h4 {
220
+ margin: 0 0 0.5rem 0;
221
+ font-size: 1.2em;
222
+ font-weight: 600;
223
+ }
224
+
225
+ .tab-content p {
226
+ margin: 0;
227
+ line-height: 1.6;
228
+ }
229
+
230
+ .tab-content ul {
231
+ margin: 0.5rem 0;
232
+ padding-left: 1.5rem;
233
+ }
234
+
235
+ .tab-content li {
236
+ margin: 0.5rem 0;
237
+ }
238
+
239
+ .details-grid {
240
+ display: grid;
241
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
242
+ gap: 1rem;
243
+ margin-top: 1rem;
244
+ }
245
+
246
+ .detail-item {
247
+ padding: 0.75rem;
248
+ background-color: var(--hover-background-color, #f5f5f5);
249
+ border-radius: 4px;
250
+ }
251
+
252
+ .settings-form {
253
+ display: flex;
254
+ flex-direction: column;
255
+ gap: 1rem;
256
+ margin-top: 1rem;
257
+ }
258
+
259
+ .form-group {
260
+ display: flex;
261
+ flex-direction: column;
262
+ gap: 0.5rem;
263
+ }
264
+
265
+ .form-group label {
266
+ font-weight: 500;
267
+ }
268
+
269
+ .form-group input[type="text"],
270
+ .form-group select {
271
+ padding: 0.5rem;
272
+ border: 1px solid var(--border-color, #ccc);
273
+ border-radius: 4px;
274
+ font-size: 1em;
275
+ }
276
+
277
+ .form-group input[type="checkbox"] {
278
+ margin-right: 0.5rem;
279
+ }
280
+
281
+ .tab-info {
282
+ margin-top: 1rem;
283
+ padding: 1rem;
284
+ background-color: var(--hover-background-color, #f5f5f5);
285
+ border-radius: 4px;
286
+ }
287
+
288
+ .tab-info p {
289
+ margin: 0.5rem 0;
290
+ }
291
+
292
+ .profile-card {
293
+ display: flex;
294
+ align-items: center;
295
+ gap: 1rem;
296
+ padding: 1rem;
297
+ background-color: var(--hover-background-color, #f5f5f5);
298
+ border-radius: 8px;
299
+ margin-top: 1rem;
300
+ }
301
+
302
+ .profile-avatar {
303
+ width: 60px;
304
+ height: 60px;
305
+ border-radius: 50%;
306
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
307
+ display: flex;
308
+ align-items: center;
309
+ justify-content: center;
310
+ color: white;
311
+ font-size: 1.5em;
312
+ font-weight: bold;
313
+ }
314
+
315
+ .profile-info h5 {
316
+ margin: 0 0 0.25rem 0;
317
+ font-size: 1.1em;
318
+ }
319
+
320
+ .profile-info p {
321
+ margin: 0;
322
+ color: var(--text-muted, #666);
323
+ }
324
+
325
+ @media (prefers-color-scheme: dark) {
326
+ .detail-item,
327
+ .tab-info,
328
+ .profile-card {
329
+ background-color: var(--hover-background-color, #333);
330
+ }
331
+
332
+ .detail-item strong,
333
+ .tab-info strong {
334
+ color: var(--text-color, #fff);
335
+ }
336
+ }
337
+ </style>
@@ -0,0 +1,79 @@
1
+ <template>
2
+ <Section title="User Control Panel" subtitle="Manage your account settings and preferences">
3
+ <Navigation ref="localNavigation">
4
+ <NavigationGrid />
5
+ </Navigation>
6
+ </Section>
7
+ </template>
8
+
9
+ <script setup>
10
+ import { ref, onMounted } from 'vue';
11
+ import Section from '../components/Section.vue';
12
+ import NavigationGrid from '../components/NavigationGrid.vue';
13
+ import Navigation from '../components/Navigation.vue';
14
+ import {
15
+ ViewIcon,
16
+ EditIcon,
17
+ SecurityValidationIcon,
18
+ HomeIcon
19
+ } from '@hugeicons/core-free-icons';
20
+
21
+ const localNavigation = ref(null);
22
+
23
+ onMounted(() => {
24
+ if (localNavigation.value) {
25
+ // Add user control panel links to local navigation
26
+ localNavigation.value.addCallback('Profile', () => {
27
+ alert('Navigate to Profile');
28
+ }, {
29
+ icon: ViewIcon,
30
+ name: 'user-profile',
31
+ description: 'View and edit your profile information'
32
+ });
33
+
34
+ localNavigation.value.addCallback('Account Settings', () => {
35
+ alert('Navigate to Account Settings');
36
+ }, {
37
+ icon: EditIcon,
38
+ name: 'account-settings',
39
+ description: 'Manage your account configuration'
40
+ });
41
+
42
+ localNavigation.value.addCallback('Security', () => {
43
+ alert('Navigate to Security Settings');
44
+ }, {
45
+ icon: SecurityValidationIcon,
46
+ name: 'security-settings',
47
+ description: 'Change password and security options'
48
+ });
49
+
50
+ localNavigation.value.addCallback('Preferences', () => {
51
+ alert('Navigate to Preferences');
52
+ }, {
53
+ icon: HomeIcon,
54
+ name: 'preferences',
55
+ description: 'Customize your application preferences'
56
+ });
57
+
58
+ localNavigation.value.addCallback('Notifications', () => {
59
+ alert('Navigate to Notifications');
60
+ }, {
61
+ icon: ViewIcon,
62
+ name: 'notifications',
63
+ description: 'Manage notification settings'
64
+ });
65
+
66
+ localNavigation.value.addCallback('Billing', () => {
67
+ alert('Navigate to Billing');
68
+ }, {
69
+ icon: EditIcon,
70
+ name: 'billing',
71
+ description: 'View billing and subscription details'
72
+ });
73
+ }
74
+ });
75
+ </script>
76
+
77
+ <style scoped>
78
+ /* Additional styles if needed */
79
+ </style>
@@ -24,7 +24,7 @@
24
24
  <button class = "good">Add</button>
25
25
  </template>
26
26
 
27
- <div>
27
+ <div role = "toolbar">
28
28
  <button class = "neutral">
29
29
  Neutral
30
30
  </button>