lexgui 0.5.2 → 0.5.3
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/build/components/audio.js +7 -7
- package/build/components/timeline.js +2 -2
- package/build/lexgui.css +387 -519
- package/build/lexgui.js +141 -102
- package/build/lexgui.min.css +4 -3
- package/build/lexgui.min.js +1 -1
- package/build/lexgui.module.js +141 -102
- package/build/lexgui.module.min.js +1 -1
- package/build/utilities.css +215 -0
- package/changelog.md +15 -1
- package/demo.js +94 -39
- package/examples/all_widgets.html +368 -0
- package/examples/area_tabs.html +94 -86
- package/examples/asset_view.html +183 -180
- package/examples/code_editor.html +62 -61
- package/examples/dialogs.html +97 -94
- package/examples/immediate_ui.html +44 -42
- package/examples/index.html +4 -7
- package/examples/node_graph.html +39 -36
- package/examples/previews/all_widgets.png +0 -0
- package/examples/side_bar.html +93 -90
- package/examples/timeline.html +4 -4
- package/examples/video_editor.html +38 -35
- package/examples/video_editor2.html +84 -79
- package/package.json +1 -1
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/* Colors */
|
|
2
|
+
/* Using !important to override anything written in main stylesheet */
|
|
3
|
+
|
|
4
|
+
.bg-primary { background-color: var(--global-color-primary) !important }
|
|
5
|
+
.bg-secondary { background-color: var(--global-color-secondary) !important }
|
|
6
|
+
.bg-tertiary { background-color: var(--global-color-tertiary) !important }
|
|
7
|
+
.bg-quaternary { background-color: var(--global-color-quaternary) !important }
|
|
8
|
+
.bg-accent { background-color: var(--global-color-accent) !important }
|
|
9
|
+
.bg-contrast { background-color: var(--global-text-primary) !important }
|
|
10
|
+
.bg-warning { background-color: var(--global-color-warning) !important }
|
|
11
|
+
.bg-error { background-color: var(--global-color-error) !important }
|
|
12
|
+
.bg-none { background: none !important }
|
|
13
|
+
|
|
14
|
+
.fg-primary { color: var(--global-text-primary) !important }
|
|
15
|
+
.fg-secondary { color: var(--global-text-secondary) !important }
|
|
16
|
+
.fg-tertiary { color: var(--global-text-tertiary) !important }
|
|
17
|
+
.fg-quaternary { color: var(--global-text-quaternary) !important }
|
|
18
|
+
.fg-accent { color: var(--global-text-accent) !important }
|
|
19
|
+
.fg-contrast { color: var(--global-text-primary) !important }
|
|
20
|
+
.fg-warning { color: var(--global-text-warning) !important }
|
|
21
|
+
.fg-error { color: var(--global-text-error) !important }
|
|
22
|
+
|
|
23
|
+
/* Layout */
|
|
24
|
+
|
|
25
|
+
.flex { display: flex }
|
|
26
|
+
.inline-flex { display: inline-flex }
|
|
27
|
+
.grid { display: grid }
|
|
28
|
+
.block { display: block }
|
|
29
|
+
.inline-block { display: inline-block }
|
|
30
|
+
.hidden { display: none !important }
|
|
31
|
+
|
|
32
|
+
.flex-col { flex-direction: column }
|
|
33
|
+
.flex-row { flex-direction: row }
|
|
34
|
+
.flex-wrap { flex-wrap: wrap }
|
|
35
|
+
|
|
36
|
+
.items-center { align-items: center }
|
|
37
|
+
.items-start { align-items: flex-start }
|
|
38
|
+
.items-end { align-items: flex-end }
|
|
39
|
+
|
|
40
|
+
.justify-start { justify-content: start }
|
|
41
|
+
.justify-center { justify-content: center }
|
|
42
|
+
.justify-end { justify-content: end }
|
|
43
|
+
.justify-between { justify-content: space-between }
|
|
44
|
+
.justify-around { justify-content: space-around }
|
|
45
|
+
|
|
46
|
+
.self-center { align-self: center }
|
|
47
|
+
|
|
48
|
+
.gap-1 { gap: 0.25rem }
|
|
49
|
+
.gap-2 { gap: 0.5rem }
|
|
50
|
+
.gap-3 { gap: 0.75rem }
|
|
51
|
+
.gap-4 { gap: 1rem }
|
|
52
|
+
.gap-5 { gap: 1.25rem }
|
|
53
|
+
.gap-6 { gap: 1.5rem }
|
|
54
|
+
.gap-7 { gap: 1.75rem }
|
|
55
|
+
.gap-8 { gap: 2rem }
|
|
56
|
+
|
|
57
|
+
/* Spacing */
|
|
58
|
+
|
|
59
|
+
.mt-auto { margin-top: auto }
|
|
60
|
+
.mb-auto { margin-bottom: auto }
|
|
61
|
+
.ml-auto { margin-left: auto }
|
|
62
|
+
.mr-auto { margin-right: auto }
|
|
63
|
+
|
|
64
|
+
.m-0 { margin: 0 }
|
|
65
|
+
.m-1 { margin: 0.25rem }
|
|
66
|
+
.m-2 { margin: 0.5rem }
|
|
67
|
+
.m-3 { margin: 0.75rem }
|
|
68
|
+
.m-4 { margin: 1rem }
|
|
69
|
+
.m-5 { margin: 1.25rem }
|
|
70
|
+
.m-6 { margin: 1.5rem }
|
|
71
|
+
.m-7 { margin: 1.75rem }
|
|
72
|
+
.m-8 { margin: 2rem }
|
|
73
|
+
|
|
74
|
+
.mt-2 { margin-top: 0.5rem }
|
|
75
|
+
.mb-2 { margin-bottom: 0.5rem }
|
|
76
|
+
.ml-2 { margin-left: 0.5rem }
|
|
77
|
+
.mr-2 { margin-right: 0.5rem }
|
|
78
|
+
|
|
79
|
+
.p-0 { padding: 0 }
|
|
80
|
+
.p-1 { padding: 0.25rem }
|
|
81
|
+
.p-2 { padding: 0.5rem }
|
|
82
|
+
.p-3 { padding: 0.75rem }
|
|
83
|
+
.p-4 { padding: 1rem }
|
|
84
|
+
.p-5 { padding: 1.25rem }
|
|
85
|
+
.p-6 { padding: 1.5rem }
|
|
86
|
+
.p-7 { padding: 1.75rem }
|
|
87
|
+
.p-8 { padding: 2rem }
|
|
88
|
+
|
|
89
|
+
.pt-0 { padding-top: 0 }
|
|
90
|
+
.pt-1 { padding-top: 0.25rem }
|
|
91
|
+
.pt-2 { padding-top: 0.5rem }
|
|
92
|
+
.pt-3 { padding-top: 0.75rem }
|
|
93
|
+
.pt-4 { padding-top: 1rem }
|
|
94
|
+
.pt-5 { padding-top: 1.25rem }
|
|
95
|
+
.pt-6 { padding-top: 1.5rem }
|
|
96
|
+
.pt-7 { padding-top: 1.75rem }
|
|
97
|
+
.pt-8 { padding-top: 2rem }
|
|
98
|
+
|
|
99
|
+
.pb-0 { padding-bottom: 0 }
|
|
100
|
+
.pb-1 { padding-bottom: 0.25rem }
|
|
101
|
+
.pb-2 { padding-bottom: 0.5rem }
|
|
102
|
+
.pb-3 { padding-bottom: 0.75rem }
|
|
103
|
+
.pb-4 { padding-bottom: 1rem }
|
|
104
|
+
.pb-5 { padding-bottom: 1.25rem }
|
|
105
|
+
.pb-6 { padding-bottom: 1.5rem }
|
|
106
|
+
.pb-7 { padding-bottom: 1.75rem }
|
|
107
|
+
.pb-8 { padding-bottom: 2rem }
|
|
108
|
+
|
|
109
|
+
.pl-0 { padding-left: 0 }
|
|
110
|
+
.pl-1 { padding-left: 0.25rem }
|
|
111
|
+
.pl-2 { padding-left: 0.75rem }
|
|
112
|
+
.pl-3 { padding-left: 0.5rem }
|
|
113
|
+
.pl-4 { padding-left: 1rem }
|
|
114
|
+
.pl-5 { padding-left: 1.25rem }
|
|
115
|
+
.pl-6 { padding-left: 1.5rem }
|
|
116
|
+
.pl-7 { padding-left: 1.75rem }
|
|
117
|
+
.pl-8 { padding-left: 2rem }
|
|
118
|
+
|
|
119
|
+
.pr-0 { padding-right: 0 }
|
|
120
|
+
.pr-1 { padding-right: 0.25rem }
|
|
121
|
+
.pr-2 { padding-right: 0.5rem }
|
|
122
|
+
.pr-3 { padding-right: 0.75rem }
|
|
123
|
+
.pr-4 { padding-right: 1rem }
|
|
124
|
+
.pr-5 { padding-right: 1.25rem }
|
|
125
|
+
.pr-6 { padding-right: 1.5rem }
|
|
126
|
+
.pr-7 { padding-right: 1.75rem }
|
|
127
|
+
.pr-8 { padding-right: 2rem }
|
|
128
|
+
|
|
129
|
+
.px-0 { padding-left: 0; padding-right: 0 }
|
|
130
|
+
.px-1 { padding-left: 0.25rem; padding-right: 0.25rem }
|
|
131
|
+
.px-2 { padding-left: 0.5rem; padding-right: 0.5rem }
|
|
132
|
+
.px-3 { padding-left: 0.75rem; padding-right: 0.75rem }
|
|
133
|
+
.px-4 { padding-left: 1rem; padding-right: 1rem }
|
|
134
|
+
.px-5 { padding-left: 1.25rem; padding-right: 1.25rem }
|
|
135
|
+
.px-6 { padding-left: 1.5rem; padding-right: 1.5rem }
|
|
136
|
+
.px-7 { padding-left: 1.75rem; padding-right: 1.75rem }
|
|
137
|
+
.px-8 { padding-left: 2rem; padding-right: 2rem }
|
|
138
|
+
|
|
139
|
+
.py-0 { padding-top: 0; padding-bottom: 0 }
|
|
140
|
+
.py-1 { padding-top: 0.25rem; padding-bottom: 0.25rem }
|
|
141
|
+
.py-2 { padding-top: 0.5rem; padding-bottom: 0.5rem }
|
|
142
|
+
.py-3 { padding-top: 0.75rem; padding-bottom: 0.75rem }
|
|
143
|
+
.py-4 { padding-top: 1rem; padding-bottom: 1rem }
|
|
144
|
+
.py-5 { padding-top: 1.25rem; padding-bottom: 1.25rem }
|
|
145
|
+
.py-6 { padding-top: 1.5rem; padding-bottom: 1.5rem }
|
|
146
|
+
.py-7 { padding-top: 1.75rem; padding-bottom: 1.75rem }
|
|
147
|
+
.py-8 { padding-top: 2rem; padding-bottom: 2rem }
|
|
148
|
+
|
|
149
|
+
/* Typography */
|
|
150
|
+
|
|
151
|
+
.font-light { font-weight: 300 }
|
|
152
|
+
.font-normal { font-weight: 400 }
|
|
153
|
+
.font-medium { font-weight: 500 }
|
|
154
|
+
.font-semibold { font-weight: 600 }
|
|
155
|
+
.font-bold { font-weight: 700 }
|
|
156
|
+
.font-extrabold { font-weight: 800 }
|
|
157
|
+
|
|
158
|
+
.italic { font-style: italic }
|
|
159
|
+
|
|
160
|
+
.uppercase { text-transform: uppercase }
|
|
161
|
+
.capitalize { text-transform: capitalize }
|
|
162
|
+
|
|
163
|
+
/* Width / Height */
|
|
164
|
+
|
|
165
|
+
.w-full { width: 100% }
|
|
166
|
+
.w-screen { width: 100vw }
|
|
167
|
+
.h-full { height: 100% }
|
|
168
|
+
.h-screen { height: 100vh }
|
|
169
|
+
|
|
170
|
+
/* Positioning */
|
|
171
|
+
|
|
172
|
+
.relative { position: relative }
|
|
173
|
+
.absolute { position: absolute }
|
|
174
|
+
.fixed { position: fixed }
|
|
175
|
+
.sticky { position: sticky }
|
|
176
|
+
|
|
177
|
+
.top-0 { top: 0 }
|
|
178
|
+
.right-0 { right: 0 }
|
|
179
|
+
.bottom-0 { bottom: 0 }
|
|
180
|
+
.left-0 { left: 0 }
|
|
181
|
+
|
|
182
|
+
.z-0 { z-index: 0 }
|
|
183
|
+
.z-10 { z-index: 10 }
|
|
184
|
+
.z-50 { z-index: 50 }
|
|
185
|
+
.z-100 { z-index: 100 }
|
|
186
|
+
.z-1000 { z-index: 1000 }
|
|
187
|
+
|
|
188
|
+
/* Borders / Radius / Shadow */
|
|
189
|
+
|
|
190
|
+
.border { border: 1px solid var(--global-color-tertiary) }
|
|
191
|
+
.border-2 { border-width: 2px }
|
|
192
|
+
|
|
193
|
+
.rounded-none { border-radius: 0 }
|
|
194
|
+
.rounded { border-radius: 0.25rem }
|
|
195
|
+
.rounded-lg { border-radius: 0.5rem }
|
|
196
|
+
.rounded-full { border-radius: 9999px }
|
|
197
|
+
|
|
198
|
+
.shadow { box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) }
|
|
199
|
+
.shadow-md { box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1) }
|
|
200
|
+
.shadow-lg { box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1) }
|
|
201
|
+
|
|
202
|
+
/* Interaction / Misc */
|
|
203
|
+
|
|
204
|
+
.cursor-pointer { cursor: pointer }
|
|
205
|
+
.pointer-events-none { pointer-events: none }
|
|
206
|
+
.pointer-events-auto { pointer-events: auto }
|
|
207
|
+
|
|
208
|
+
.select-none { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none }
|
|
209
|
+
|
|
210
|
+
.opacity-0 { opacity: 0 }
|
|
211
|
+
.opacity-50 { opacity: 0.5 }
|
|
212
|
+
.opacity-100 { opacity: 1 }
|
|
213
|
+
|
|
214
|
+
.ease-in { transition-timing-function: ease-in }
|
|
215
|
+
.ease-out { transition-timing-function: ease-out }
|
package/changelog.md
CHANGED
|
@@ -2,7 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
## dev
|
|
4
4
|
|
|
5
|
-
## 0.5.
|
|
5
|
+
## 0.5.3 (master)
|
|
6
|
+
|
|
7
|
+
Widgets:
|
|
8
|
+
- Fixed Select Widget filter issues.
|
|
9
|
+
- Fixed Color Widget not updating hex code on pasting value.
|
|
10
|
+
|
|
11
|
+
`Panel.endLine` now accepts `className` as first param to allow more customization.
|
|
12
|
+
Remove `gap` by default in inline widgets container.
|
|
13
|
+
Changed global font family to Geist Sans.
|
|
14
|
+
Started support for tailwind-like utility css classes.
|
|
15
|
+
Fixed Select Widget inside Dialog when opening above selector.
|
|
16
|
+
Improve styling for supported widgets. Better consistency.
|
|
17
|
+
Added new demo example showcasing all widgets.
|
|
18
|
+
|
|
19
|
+
## 0.5.2
|
|
6
20
|
|
|
7
21
|
Table Widget:
|
|
8
22
|
- Fixed manual-sort not modifying inner data.
|
package/demo.js
CHANGED
|
@@ -15,9 +15,10 @@ let area = LX.init( { strictViewport: false } );
|
|
|
15
15
|
|
|
16
16
|
m.add( "Docs", { icon: "fa-solid fa-magnifying-glass", short: "F1", callback: () => { window.open("./docs/") }});
|
|
17
17
|
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
const commandButton = new LX.Button(null, "Search command...", () => { LX.setCommandbarState( true ) }, {
|
|
19
|
+
width: "256px", className: "right", buttonClass: "outline left fg-tertiary bg-secondary" }
|
|
20
|
+
);
|
|
21
|
+
m.root.appendChild( commandButton.root );
|
|
21
22
|
|
|
22
23
|
m.addButtons( [
|
|
23
24
|
{
|
|
@@ -39,17 +40,13 @@ let area = LX.init( { strictViewport: false } );
|
|
|
39
40
|
|
|
40
41
|
// Header
|
|
41
42
|
{
|
|
42
|
-
const header = LX.makeContainer( [ null, "auto" ], "col"
|
|
43
|
-
border: "1px solid rgba(255, 255, 255, 0.08)",
|
|
44
|
-
padding: "36px 24px 36px 24px",
|
|
45
|
-
gap: "8px"
|
|
46
|
-
} );
|
|
43
|
+
const header = LX.makeContainer( [ null, "auto" ], "col border gap-2 p-8" );
|
|
47
44
|
|
|
48
45
|
header.innerHTML = `
|
|
49
46
|
<a>Get started with LexGUI.js</a>
|
|
50
47
|
<h1>Build your application interface</h1>
|
|
51
|
-
<p style="max-width:
|
|
52
|
-
|
|
48
|
+
<p style="max-width:32rem">A set of beautifully-designed, accessible widgets and components.
|
|
49
|
+
No complex frameworks. Pure JavaScript and CSS. Open Source.</p>
|
|
53
50
|
`;
|
|
54
51
|
|
|
55
52
|
area.attach( header );
|
|
@@ -57,59 +54,117 @@ let area = LX.init( { strictViewport: false } );
|
|
|
57
54
|
|
|
58
55
|
// Content
|
|
59
56
|
{
|
|
60
|
-
area.
|
|
57
|
+
const tabs = area.addTabs( { sizes: [ "auto", "auto" ], contentClass: "p-6 pt-0" } );
|
|
58
|
+
tabs.root.parentElement.classList.add( "p-4" );
|
|
61
59
|
|
|
62
|
-
|
|
60
|
+
// Mail
|
|
61
|
+
{
|
|
62
|
+
const mailContainer = LX.makeContainer( [ null, "auto" ], "col bg-primary border rounded-lg p-6" );
|
|
63
|
+
tabs.add( "Mail", mailContainer, { selected: true } );
|
|
64
|
+
}
|
|
63
65
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
// Tasks
|
|
67
|
+
{
|
|
68
|
+
const tasksContainer = LX.makeContainer( [ null, "auto" ], "col bg-primary border rounded-lg p-6" );
|
|
69
|
+
tabs.add( "Tasks", tasksContainer, { xselected: true } );
|
|
67
70
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
+
const header = LX.makeContainer( [ null, "auto" ], "col rounded-lg p-6" );
|
|
72
|
+
header.innerHTML = `
|
|
73
|
+
<h2>Welcome back!</h2>
|
|
74
|
+
<p class="fg-tertiary">Here's a list of your tasks for this month!</p>
|
|
75
|
+
`;
|
|
76
|
+
tasksContainer.appendChild( header );
|
|
71
77
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
78
|
+
const tableWidget = new LX.Table(null, {
|
|
79
|
+
head: ["Name", "Status", "Priority"],
|
|
80
|
+
body: [
|
|
81
|
+
["Alice", "In Progress", "High"],
|
|
82
|
+
["Bob", "Backlog", "Medium"],
|
|
83
|
+
["Prince", "Canceled", "Low"],
|
|
84
|
+
["Sean", "Done", "High"],
|
|
85
|
+
["Carter", "In Progress", "Medium"],
|
|
86
|
+
["James", "Backlog", "Low"],
|
|
87
|
+
["Mickey", "Todo", "Low"],
|
|
88
|
+
["Charlie", "Canceled", "Low"],
|
|
89
|
+
["Potato", "Todo", "High"]
|
|
90
|
+
]
|
|
91
|
+
}, {
|
|
92
|
+
selectable: true,
|
|
93
|
+
sortable: true,
|
|
94
|
+
toggleColumns: true,
|
|
95
|
+
filter: "Name",
|
|
96
|
+
customFilters: [
|
|
97
|
+
{ name: "Status", options: ["Backlog", "Todo", "In Progress", "Done", "Cancelled"] },
|
|
98
|
+
{ name: "Priority", options: ["Low", "Medium", "High"] },
|
|
99
|
+
],
|
|
100
|
+
rowActions: [
|
|
101
|
+
{ icon: "edit", title: "Edit Row" },
|
|
102
|
+
"delete",
|
|
103
|
+
"menu"
|
|
104
|
+
],
|
|
105
|
+
onMenuAction: (index, tableData) => {
|
|
106
|
+
return [
|
|
107
|
+
{ name: "Export" },
|
|
108
|
+
{ name: "Make a copy" },
|
|
109
|
+
{ name: "Favourite" }
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
tasksContainer.appendChild( tableWidget.root );
|
|
114
|
+
}
|
|
75
115
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
116
|
+
// Code
|
|
117
|
+
{
|
|
118
|
+
const codeContainer = LX.makeContainer( [ "auto", "850px" ], "", {
|
|
119
|
+
backgroundColor: "red"
|
|
120
|
+
} );
|
|
121
|
+
|
|
122
|
+
tabs.add( "Code", codeContainer );
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Audio
|
|
126
|
+
{
|
|
127
|
+
const audioContainer = LX.makeContainer( [ "auto", "850px" ], "", {
|
|
128
|
+
backgroundColor: "red"
|
|
129
|
+
} );
|
|
130
|
+
|
|
131
|
+
tabs.add( "Audio", audioContainer );
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Examples
|
|
135
|
+
{
|
|
136
|
+
const examplesContainer = LX.makeContainer( [ "auto", "850px" ], "", {
|
|
137
|
+
backgroundColor: "red"
|
|
138
|
+
} );
|
|
79
139
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
tabs.add( "Code", codeContainer );
|
|
83
|
-
tabs.add( "Audio", audioContainer );
|
|
140
|
+
tabs.add( "Examples", examplesContainer );
|
|
141
|
+
}
|
|
84
142
|
}
|
|
85
143
|
|
|
86
144
|
// Footer
|
|
87
145
|
{
|
|
88
146
|
const footer = new LX.Footer( {
|
|
89
|
-
parent:
|
|
147
|
+
parent: LX.root,
|
|
90
148
|
columns: [
|
|
91
149
|
{
|
|
92
150
|
title: "LexGUI",
|
|
93
151
|
items: [
|
|
94
|
-
{ title: "
|
|
95
|
-
{ title: "
|
|
96
|
-
{ title: "Web demo", link: "" },
|
|
97
|
-
{ title: "Source code", link: "" }
|
|
152
|
+
{ title: "Documentation", link: "https://jxarco.github.io/lexgui.js/docs/" },
|
|
153
|
+
{ title: "Source code", link: "https://github.com/jxarco/lexgui.js/" }
|
|
98
154
|
]
|
|
99
155
|
},
|
|
100
156
|
{
|
|
101
157
|
title: "Projects",
|
|
102
158
|
items: [
|
|
103
|
-
{ title: "Animics", link: "" },
|
|
104
|
-
{ title: "Performs", link: "" }
|
|
159
|
+
{ title: "Animics", link: "https://animics.gti.upf.edu/" },
|
|
160
|
+
{ title: "Performs", link: "https://performs.gti.upf.edu/" }
|
|
105
161
|
]
|
|
106
162
|
},
|
|
107
163
|
{
|
|
108
|
-
title: "
|
|
164
|
+
title: "References",
|
|
109
165
|
items: [
|
|
110
|
-
{ title: "
|
|
111
|
-
{ title: "
|
|
112
|
-
{ title: "No more ideas", link: "" },
|
|
166
|
+
{ title: "shadcn/ui", link: "https://ui.shadcn.com/" },
|
|
167
|
+
{ title: "Radix UI", link: "https://www.radix-ui.com/" },
|
|
113
168
|
]
|
|
114
169
|
}
|
|
115
170
|
],
|