picocrank 1.30.0 → 1.31.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.
package/package.json
CHANGED
|
@@ -6,11 +6,21 @@
|
|
|
6
6
|
<div
|
|
7
7
|
v-if="showActions"
|
|
8
8
|
class="readonly-textarea-actions"
|
|
9
|
-
:class="{ 'readonly-textarea-actions--leading': hasActions }"
|
|
10
9
|
>
|
|
11
10
|
<div v-if="hasActions" class="readonly-textarea-actions-slot">
|
|
12
11
|
<slot name="actions" />
|
|
13
12
|
</div>
|
|
13
|
+
<button
|
|
14
|
+
v-if="showClearButton"
|
|
15
|
+
type="button"
|
|
16
|
+
class="readonly-textarea-clear neutral"
|
|
17
|
+
title="Clear contents"
|
|
18
|
+
:disabled="!modelValue"
|
|
19
|
+
@click="clear"
|
|
20
|
+
>
|
|
21
|
+
<HugeiconsIcon :icon="Delete02Icon" width="1em" height="1em" />
|
|
22
|
+
<span>{{ clearLabel }}</span>
|
|
23
|
+
</button>
|
|
14
24
|
<button
|
|
15
25
|
v-if="showCopyButton"
|
|
16
26
|
type="button"
|
|
@@ -39,7 +49,7 @@
|
|
|
39
49
|
<script setup>
|
|
40
50
|
import { ref, computed, useId, useSlots, watch, Comment } from 'vue'
|
|
41
51
|
import { HugeiconsIcon } from '@hugeicons/vue'
|
|
42
|
-
import { Copy01Icon, CopyCheckIcon } from '@hugeicons/core-free-icons'
|
|
52
|
+
import { Copy01Icon, CopyCheckIcon, Delete02Icon } from '@hugeicons/core-free-icons'
|
|
43
53
|
|
|
44
54
|
const props = defineProps({
|
|
45
55
|
modelValue: {
|
|
@@ -70,6 +80,10 @@ const props = defineProps({
|
|
|
70
80
|
type: Boolean,
|
|
71
81
|
default: true,
|
|
72
82
|
},
|
|
83
|
+
showClearButton: {
|
|
84
|
+
type: Boolean,
|
|
85
|
+
default: false,
|
|
86
|
+
},
|
|
73
87
|
copyLabel: {
|
|
74
88
|
type: String,
|
|
75
89
|
default: 'Copy',
|
|
@@ -78,6 +92,10 @@ const props = defineProps({
|
|
|
78
92
|
type: String,
|
|
79
93
|
default: 'Copied',
|
|
80
94
|
},
|
|
95
|
+
clearLabel: {
|
|
96
|
+
type: String,
|
|
97
|
+
default: 'Clear',
|
|
98
|
+
},
|
|
81
99
|
copiedFeedbackMs: {
|
|
82
100
|
type: Number,
|
|
83
101
|
default: 2000,
|
|
@@ -92,27 +110,40 @@ const props = defineProps({
|
|
|
92
110
|
},
|
|
93
111
|
})
|
|
94
112
|
|
|
95
|
-
const emit = defineEmits(['copy', 'copy-error', 'update:modelValue'])
|
|
113
|
+
const emit = defineEmits(['copy', 'copy-error', 'clear', 'update:modelValue'])
|
|
96
114
|
|
|
97
115
|
const slots = useSlots()
|
|
98
116
|
|
|
99
|
-
const
|
|
117
|
+
const slotActionCount = computed(() => {
|
|
100
118
|
const render = slots.actions
|
|
101
119
|
if (!render) {
|
|
102
|
-
return
|
|
120
|
+
return 0
|
|
103
121
|
}
|
|
104
|
-
return render().
|
|
122
|
+
return render().filter((vnode) => vnode.type !== Comment).length
|
|
105
123
|
})
|
|
106
124
|
|
|
107
|
-
const
|
|
125
|
+
const hasActions = computed(() => slotActionCount.value > 0)
|
|
126
|
+
|
|
127
|
+
const builtInActionCount = computed(() => {
|
|
128
|
+
let count = 0
|
|
129
|
+
if (props.showClearButton) count++
|
|
130
|
+
if (props.showCopyButton) count++
|
|
131
|
+
return count
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
const actionButtonCount = computed(
|
|
135
|
+
() => slotActionCount.value + builtInActionCount.value,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
const showActions = computed(
|
|
139
|
+
() => actionButtonCount.value > 0,
|
|
140
|
+
)
|
|
108
141
|
|
|
109
142
|
const showHeader = computed(
|
|
110
143
|
() => Boolean(props.label) || showActions.value,
|
|
111
144
|
)
|
|
112
145
|
|
|
113
|
-
const pushActionsEnd = computed(
|
|
114
|
-
() => showActions.value && !hasActions.value,
|
|
115
|
-
)
|
|
146
|
+
const pushActionsEnd = computed(() => showActions.value)
|
|
116
147
|
|
|
117
148
|
const generatedId = useId()
|
|
118
149
|
const textareaId = props.id || `readonly-textarea-${generatedId}`
|
|
@@ -156,6 +187,7 @@ function appendSection(sectionName) {
|
|
|
156
187
|
function clear() {
|
|
157
188
|
content.value = ''
|
|
158
189
|
emit('update:modelValue', content.value)
|
|
190
|
+
emit('clear')
|
|
159
191
|
}
|
|
160
192
|
|
|
161
193
|
function getContentAsString() {
|
|
@@ -236,10 +268,6 @@ defineExpose({
|
|
|
236
268
|
flex-shrink: 0;
|
|
237
269
|
}
|
|
238
270
|
|
|
239
|
-
.readonly-textarea-actions--leading {
|
|
240
|
-
margin-left: 0;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
271
|
.readonly-textarea-actions-slot {
|
|
244
272
|
display: inline-flex;
|
|
245
273
|
align-items: center;
|
|
@@ -247,7 +275,8 @@ defineExpose({
|
|
|
247
275
|
flex-wrap: wrap;
|
|
248
276
|
}
|
|
249
277
|
|
|
250
|
-
.readonly-textarea-copy
|
|
278
|
+
.readonly-textarea-copy,
|
|
279
|
+
.readonly-textarea-clear {
|
|
251
280
|
display: inline-flex;
|
|
252
281
|
align-items: center;
|
|
253
282
|
gap: 0.35em;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
:id="SIDEBAR_PANEL_ID"
|
|
4
4
|
ref="sidebarRef"
|
|
5
5
|
class="sidebar"
|
|
6
|
-
:class="{ 'shown':
|
|
6
|
+
:class="{ 'shown': isVisible, 'stuck': isStuck }"
|
|
7
7
|
aria-label="Sidebar"
|
|
8
8
|
:aria-hidden="isVisible ? undefined : 'true'"
|
|
9
9
|
:inert="isVisible ? undefined : true"
|
|
@@ -25,14 +25,14 @@
|
|
|
25
25
|
:icon="Pin02Icon"
|
|
26
26
|
width="1em"
|
|
27
27
|
height="1em"
|
|
28
|
-
:strokeWidth="
|
|
28
|
+
:strokeWidth="1.5"
|
|
29
29
|
/>
|
|
30
30
|
<HugeiconsIcon
|
|
31
31
|
v-else
|
|
32
32
|
:icon="PinIcon"
|
|
33
33
|
width="1em"
|
|
34
34
|
height="1em"
|
|
35
|
-
:strokeWidth="
|
|
35
|
+
:strokeWidth="1.5"
|
|
36
36
|
/>
|
|
37
37
|
</span>
|
|
38
38
|
</button>
|
|
@@ -274,8 +274,13 @@ function unstick() {
|
|
|
274
274
|
}
|
|
275
275
|
|
|
276
276
|
function toggle() {
|
|
277
|
+
if (isStuck.value) {
|
|
278
|
+
isStuck.value = false
|
|
279
|
+
isOpen.value = false
|
|
280
|
+
return
|
|
281
|
+
}
|
|
282
|
+
|
|
277
283
|
isOpen.value = !isOpen.value
|
|
278
|
-
isStuck.value = false
|
|
279
284
|
}
|
|
280
285
|
|
|
281
286
|
function open() {
|
|
@@ -284,7 +289,6 @@ function open() {
|
|
|
284
289
|
|
|
285
290
|
function close() {
|
|
286
291
|
isOpen.value = false
|
|
287
|
-
isStuck.value = false
|
|
288
292
|
}
|
|
289
293
|
|
|
290
294
|
function isLinkActive(link) {
|
|
@@ -410,6 +414,28 @@ button {
|
|
|
410
414
|
border: 0;
|
|
411
415
|
}
|
|
412
416
|
|
|
417
|
+
.stick-toggle {
|
|
418
|
+
display: inline-flex;
|
|
419
|
+
align-items: center;
|
|
420
|
+
justify-content: center;
|
|
421
|
+
align-self: stretch;
|
|
422
|
+
flex-shrink: 0;
|
|
423
|
+
padding-top: 0;
|
|
424
|
+
padding-bottom: 0;
|
|
425
|
+
padding-left: 1em;
|
|
426
|
+
padding-right: 1em;
|
|
427
|
+
border-radius: 0;
|
|
428
|
+
color: var(--text-color);
|
|
429
|
+
background-color: transparent;
|
|
430
|
+
cursor: pointer;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
.stick-toggle:hover,
|
|
434
|
+
.stick-toggle:focus-visible {
|
|
435
|
+
background-color: var(--sidebar-hover-bg-color);
|
|
436
|
+
color: var(--hover-text-color);
|
|
437
|
+
}
|
|
438
|
+
|
|
413
439
|
.navigation-links,
|
|
414
440
|
.nav-section-links {
|
|
415
441
|
list-style: none;
|
package/vue/examples/App.vue
CHANGED
|
@@ -222,11 +222,6 @@
|
|
|
222
222
|
registerSidebarNavigation(navigation.value, { onHelloWorld: helloWorld })
|
|
223
223
|
registerTopBarNavigation(topBarNavigation.value)
|
|
224
224
|
|
|
225
|
-
if (sidebar.value) {
|
|
226
|
-
sidebar.value.open();
|
|
227
|
-
sidebar.value.stick();
|
|
228
|
-
}
|
|
229
|
-
|
|
230
225
|
registerQuickSearchItems()
|
|
231
226
|
});
|
|
232
227
|
|
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
v-model="diagnosticLog"
|
|
18
18
|
label="Application log"
|
|
19
19
|
:rows="10"
|
|
20
|
+
show-clear-button
|
|
20
21
|
@copy="onCopy"
|
|
22
|
+
@clear="onClear"
|
|
21
23
|
>
|
|
22
24
|
<template #actions>
|
|
23
25
|
<button type="button" @click="refreshDiagnostics">Refresh log</button>
|
|
@@ -28,6 +30,7 @@
|
|
|
28
30
|
v-model="environmentInfo"
|
|
29
31
|
label="Environment (JSON)"
|
|
30
32
|
:rows="12"
|
|
33
|
+
show-clear-button
|
|
31
34
|
markdown-ticks
|
|
32
35
|
markdown-lang="json"
|
|
33
36
|
/>
|
|
@@ -37,14 +40,99 @@
|
|
|
37
40
|
v-model="yamlConfig"
|
|
38
41
|
label="Configuration (YAML)"
|
|
39
42
|
:rows="12"
|
|
43
|
+
show-clear-button
|
|
40
44
|
markdown-ticks
|
|
41
45
|
markdown-lang="yaml"
|
|
42
46
|
/>
|
|
43
47
|
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
<div class="readonly-playground">
|
|
49
|
+
<p class="readonly-playground-intro">
|
|
50
|
+
Toggle options on the playground instance below to explore every
|
|
51
|
+
<code>ReadOnlyTextArea</code> prop and the actions slot.
|
|
52
|
+
</p>
|
|
53
|
+
|
|
54
|
+
<div
|
|
55
|
+
class="readonly-playground-controls"
|
|
56
|
+
role="group"
|
|
57
|
+
aria-label="ReadOnlyTextArea playground options"
|
|
58
|
+
>
|
|
59
|
+
<label class="readonly-example-toggle">
|
|
60
|
+
<input v-model="playground.labelEnabled" type="checkbox" />
|
|
61
|
+
Label
|
|
62
|
+
</label>
|
|
63
|
+
<label class="readonly-example-toggle">
|
|
64
|
+
<input v-model="playground.showCopyButton" type="checkbox" />
|
|
65
|
+
Copy button
|
|
66
|
+
</label>
|
|
67
|
+
<label class="readonly-example-toggle">
|
|
68
|
+
<input v-model="playground.showClearButton" type="checkbox" />
|
|
69
|
+
Clear button
|
|
70
|
+
</label>
|
|
71
|
+
<label class="readonly-example-toggle">
|
|
72
|
+
<input v-model="playground.showActions" type="checkbox" />
|
|
73
|
+
Actions slot
|
|
74
|
+
</label>
|
|
75
|
+
<label class="readonly-example-toggle">
|
|
76
|
+
<input v-model="playground.monospace" type="checkbox" />
|
|
77
|
+
Monospace
|
|
78
|
+
</label>
|
|
79
|
+
<label class="readonly-example-toggle">
|
|
80
|
+
<input v-model="playground.markdownTicks" type="checkbox" />
|
|
81
|
+
Markdown ticks
|
|
82
|
+
</label>
|
|
83
|
+
<label class="readonly-example-toggle">
|
|
84
|
+
<input
|
|
85
|
+
v-model="playground.markdownLangJson"
|
|
86
|
+
type="checkbox"
|
|
87
|
+
:disabled="!playground.markdownTicks"
|
|
88
|
+
/>
|
|
89
|
+
Markdown lang: json
|
|
90
|
+
</label>
|
|
91
|
+
<label class="readonly-example-toggle">
|
|
92
|
+
<input v-model="playground.usePlaceholder" type="checkbox" />
|
|
93
|
+
Placeholder
|
|
94
|
+
</label>
|
|
95
|
+
<label class="readonly-example-toggle">
|
|
96
|
+
<input v-model="playground.customButtonLabels" type="checkbox" />
|
|
97
|
+
Custom button labels
|
|
98
|
+
</label>
|
|
99
|
+
<label class="readonly-example-toggle readonly-playground-rows">
|
|
100
|
+
<span>Rows</span>
|
|
101
|
+
<input
|
|
102
|
+
v-model.number="playground.rows"
|
|
103
|
+
type="number"
|
|
104
|
+
min="2"
|
|
105
|
+
max="24"
|
|
106
|
+
/>
|
|
107
|
+
</label>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<ReadOnlyTextArea
|
|
111
|
+
v-model="playgroundContent"
|
|
112
|
+
:label="playground.labelEnabled ? 'Playground output' : ''"
|
|
113
|
+
:rows="playground.rows"
|
|
114
|
+
:placeholder="playground.usePlaceholder ? 'No diagnostics available.' : ''"
|
|
115
|
+
:monospace="playground.monospace"
|
|
116
|
+
:show-copy-button="playground.showCopyButton"
|
|
117
|
+
:show-clear-button="playground.showClearButton"
|
|
118
|
+
:copy-label="playground.customButtonLabels ? 'Copy all' : undefined"
|
|
119
|
+
:copied-label="playground.customButtonLabels ? 'Copied!' : undefined"
|
|
120
|
+
:clear-label="playground.customButtonLabels ? 'Reset' : undefined"
|
|
121
|
+
:markdown-ticks="playground.markdownTicks"
|
|
122
|
+
:markdown-lang="playground.markdownTicks && playground.markdownLangJson ? 'json' : ''"
|
|
123
|
+
@copy="onPlaygroundCopy"
|
|
124
|
+
@clear="onPlaygroundClear"
|
|
125
|
+
@copy-error="onPlaygroundCopyError"
|
|
126
|
+
>
|
|
127
|
+
<template v-if="playground.showActions" #actions>
|
|
128
|
+
<button type="button" @click="fillPlaygroundContent">Fill sample</button>
|
|
129
|
+
</template>
|
|
130
|
+
</ReadOnlyTextArea>
|
|
131
|
+
|
|
132
|
+
<p v-if="playgroundFeedback" class="copy-feedback subtle">
|
|
133
|
+
{{ playgroundFeedback }}
|
|
134
|
+
</p>
|
|
135
|
+
</div>
|
|
48
136
|
|
|
49
137
|
<p v-if="lastCopied" class="copy-feedback subtle">
|
|
50
138
|
Copied {{ lastCopied.length > 60 ? `${lastCopied.slice(0, 60)}…` : lastCopied }}
|
|
@@ -62,8 +150,40 @@ const diagnosticLog = ref('')
|
|
|
62
150
|
const environmentInfo = ref('')
|
|
63
151
|
const yamlConfig = ref('')
|
|
64
152
|
const lastCopied = ref('')
|
|
153
|
+
const playgroundFeedback = ref('')
|
|
65
154
|
const yamlConfigRef = ref(null)
|
|
66
155
|
|
|
156
|
+
const playground = ref({
|
|
157
|
+
labelEnabled: false,
|
|
158
|
+
showCopyButton: true,
|
|
159
|
+
showClearButton: false,
|
|
160
|
+
showActions: false,
|
|
161
|
+
monospace: true,
|
|
162
|
+
markdownTicks: false,
|
|
163
|
+
markdownLangJson: false,
|
|
164
|
+
usePlaceholder: false,
|
|
165
|
+
customButtonLabels: false,
|
|
166
|
+
rows: 4,
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
function buildPlaygroundSample() {
|
|
170
|
+
return [
|
|
171
|
+
'Playground sample output',
|
|
172
|
+
'Toggle the checkboxes above to try label, buttons, markdown fences, and monospace.',
|
|
173
|
+
'',
|
|
174
|
+
'status: ok',
|
|
175
|
+
'items: 3',
|
|
176
|
+
].join('\n')
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const playgroundContent = ref(buildPlaygroundSample())
|
|
180
|
+
|
|
181
|
+
function fillPlaygroundContent() {
|
|
182
|
+
playground.value.usePlaceholder = false
|
|
183
|
+
playgroundContent.value = buildPlaygroundSample()
|
|
184
|
+
playgroundFeedback.value = 'Filled playground with sample content.'
|
|
185
|
+
}
|
|
186
|
+
|
|
67
187
|
function buildDiagnosticLog() {
|
|
68
188
|
const now = new Date().toISOString()
|
|
69
189
|
return [
|
|
@@ -122,6 +242,23 @@ function onCopy(value) {
|
|
|
122
242
|
lastCopied.value = value.split('\n')[0]
|
|
123
243
|
}
|
|
124
244
|
|
|
245
|
+
function onClear() {
|
|
246
|
+
lastCopied.value = ''
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function onPlaygroundCopy(value) {
|
|
250
|
+
playgroundFeedback.value = `Copied ${value.split('\n').length} line(s).`
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function onPlaygroundClear() {
|
|
254
|
+
playgroundContent.value = ''
|
|
255
|
+
playgroundFeedback.value = 'Playground cleared.'
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function onPlaygroundCopyError(error) {
|
|
259
|
+
playgroundFeedback.value = `Copy failed: ${error?.message ?? error}`
|
|
260
|
+
}
|
|
261
|
+
|
|
125
262
|
refreshDiagnostics()
|
|
126
263
|
</script>
|
|
127
264
|
|
|
@@ -140,4 +277,34 @@ refreshDiagnostics()
|
|
|
140
277
|
margin: 0;
|
|
141
278
|
font-size: 0.875rem;
|
|
142
279
|
}
|
|
280
|
+
|
|
281
|
+
.readonly-playground {
|
|
282
|
+
display: flex;
|
|
283
|
+
flex-direction: column;
|
|
284
|
+
gap: 0.75rem;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.readonly-playground-intro {
|
|
288
|
+
margin: 0;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
.readonly-example-toggle {
|
|
292
|
+
display: inline-flex;
|
|
293
|
+
align-items: center;
|
|
294
|
+
gap: 0.35rem;
|
|
295
|
+
font-size: 0.875rem;
|
|
296
|
+
cursor: pointer;
|
|
297
|
+
user-select: none;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.readonly-playground-controls {
|
|
301
|
+
display: flex;
|
|
302
|
+
flex-wrap: wrap;
|
|
303
|
+
gap: 0.75rem 1rem;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.readonly-playground-rows input[type='number'] {
|
|
307
|
+
width: 4rem;
|
|
308
|
+
padding: 0.15rem 0.35rem;
|
|
309
|
+
}
|
|
143
310
|
</style>
|