@brickflow/ui 0.0.40 → 0.0.43
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/dist/module.json +1 -1
- package/dist/module.mjs +3 -0
- package/dist/runtime/components/Button/icons.demo.vue +9 -9
- package/dist/runtime/components/Button/index.vue +83 -57
- package/dist/runtime/components/Button/size.demo.vue +35 -66
- package/dist/runtime/components/Button/slots.demo.vue +10 -8
- package/dist/runtime/components/Button/state.demo.vue +58 -8
- package/dist/runtime/components/Button/variants.demo.vue +18 -20
- package/dist/runtime/components/Icon/basic.demo.vue +13 -10
- package/dist/runtime/components/Icon/gallery.demo.vue +142 -0
- package/dist/runtime/components/Icon/index.vue +15 -9
- package/dist/runtime/components/Link/basic.demo.vue +7 -7
- package/dist/runtime/components/Link/index.vue +81 -50
- package/dist/runtime/icon-font.d.ts +1 -0
- package/dist/runtime/pages/ui.vue +514 -347
- package/package.json +5 -5
- package/dist/runtime/components/Button/icons.demo.d.vue.ts +0 -8
- package/dist/runtime/components/Button/icons.demo.vue.d.ts +0 -8
- package/dist/runtime/components/Button/index.d.vue.ts +0 -51
- package/dist/runtime/components/Button/index.vue.d.ts +0 -51
- package/dist/runtime/components/Button/size.demo.d.vue.ts +0 -7
- package/dist/runtime/components/Button/size.demo.vue.d.ts +0 -7
- package/dist/runtime/components/Button/slots.demo.d.vue.ts +0 -7
- package/dist/runtime/components/Button/slots.demo.vue.d.ts +0 -7
- package/dist/runtime/components/Button/state.demo.d.vue.ts +0 -7
- package/dist/runtime/components/Button/state.demo.vue.d.ts +0 -7
- package/dist/runtime/components/Button/variants.demo.d.vue.ts +0 -7
- package/dist/runtime/components/Button/variants.demo.vue.d.ts +0 -7
- package/dist/runtime/components/Icon/basic.demo.d.vue.ts +0 -8
- package/dist/runtime/components/Icon/basic.demo.vue.d.ts +0 -8
- package/dist/runtime/components/Icon/index.d.vue.ts +0 -7
- package/dist/runtime/components/Icon/index.vue.d.ts +0 -7
- package/dist/runtime/components/Link/basic.demo.d.vue.ts +0 -8
- package/dist/runtime/components/Link/basic.demo.vue.d.ts +0 -8
- package/dist/runtime/components/Link/index.d.vue.ts +0 -51
- package/dist/runtime/components/Link/index.vue.d.ts +0 -51
- package/dist/runtime/pages/ui.d.vue.ts +0 -4
- package/dist/runtime/pages/ui.vue.d.ts +0 -4
|
@@ -1,348 +1,442 @@
|
|
|
1
|
-
<script setup>
|
|
2
|
-
import { useHead, useRoute, useRouter } from
|
|
3
|
-
import { computed, nextTick, onMounted, ref, watch } from
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { useHead, useRoute, useRouter } from 'nuxt/app'
|
|
3
|
+
import { computed, nextTick, onMounted, ref, watch } from 'vue'
|
|
4
|
+
|
|
5
|
+
import { uiComponents } from '#brickflow-ui-catalog'
|
|
6
|
+
import { uiThemeEnabled } from '#brickflow-ui-options'
|
|
7
|
+
|
|
8
|
+
import { useTheme } from '../composables/useTheme'
|
|
9
|
+
|
|
10
|
+
useHead({
|
|
11
|
+
meta: [
|
|
12
|
+
{
|
|
13
|
+
content: 'noindex, nofollow, noarchive',
|
|
14
|
+
name: 'robots',
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
title: 'UI playground',
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
const route = useRoute()
|
|
21
|
+
const router = useRouter()
|
|
22
|
+
const expandedDemoCode = ref(new Set<string>())
|
|
23
|
+
const isNavigationOpen = ref(false)
|
|
24
|
+
const mobileNavigation = ref<HTMLElement>()
|
|
25
|
+
const colorSwatchesReady = ref(false)
|
|
26
|
+
const stylesExpanded = ref(false)
|
|
27
|
+
const theme = uiThemeEnabled ? useTheme() : undefined
|
|
28
|
+
const isDark = computed(() => theme?.isDark.value ?? false)
|
|
29
|
+
const toggleTheme = (): void => theme?.toggleTheme()
|
|
30
|
+
|
|
31
|
+
const activeComponent = computed(() => {
|
|
32
|
+
const component = route.query.component
|
|
33
|
+
const id = typeof component === 'string' ? component : undefined
|
|
34
|
+
|
|
35
|
+
return uiComponents.find((item) => item.id === id) ?? uiComponents[0]
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
const visibleStyles = computed(() => {
|
|
39
|
+
const styles = activeComponent.value?.styles ?? []
|
|
40
|
+
|
|
41
|
+
return stylesExpanded.value ? styles : styles.slice(0, 5)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
const getDemoCodeKey = (demoId: string): string => `${activeComponent.value?.id}:${demoId}`
|
|
45
|
+
|
|
46
|
+
const escapeHtml = (value: string): string =>
|
|
47
|
+
value.replace(
|
|
48
|
+
/[&<>"']/g,
|
|
49
|
+
(character) =>
|
|
50
|
+
({
|
|
51
|
+
'"': '"',
|
|
52
|
+
'&': '&',
|
|
53
|
+
"'": ''',
|
|
54
|
+
'<': '<',
|
|
55
|
+
'>': '>',
|
|
56
|
+
})[character] ?? character,
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
const token = (className: string, value: string): string => `<span class="${className}">${value}</span>`
|
|
60
|
+
|
|
61
|
+
const highlightTypeScript = (source: string): string => {
|
|
62
|
+
const pattern =
|
|
63
|
+
/\/\*[\s\S]*?\*\/|\/\/[^\n]*|`(?:\\[\s\S]|[^`])*`|'(?:\\[\s\S]|[^'])*'|"(?:\\[\s\S]|[^"])*"|\b(?:as|async|await|const|export|from|function|import|interface|let|return|type)\b|\b\d+(?:\.\d+)?\b/g
|
|
64
|
+
let html = ''
|
|
65
|
+
let lastIndex = 0
|
|
66
|
+
|
|
67
|
+
for (const match of source.matchAll(pattern)) {
|
|
68
|
+
const index = match.index ?? 0
|
|
69
|
+
const value = match[0]
|
|
70
|
+
html += escapeHtml(source.slice(lastIndex, index))
|
|
71
|
+
|
|
72
|
+
if (value.startsWith('//') || value.startsWith('/*')) {
|
|
73
|
+
html += token('ui-code-comment', escapeHtml(value))
|
|
74
|
+
} else if (value.startsWith("'") || value.startsWith('"') || value.startsWith('`')) {
|
|
75
|
+
html += token('ui-code-string', escapeHtml(value))
|
|
76
|
+
} else if (/^\d/.test(value)) {
|
|
77
|
+
html += token('ui-code-number', value)
|
|
78
|
+
} else {
|
|
79
|
+
html += token('ui-code-keyword', value)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
lastIndex = index + value.length
|
|
63
83
|
}
|
|
64
|
-
|
|
84
|
+
|
|
85
|
+
return html + escapeHtml(source.slice(lastIndex))
|
|
65
86
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
87
|
+
|
|
88
|
+
const highlightPropType = (source: string): string => {
|
|
89
|
+
const pattern =
|
|
90
|
+
/`(?:\\[\s\S]|[^`])*`|'(?:\\[\s\S]|[^'])*'|"(?:\\[\s\S]|[^"])*"|\b(?:any|bigint|boolean|never|null|number|object|string|symbol|undefined|unknown|void)\b|\b[A-Z]\w*\b|\|/g
|
|
91
|
+
let html = ''
|
|
92
|
+
let lastIndex = 0
|
|
93
|
+
|
|
94
|
+
for (const match of source.matchAll(pattern)) {
|
|
95
|
+
const index = match.index ?? 0
|
|
96
|
+
const value = match[0]
|
|
97
|
+
html += escapeHtml(source.slice(lastIndex, index))
|
|
98
|
+
|
|
99
|
+
if (value.startsWith("'") || value.startsWith('"') || value.startsWith('`')) {
|
|
100
|
+
html += token('ui-code-string', escapeHtml(value))
|
|
101
|
+
} else if (value === '|') {
|
|
102
|
+
html += token('ui-code-punctuation', value)
|
|
103
|
+
} else if (/^[A-Z]/.test(value)) {
|
|
104
|
+
html += token('ui-code-tag', escapeHtml(value))
|
|
105
|
+
} else {
|
|
106
|
+
html += token('ui-code-keyword', value)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
lastIndex = index + value.length
|
|
84
110
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return html + escapeHtml(source.slice(lastIndex));
|
|
88
|
-
};
|
|
89
|
-
const highlightTag = (source) => {
|
|
90
|
-
const opening = source.match(/^<(\/)?([\w.-]+)/);
|
|
91
|
-
const closing = source.match(/\/?>\s*$/);
|
|
92
|
-
if (!opening || !closing) {
|
|
93
|
-
return escapeHtml(source);
|
|
94
|
-
}
|
|
95
|
-
const attributes = source.slice(opening[0].length, source.length - closing[0].length);
|
|
96
|
-
let html = token("ui-code-punctuation", "<");
|
|
97
|
-
let attributeIndex = 0;
|
|
98
|
-
if (opening[1]) {
|
|
99
|
-
html += token("ui-code-punctuation", "/");
|
|
111
|
+
|
|
112
|
+
return html + escapeHtml(source.slice(lastIndex))
|
|
100
113
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
const nameStart = attributeIndex;
|
|
110
|
-
while (attributeIndex < attributes.length && !/[\s=]/.test(attributes[attributeIndex] ?? "")) {
|
|
111
|
-
attributeIndex += 1;
|
|
112
|
-
}
|
|
113
|
-
const name = attributes.slice(nameStart, attributeIndex);
|
|
114
|
-
html += token("ui-code-attribute", escapeHtml(name));
|
|
115
|
-
const whitespaceStart = attributeIndex;
|
|
116
|
-
while (/\s/.test(attributes[attributeIndex] ?? "")) {
|
|
117
|
-
attributeIndex += 1;
|
|
118
|
-
}
|
|
119
|
-
html += escapeHtml(attributes.slice(whitespaceStart, attributeIndex));
|
|
120
|
-
if (attributes[attributeIndex] !== "=") {
|
|
121
|
-
continue;
|
|
114
|
+
|
|
115
|
+
const highlightTag = (source: string): string => {
|
|
116
|
+
const opening = source.match(/^<(\/)?([\w.-]+)/)
|
|
117
|
+
const closing = source.match(/\/?>\s*$/)
|
|
118
|
+
|
|
119
|
+
if (!opening || !closing) {
|
|
120
|
+
return escapeHtml(source)
|
|
122
121
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
122
|
+
|
|
123
|
+
const attributes = source.slice(opening[0].length, source.length - closing[0].length)
|
|
124
|
+
let html = token('ui-code-punctuation', '<')
|
|
125
|
+
let attributeIndex = 0
|
|
126
|
+
|
|
127
|
+
if (opening[1]) {
|
|
128
|
+
html += token('ui-code-punctuation', '/')
|
|
128
129
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
attributeIndex
|
|
134
|
-
|
|
135
|
-
|
|
130
|
+
|
|
131
|
+
html += token('ui-code-tag', escapeHtml(opening[2] ?? ''))
|
|
132
|
+
|
|
133
|
+
while (attributeIndex < attributes.length) {
|
|
134
|
+
const character = attributes[attributeIndex] ?? ''
|
|
135
|
+
if (/\s/.test(character)) {
|
|
136
|
+
html += escapeHtml(character)
|
|
137
|
+
attributeIndex += 1
|
|
138
|
+
continue
|
|
136
139
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
while (attributeIndex < attributes.length &&
|
|
140
|
-
attributeIndex += 1
|
|
140
|
+
|
|
141
|
+
const nameStart = attributeIndex
|
|
142
|
+
while (attributeIndex < attributes.length && !/[\s=]/.test(attributes[attributeIndex] ?? '')) {
|
|
143
|
+
attributeIndex += 1
|
|
141
144
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
let html = "";
|
|
150
|
-
let index = 0;
|
|
151
|
-
while (index < source.length) {
|
|
152
|
-
const commentStart = source.indexOf("<!--", index);
|
|
153
|
-
const interpolationStart = source.indexOf("{{", index);
|
|
154
|
-
const tagStart = source.indexOf("<", index);
|
|
155
|
-
const starts = [commentStart, interpolationStart, tagStart].filter((start2) => start2 !== -1);
|
|
156
|
-
const start = Math.min(...starts);
|
|
157
|
-
if (!Number.isFinite(start)) {
|
|
158
|
-
return html + escapeHtml(source.slice(index));
|
|
159
|
-
}
|
|
160
|
-
html += escapeHtml(source.slice(index, start));
|
|
161
|
-
if (start === commentStart) {
|
|
162
|
-
const end = source.indexOf("-->", start + 4);
|
|
163
|
-
if (end === -1) {
|
|
164
|
-
return html + token("ui-code-comment", escapeHtml(source.slice(start)));
|
|
145
|
+
|
|
146
|
+
const name = attributes.slice(nameStart, attributeIndex)
|
|
147
|
+
html += token('ui-code-attribute', escapeHtml(name))
|
|
148
|
+
|
|
149
|
+
const whitespaceStart = attributeIndex
|
|
150
|
+
while (/\s/.test(attributes[attributeIndex] ?? '')) {
|
|
151
|
+
attributeIndex += 1
|
|
165
152
|
}
|
|
166
|
-
html +=
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
if (end === -1) {
|
|
171
|
-
return html + escapeHtml(source.slice(start));
|
|
153
|
+
html += escapeHtml(attributes.slice(whitespaceStart, attributeIndex))
|
|
154
|
+
|
|
155
|
+
if (attributes[attributeIndex] !== '=') {
|
|
156
|
+
continue
|
|
172
157
|
}
|
|
173
|
-
|
|
174
|
-
html +=
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
while (tagEnd < source.length) {
|
|
181
|
-
const character = source[tagEnd] ?? "";
|
|
182
|
-
if (quote) {
|
|
183
|
-
if (character === "\\") {
|
|
184
|
-
tagEnd += 2;
|
|
185
|
-
continue;
|
|
186
|
-
}
|
|
187
|
-
if (character === quote) {
|
|
188
|
-
quote = "";
|
|
189
|
-
}
|
|
190
|
-
} else if (character === '"' || character === "'") {
|
|
191
|
-
quote = character;
|
|
192
|
-
} else if (character === ">") {
|
|
193
|
-
break;
|
|
194
|
-
}
|
|
195
|
-
tagEnd += 1;
|
|
158
|
+
|
|
159
|
+
html += token('ui-code-punctuation', '=')
|
|
160
|
+
attributeIndex += 1
|
|
161
|
+
|
|
162
|
+
const valueWhitespaceStart = attributeIndex
|
|
163
|
+
while (/\s/.test(attributes[attributeIndex] ?? '')) {
|
|
164
|
+
attributeIndex += 1
|
|
196
165
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
166
|
+
html += escapeHtml(attributes.slice(valueWhitespaceStart, attributeIndex))
|
|
167
|
+
|
|
168
|
+
const quote = attributes[attributeIndex]
|
|
169
|
+
const valueStart = attributeIndex
|
|
170
|
+
if (quote === '"' || quote === "'") {
|
|
171
|
+
attributeIndex += 1
|
|
172
|
+
while (attributeIndex < attributes.length && attributes[attributeIndex] !== quote) {
|
|
173
|
+
attributeIndex += attributes[attributeIndex] === '\\' ? 2 : 1
|
|
174
|
+
}
|
|
175
|
+
attributeIndex += 1
|
|
200
176
|
} else {
|
|
201
|
-
|
|
177
|
+
while (attributeIndex < attributes.length && !/\s/.test(attributes[attributeIndex] ?? '')) {
|
|
178
|
+
attributeIndex += 1
|
|
179
|
+
}
|
|
202
180
|
}
|
|
203
|
-
|
|
181
|
+
|
|
182
|
+
html += token('ui-code-string', escapeHtml(attributes.slice(valueStart, attributeIndex)))
|
|
204
183
|
}
|
|
184
|
+
|
|
185
|
+
html += token('ui-code-punctuation', escapeHtml(closing[0]))
|
|
186
|
+
|
|
187
|
+
return html
|
|
205
188
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
189
|
+
|
|
190
|
+
const highlightTemplate = (source: string): string => {
|
|
191
|
+
let html = ''
|
|
192
|
+
let index = 0
|
|
193
|
+
|
|
194
|
+
while (index < source.length) {
|
|
195
|
+
const commentStart = source.indexOf('<!--', index)
|
|
196
|
+
const interpolationStart = source.indexOf('{{', index)
|
|
197
|
+
const tagStart = source.indexOf('<', index)
|
|
198
|
+
const starts = [commentStart, interpolationStart, tagStart].filter((start) => start !== -1)
|
|
199
|
+
const start = Math.min(...starts)
|
|
200
|
+
|
|
201
|
+
if (!Number.isFinite(start)) {
|
|
202
|
+
return html + escapeHtml(source.slice(index))
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
html += escapeHtml(source.slice(index, start))
|
|
206
|
+
|
|
207
|
+
if (start === commentStart) {
|
|
208
|
+
const end = source.indexOf('-->', start + 4)
|
|
209
|
+
if (end === -1) {
|
|
210
|
+
return html + token('ui-code-comment', escapeHtml(source.slice(start)))
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
html += token('ui-code-comment', escapeHtml(source.slice(start, end + 3)))
|
|
214
|
+
index = end + 3
|
|
215
|
+
} else if (start === interpolationStart) {
|
|
216
|
+
const end = source.indexOf('}}', start + 2)
|
|
217
|
+
if (end === -1) {
|
|
218
|
+
return html + escapeHtml(source.slice(start))
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
html += token('ui-code-punctuation', '{{')
|
|
222
|
+
html += highlightTypeScript(source.slice(start + 2, end))
|
|
223
|
+
html += token('ui-code-punctuation', '}}')
|
|
224
|
+
index = end + 2
|
|
225
|
+
} else {
|
|
226
|
+
let tagEnd = start + 1
|
|
227
|
+
let quote = ''
|
|
228
|
+
|
|
229
|
+
while (tagEnd < source.length) {
|
|
230
|
+
const character = source[tagEnd] ?? ''
|
|
231
|
+
if (quote) {
|
|
232
|
+
if (character === '\\') {
|
|
233
|
+
tagEnd += 2
|
|
234
|
+
continue
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (character === quote) {
|
|
238
|
+
quote = ''
|
|
239
|
+
}
|
|
240
|
+
} else if (character === '"' || character === "'") {
|
|
241
|
+
quote = character
|
|
242
|
+
} else if (character === '>') {
|
|
243
|
+
break
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
tagEnd += 1
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const tag = source.slice(start, tagEnd + 1)
|
|
250
|
+
if (/^<\/?[\w.-]/.test(tag)) {
|
|
251
|
+
html += highlightTag(tag)
|
|
252
|
+
} else {
|
|
253
|
+
html += escapeHtml(tag)
|
|
254
|
+
}
|
|
255
|
+
index = tagEnd + 1
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return html
|
|
231
260
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
261
|
+
|
|
262
|
+
const highlightDemoCode = (source: string): string => {
|
|
263
|
+
const scriptPattern = /(<script\b[^>]*>)([\s\S]*?)(<\/script>)/g
|
|
264
|
+
let html = ''
|
|
265
|
+
let lastIndex = 0
|
|
266
|
+
|
|
267
|
+
for (const match of source.matchAll(scriptPattern)) {
|
|
268
|
+
const index = match.index ?? 0
|
|
269
|
+
html += highlightTemplate(source.slice(lastIndex, index))
|
|
270
|
+
html += highlightTag(match[1] ?? '')
|
|
271
|
+
html += highlightTypeScript(match[2] ?? '')
|
|
272
|
+
html += highlightTag(match[3] ?? '')
|
|
273
|
+
lastIndex = index + match[0].length
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return html + highlightTemplate(source.slice(lastIndex))
|
|
240
277
|
}
|
|
241
|
-
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
278
|
+
|
|
279
|
+
const highlightTailwindValue = (value: string): string => {
|
|
280
|
+
const pattern = /\d+(?:\.\d+)?/g
|
|
281
|
+
let html = ''
|
|
282
|
+
let lastIndex = 0
|
|
283
|
+
|
|
284
|
+
for (const match of value.matchAll(pattern)) {
|
|
285
|
+
const index = match.index ?? 0
|
|
286
|
+
html += token('ui-code-string', escapeHtml(value.slice(lastIndex, index)))
|
|
287
|
+
html += token('ui-code-number', match[0])
|
|
288
|
+
lastIndex = index + match[0].length
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return html + token('ui-code-string', escapeHtml(value.slice(lastIndex)))
|
|
246
292
|
}
|
|
247
|
-
|
|
248
|
-
const
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
293
|
+
|
|
294
|
+
const getTailwindColorSwatch = (utility: string): string => {
|
|
295
|
+
const match = utility.match(
|
|
296
|
+
/^(?:accent|bg|border|caret|decoration|divide|fill|from|outline|ring|shadow|stroke|text|to|via)-([a-z][a-z0-9-]*)(?:\/(\d{1,3}))?$/,
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
if (!colorSwatchesReady.value || !match || typeof window === 'undefined') {
|
|
300
|
+
return ''
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const [, name, opacity] = match
|
|
304
|
+
const colorVariable = `--color-${name}`
|
|
305
|
+
const color = getComputedStyle(document.body).getPropertyValue(colorVariable).trim()
|
|
306
|
+
|
|
307
|
+
if (!color || !CSS.supports('color', color)) {
|
|
308
|
+
return ''
|
|
258
309
|
}
|
|
310
|
+
|
|
311
|
+
const opacityValue = opacity && Number(opacity) <= 100 ? Number(opacity) : undefined
|
|
312
|
+
const background = opacityValue
|
|
313
|
+
? `color-mix(in srgb, var(${colorVariable}) ${opacityValue}%, transparent)`
|
|
314
|
+
: `var(${colorVariable})`
|
|
315
|
+
|
|
316
|
+
return `<span aria-hidden="true" class="ui-color-swatch" style="--ui-color-swatch: ${background}"></span>`
|
|
259
317
|
}
|
|
260
|
-
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
|
|
318
|
+
|
|
319
|
+
const highlightTailwindUtility = (utility: string): string => {
|
|
320
|
+
let source = utility
|
|
321
|
+
let html = ''
|
|
322
|
+
|
|
323
|
+
for (const prefix of ['!', '-']) {
|
|
324
|
+
if (source.startsWith(prefix)) {
|
|
325
|
+
html += token('ui-code-punctuation', prefix)
|
|
326
|
+
source = source.slice(prefix.length)
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
html += getTailwindColorSwatch(source)
|
|
331
|
+
|
|
332
|
+
const separatorIndex = source.indexOf('-')
|
|
333
|
+
if (separatorIndex === -1) {
|
|
334
|
+
return html + token('ui-code-attribute', escapeHtml(source))
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
html += token('ui-code-attribute', escapeHtml(source.slice(0, separatorIndex)))
|
|
338
|
+
html += token('ui-code-punctuation', '-')
|
|
339
|
+
|
|
340
|
+
return html + highlightTailwindValue(source.slice(separatorIndex + 1))
|
|
264
341
|
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
342
|
+
|
|
343
|
+
const highlightTailwindClass = (className: string): string => {
|
|
344
|
+
const segments: string[] = []
|
|
345
|
+
let start = 0
|
|
346
|
+
let bracketDepth = 0
|
|
347
|
+
|
|
348
|
+
for (let index = 0; index < className.length; index += 1) {
|
|
349
|
+
const character = className[index]
|
|
350
|
+
|
|
351
|
+
if (character === '[') {
|
|
352
|
+
bracketDepth += 1
|
|
353
|
+
} else if (character === ']') {
|
|
354
|
+
bracketDepth = Math.max(0, bracketDepth - 1)
|
|
355
|
+
} else if (character === ':' && bracketDepth === 0) {
|
|
356
|
+
segments.push(className.slice(start, index))
|
|
357
|
+
start = index + 1
|
|
358
|
+
}
|
|
282
359
|
}
|
|
360
|
+
|
|
361
|
+
const utility = className.slice(start)
|
|
362
|
+
const variants = segments.map(
|
|
363
|
+
(segment) => `${token('ui-code-keyword', escapeHtml(segment))}${token('ui-code-punctuation', ':')}`,
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
return variants.join('') + highlightTailwindUtility(utility)
|
|
283
367
|
}
|
|
284
|
-
|
|
285
|
-
const
|
|
286
|
-
(
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
368
|
+
|
|
369
|
+
const highlightStyleValue = (value: string | undefined): string => {
|
|
370
|
+
if (value === undefined) {
|
|
371
|
+
return token('ui-code-comment', '—')
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
if (value === '') {
|
|
375
|
+
return token('ui-code-string', '""')
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return value
|
|
379
|
+
.split(/(\s+)/)
|
|
380
|
+
.map((part) => (/\s/.test(part) ? escapeHtml(part) : highlightTailwindClass(part)))
|
|
381
|
+
.join('')
|
|
293
382
|
}
|
|
294
|
-
|
|
295
|
-
|
|
383
|
+
|
|
384
|
+
const isDemoCodeExpanded = (demoId: string): boolean => expandedDemoCode.value.has(getDemoCodeKey(demoId))
|
|
385
|
+
|
|
386
|
+
const toggleDemoCode = (demoId: string): void => {
|
|
387
|
+
const key = getDemoCodeKey(demoId)
|
|
388
|
+
const next = new Set(expandedDemoCode.value)
|
|
389
|
+
|
|
390
|
+
next.has(key) ? next.delete(key) : next.add(key)
|
|
391
|
+
expandedDemoCode.value = next
|
|
296
392
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
const toggleDemoCode = (demoId) => {
|
|
301
|
-
const key = getDemoCodeKey(demoId);
|
|
302
|
-
const next = new Set(expandedDemoCode.value);
|
|
303
|
-
next.has(key) ? next.delete(key) : next.add(key);
|
|
304
|
-
expandedDemoCode.value = next;
|
|
305
|
-
};
|
|
306
|
-
const closeNavigation = () => {
|
|
307
|
-
isNavigationOpen.value = false;
|
|
308
|
-
};
|
|
309
|
-
onMounted(() => {
|
|
310
|
-
colorSwatchesReady.value = true;
|
|
311
|
-
});
|
|
312
|
-
watch(isNavigationOpen, async (isOpen) => {
|
|
313
|
-
if (isOpen) {
|
|
314
|
-
await nextTick();
|
|
315
|
-
mobileNavigation.value?.focus();
|
|
393
|
+
|
|
394
|
+
const closeNavigation = (): void => {
|
|
395
|
+
isNavigationOpen.value = false
|
|
316
396
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
if (
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
const firstComponent = uiComponents[0];
|
|
327
|
-
if (!firstComponent) {
|
|
328
|
-
return;
|
|
397
|
+
|
|
398
|
+
onMounted(() => {
|
|
399
|
+
colorSwatchesReady.value = true
|
|
400
|
+
})
|
|
401
|
+
|
|
402
|
+
watch(isNavigationOpen, async (isOpen) => {
|
|
403
|
+
if (isOpen) {
|
|
404
|
+
await nextTick()
|
|
405
|
+
mobileNavigation.value?.focus()
|
|
329
406
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
407
|
+
})
|
|
408
|
+
|
|
409
|
+
watch(
|
|
410
|
+
() => route.query.component,
|
|
411
|
+
(component) => {
|
|
412
|
+
closeNavigation()
|
|
413
|
+
window.scrollTo({ behavior: 'smooth', top: 0 })
|
|
414
|
+
if (typeof component === 'string' && uiComponents.some((item) => item.id === component)) {
|
|
415
|
+
return
|
|
335
416
|
}
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
417
|
+
|
|
418
|
+
const firstComponent = uiComponents[0]
|
|
419
|
+
if (!firstComponent) {
|
|
420
|
+
return
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
router.replace({
|
|
424
|
+
path: '/ui',
|
|
425
|
+
query: {
|
|
426
|
+
...route.query,
|
|
427
|
+
component: firstComponent.id,
|
|
428
|
+
},
|
|
429
|
+
})
|
|
430
|
+
},
|
|
431
|
+
{ immediate: true },
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
watch(
|
|
435
|
+
() => activeComponent.value?.id,
|
|
436
|
+
() => {
|
|
437
|
+
stylesExpanded.value = false
|
|
438
|
+
},
|
|
439
|
+
)
|
|
346
440
|
</script>
|
|
347
441
|
|
|
348
442
|
<template>
|
|
@@ -423,18 +517,20 @@ watch(
|
|
|
423
517
|
<NuxtLink
|
|
424
518
|
v-for="component in uiComponents"
|
|
425
519
|
:key="component.id"
|
|
426
|
-
:aria-current="activeComponent?.id === component.id ? 'page' :
|
|
520
|
+
:aria-current="activeComponent?.id === component.id ? 'page' : undefined"
|
|
427
521
|
:class="[
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
522
|
+
'block rounded-lg px-3 py-2.5 text-sm font-semibold tracking-wide transition',
|
|
523
|
+
activeComponent?.id === component.id
|
|
524
|
+
? 'bg-blue-900 text-blue-100'
|
|
525
|
+
: 'text-zinc-400 hover:bg-zinc-900 hover:text-zinc-100',
|
|
526
|
+
]"
|
|
431
527
|
:to="{
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
}"
|
|
528
|
+
path: '/ui',
|
|
529
|
+
query: {
|
|
530
|
+
...route.query,
|
|
531
|
+
component: component.id,
|
|
532
|
+
},
|
|
533
|
+
}"
|
|
438
534
|
@click="closeNavigation"
|
|
439
535
|
>
|
|
440
536
|
{{ component.name }}
|
|
@@ -454,18 +550,20 @@ watch(
|
|
|
454
550
|
<NuxtLink
|
|
455
551
|
v-for="component in uiComponents"
|
|
456
552
|
:key="component.id"
|
|
457
|
-
:aria-current="activeComponent?.id === component.id ? 'page' :
|
|
553
|
+
:aria-current="activeComponent?.id === component.id ? 'page' : undefined"
|
|
458
554
|
:class="[
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
555
|
+
'block rounded-lg px-3 py-2 text-sm font-semibold tracking-wide transition',
|
|
556
|
+
activeComponent?.id === component.id
|
|
557
|
+
? 'bg-blue-900 text-blue-100'
|
|
558
|
+
: 'text-zinc-400 hover:bg-zinc-900 hover:text-zinc-100',
|
|
559
|
+
]"
|
|
462
560
|
:to="{
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
}"
|
|
561
|
+
path: '/ui',
|
|
562
|
+
query: {
|
|
563
|
+
...route.query,
|
|
564
|
+
component: component.id,
|
|
565
|
+
},
|
|
566
|
+
}"
|
|
469
567
|
>
|
|
470
568
|
{{ component.name }}
|
|
471
569
|
</NuxtLink>
|
|
@@ -540,9 +638,11 @@ watch(
|
|
|
540
638
|
type="button"
|
|
541
639
|
:aria-label="isDemoCodeExpanded(demo.id) ? 'Hide code' : 'View code'"
|
|
542
640
|
:class="[
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
641
|
+
'flex size-6 shrink-0 cursor-pointer items-center justify-center rounded-md border transition focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-400',
|
|
642
|
+
isDemoCodeExpanded(demo.id)
|
|
643
|
+
? 'border-blue-700 bg-blue-900 text-blue-200'
|
|
644
|
+
: 'border-zinc-700 text-zinc-400 hover:border-blue-700 hover:text-blue-200',
|
|
645
|
+
]"
|
|
546
646
|
:title="isDemoCodeExpanded(demo.id) ? 'Hide code' : 'View code'"
|
|
547
647
|
@click="toggleDemoCode(demo.id)"
|
|
548
648
|
>
|
|
@@ -562,7 +662,7 @@ watch(
|
|
|
562
662
|
</svg>
|
|
563
663
|
</button>
|
|
564
664
|
</header>
|
|
565
|
-
<div class="p-8 mb:p-4">
|
|
665
|
+
<div class="overflow-auto p-8 mb:p-4">
|
|
566
666
|
<component :is="demo.component" />
|
|
567
667
|
</div>
|
|
568
668
|
<div
|
|
@@ -615,7 +715,7 @@ watch(
|
|
|
615
715
|
class="py-3 text-right text-xs"
|
|
616
716
|
:class="prop.required ? 'text-red-600' : 'text-zinc-500'"
|
|
617
717
|
>
|
|
618
|
-
{{ prop.required ?
|
|
718
|
+
{{ prop.required ? '*' : '-' }}
|
|
619
719
|
</td>
|
|
620
720
|
</tr>
|
|
621
721
|
<tr v-if="activeComponent.props.length === 0">
|
|
@@ -700,7 +800,7 @@ watch(
|
|
|
700
800
|
class="flex w-full cursor-pointer items-center justify-center text-sm font-medium text-cyan-500 transition hover:text-cyan-400 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-cyan-400"
|
|
701
801
|
@click="stylesExpanded = !stylesExpanded"
|
|
702
802
|
>
|
|
703
|
-
{{ stylesExpanded ?
|
|
803
|
+
{{ stylesExpanded ? 'Collapse styles' : `Show all ${activeComponent.styles.length} styles` }}
|
|
704
804
|
</button>
|
|
705
805
|
</footer>
|
|
706
806
|
</section>
|
|
@@ -721,10 +821,77 @@ watch(
|
|
|
721
821
|
</main>
|
|
722
822
|
</template>
|
|
723
823
|
|
|
724
|
-
<style src="../ui-page.css">
|
|
725
|
-
|
|
726
|
-
</style>
|
|
824
|
+
<style src="../ui-page.css"></style>
|
|
727
825
|
|
|
728
826
|
<style module>
|
|
729
|
-
:global(.ui-code-comment)
|
|
827
|
+
:global(.ui-code-comment) {
|
|
828
|
+
color: var(--color-zinc-500, #71717a);
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
:global(.ui-code-string) {
|
|
832
|
+
color: var(--color-emerald-400, #34d399);
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
:global(.ui-code-keyword) {
|
|
836
|
+
color: var(--color-blue-400, #60a5fa);
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
:global(.ui-code-number) {
|
|
840
|
+
color: var(--color-amber-300, #fcd34d);
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
:global(.ui-code-tag) {
|
|
844
|
+
color: var(--color-cyan-500, #22d3ee);
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
:global(.ui-code-attribute) {
|
|
848
|
+
color: var(--color-violet-300, #c4b5fd);
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
:global(.ui-code-punctuation) {
|
|
852
|
+
color: var(--color-zinc-400, #a1a1aa);
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
:global(.ui-color-swatch) {
|
|
856
|
+
display: inline-block;
|
|
857
|
+
width: 0.65rem;
|
|
858
|
+
height: 0.65rem;
|
|
859
|
+
margin-right: 0.25rem;
|
|
860
|
+
vertical-align: -0.1rem;
|
|
861
|
+
border: 1px solid rgb(255 255 255 / 10%);
|
|
862
|
+
border-radius: 0.2rem;
|
|
863
|
+
background: var(--ui-color-swatch);
|
|
864
|
+
opacity: 0.85;
|
|
865
|
+
/* box-shadow: inset 0 0 0 1px rgb(0 0 0 / 10%); */
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
.mobileNavigation {
|
|
869
|
+
width: min(18rem, calc(100vw - 3rem));
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
@media (width >= 40rem) {
|
|
873
|
+
.styleGrid {
|
|
874
|
+
grid-template-columns: minmax(12rem, 0.8fr) minmax(0, 1.8fr);
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
.styleValue :global(.ui-code-keyword) {
|
|
879
|
+
color: var(--color-zinc-500, #71717a);
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
.styleValue :global(.ui-code-attribute) {
|
|
883
|
+
color: var(--color-zinc-200, #e4e4e7);
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
.styleValue :global(.ui-code-string) {
|
|
887
|
+
color: var(--color-zinc-300, #d4d4d8);
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
.styleValue :global(.ui-code-number) {
|
|
891
|
+
color: var(--color-zinc-400, #a1a1aa);
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
.styleValue :global(.ui-code-punctuation) {
|
|
895
|
+
color: var(--color-zinc-500, #71717a);
|
|
896
|
+
}
|
|
730
897
|
</style>
|