@studiocms/ui 0.3.2 → 0.4.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/dist/components/Accordion/Accordion.astro +23 -0
- package/dist/components/Accordion/Item.astro +21 -0
- package/dist/components/Accordion/accordion.css +64 -0
- package/dist/components/Accordion/accordion.d.ts +1 -0
- package/dist/components/Accordion/accordion.js +70 -0
- package/dist/components/Badge/Badge.astro +49 -0
- package/dist/components/Badge/badge.css +111 -0
- package/dist/components/Breadcrumbs/Breadcrumbs.astro +31 -0
- package/dist/components/Breadcrumbs/breadcrumbs.css +15 -0
- package/dist/components/Button/Button.astro +75 -0
- package/dist/components/Button/button.css +292 -0
- package/{src/components → dist/components/Card}/Card.astro +1 -48
- package/dist/components/Card/card.css +38 -0
- package/dist/components/Center/Center.astro +7 -0
- package/dist/components/Center/center.css +8 -0
- package/dist/components/Checkbox/Checkbox.astro +95 -0
- package/dist/components/Checkbox/checkbox.css +119 -0
- package/dist/components/Checkbox/checkbox.d.ts +2 -0
- package/dist/components/Checkbox/checkbox.js +20 -0
- package/{src/components → dist/components/Divider}/Divider.astro +2 -25
- package/dist/components/Divider/divider.css +21 -0
- package/dist/components/Dropdown/Dropdown.astro +116 -0
- package/dist/components/Dropdown/dropdown.css +180 -0
- package/dist/components/Dropdown/dropdown.d.ts +48 -0
- package/dist/components/Dropdown/dropdown.js +201 -0
- package/dist/components/Footer/Footer.astro +58 -0
- package/dist/components/Footer/footer.css +68 -0
- package/dist/components/Group/Group.astro +7 -0
- package/dist/components/Group/group.css +19 -0
- package/{src/utils → dist/components/Icon}/Icon.astro +1 -1
- package/{src/utils/iconType.ts → dist/components/Icon/iconType.d.ts} +0 -1
- package/dist/components/Icon/iconType.js +0 -0
- package/{src/components → dist/components/Input}/Input.astro +2 -48
- package/dist/components/Input/input.css +38 -0
- package/{src → dist}/components/Modal/Modal.astro +4 -122
- package/dist/components/Modal/modal.css +100 -0
- package/dist/components/Modal/modal.d.ts +48 -0
- package/dist/components/Modal/modal.js +129 -0
- package/dist/components/Progress/Progress.astro +21 -0
- package/dist/components/Progress/helper.d.ts +13 -0
- package/dist/components/Progress/helper.js +32 -0
- package/dist/components/Progress/progress.css +29 -0
- package/dist/components/Progress/progress.d.ts +1 -0
- package/dist/components/Progress/progress.js +10 -0
- package/dist/components/RadioGroup/RadioGroup.astro +124 -0
- package/dist/components/RadioGroup/radiogroup.css +96 -0
- package/dist/components/RadioGroup/radiogroup.d.ts +1 -0
- package/dist/components/RadioGroup/radiogroup.js +48 -0
- package/{src/components → dist/components/Row}/Row.astro +1 -24
- package/dist/components/Row/row.css +18 -0
- package/dist/components/SearchSelect/SearchSelect.astro +135 -0
- package/dist/components/SearchSelect/searchselect.css +95 -0
- package/dist/components/SearchSelect/searchselect.d.ts +6 -0
- package/dist/components/SearchSelect/searchselect.js +166 -0
- package/dist/components/Select/Select.astro +147 -0
- package/dist/components/Select/select.css +110 -0
- package/dist/components/Select/select.d.ts +1 -0
- package/dist/components/Select/select.js +143 -0
- package/dist/components/Sidebar/helpers.d.ts +76 -0
- package/dist/components/Sidebar/helpers.js +160 -0
- package/{src → dist}/components/Tabs/TabItem.astro +3 -3
- package/dist/components/Tabs/Tabs.astro +150 -0
- package/dist/components/Tabs/tabs.css +121 -0
- package/dist/components/Tabs/tabs.d.ts +1 -0
- package/dist/components/Tabs/tabs.js +82 -0
- package/{src/components → dist/components/Textarea}/Textarea.astro +2 -61
- package/dist/components/Textarea/textarea.css +49 -0
- package/dist/components/ThemeToggle/ThemeToggle.astro +21 -0
- package/dist/components/ThemeToggle/themetoggle.css +17 -0
- package/dist/components/ThemeToggle/themetoggle.d.ts +1 -0
- package/dist/components/ThemeToggle/themetoggle.js +4 -0
- package/dist/components/Toast/Toaster.astro +69 -0
- package/dist/components/Toast/toast.d.ts +8 -0
- package/dist/components/Toast/toast.js +9 -0
- package/dist/components/Toast/toaster.css +168 -0
- package/dist/components/Toast/toaster.d.ts +1 -0
- package/dist/components/Toast/toaster.js +160 -0
- package/dist/components/Toggle/Toggle.astro +84 -0
- package/dist/components/Toggle/toggle.css +93 -0
- package/dist/components/Toggle/toggle.d.ts +2 -0
- package/dist/components/Toggle/toggle.js +20 -0
- package/{src/components → dist/components/User}/User.astro +3 -43
- package/dist/components/User/user.css +35 -0
- package/dist/css/colors.css +95 -0
- package/dist/css/global.css +3 -0
- package/dist/css/radii.css +6 -0
- package/dist/css/resets.css +46 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +379 -0
- package/dist/toolbar/ColorPicker.d.ts +7 -0
- package/dist/toolbar/ColorPicker.js +85 -0
- package/dist/toolbar/icon.d.ts +1 -0
- package/dist/toolbar/icon.js +4 -0
- package/dist/toolbar/index.d.ts +2 -0
- package/dist/toolbar/index.js +292 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/index.js +0 -0
- package/dist/utils/ThemeHelper.d.ts +49 -0
- package/dist/utils/ThemeHelper.js +113 -0
- package/{src/utils/colors.ts → dist/utils/colors.d.ts} +1 -1
- package/dist/utils/colors.js +0 -0
- package/dist/utils/generateID.d.ts +2 -0
- package/dist/utils/generateID.js +6 -0
- package/dist/utils/headers.d.ts +43 -0
- package/dist/utils/headers.js +129 -0
- package/dist/utils/iconStrings.d.ts +4 -0
- package/dist/utils/iconStrings.js +13 -0
- package/dist/utils/integration-utils.d.ts +130 -0
- package/dist/utils/integration-utils.js +161 -0
- package/package.json +25 -9
- package/src/components/BaseHead.astro +0 -22
- package/src/components/Button.astro +0 -372
- package/src/components/Center.astro +0 -16
- package/src/components/Checkbox.astro +0 -250
- package/src/components/Dropdown/Dropdown.astro +0 -314
- package/src/components/Dropdown/dropdown.ts +0 -258
- package/src/components/Dropdown/index.ts +0 -2
- package/src/components/Footer.astro +0 -137
- package/src/components/Modal/index.ts +0 -2
- package/src/components/Modal/modal.ts +0 -163
- package/src/components/RadioGroup.astro +0 -299
- package/src/components/SearchSelect.astro +0 -486
- package/src/components/Select.astro +0 -467
- package/src/components/Sidebar/helpers.ts +0 -179
- package/src/components/Sidebar/index.ts +0 -3
- package/src/components/Tabs/Tabs.astro +0 -393
- package/src/components/Tabs/index.ts +0 -2
- package/src/components/ThemeToggle.astro +0 -46
- package/src/components/Toast/Toaster.astro +0 -470
- package/src/components/Toast/index.ts +0 -2
- package/src/components/Toast/toast.ts +0 -16
- package/src/components/Toggle.astro +0 -214
- package/src/components/index.ts +0 -27
- package/src/components.ts +0 -26
- package/src/css/colors.css +0 -106
- package/src/css/global.css +0 -2
- package/src/css/resets.css +0 -54
- package/src/env.d.ts +0 -15
- package/src/integration.ts +0 -31
- package/src/layouts/RootLayout.astro +0 -33
- package/src/layouts/index.ts +0 -2
- package/src/layouts.ts +0 -1
- package/src/types/index.ts +0 -11
- package/src/utils/ThemeHelper.ts +0 -145
- package/src/utils/create-resolver.ts +0 -30
- package/src/utils/generateID.ts +0 -5
- package/src/utils/headers.ts +0 -190
- package/src/utils/iconStrings.ts +0 -29
- package/src/utils/index.ts +0 -1
- package/src/utils/virtual-module-plugin-builder.ts +0 -37
- /package/{src → dist}/components/Sidebar/Double.astro +0 -0
- /package/{src → dist}/components/Sidebar/Single.astro +0 -0
- /package/{src → dist}/icons/Checkmark.astro +0 -0
- /package/{src → dist}/icons/ChevronUpDown.astro +0 -0
- /package/{src → dist}/icons/User.astro +0 -0
- /package/{src → dist}/icons/X-Mark.astro +0 -0
|
File without changes
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import type { HTMLAttributes } from 'astro/types';
|
|
3
|
-
import { generateID } from '
|
|
3
|
+
import { generateID } from '../../utils/generateID.js';
|
|
4
|
+
import './input.css';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* The props for the input component.
|
|
@@ -72,50 +73,3 @@ const {
|
|
|
72
73
|
{...props}
|
|
73
74
|
/>
|
|
74
75
|
</label>
|
|
75
|
-
<style>
|
|
76
|
-
.sui-input-label {
|
|
77
|
-
width: 100%;
|
|
78
|
-
display: flex;
|
|
79
|
-
flex-direction: column;
|
|
80
|
-
gap: .25rem;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
.sui-input-label.disabled {
|
|
84
|
-
opacity: 0.5;
|
|
85
|
-
pointer-events: none;
|
|
86
|
-
color: hsl(var(--text-muted));
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
.label {
|
|
90
|
-
font-size: 14px;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
.sui-input {
|
|
94
|
-
padding: .5rem 1rem;
|
|
95
|
-
border-radius: 8px;
|
|
96
|
-
border: 1px solid hsl(var(--border));
|
|
97
|
-
background: hsl(var(--background-step-2));
|
|
98
|
-
color: hsl(var(--text-normal));
|
|
99
|
-
transition: all .15s ease;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
.sui-input:hover {
|
|
103
|
-
background: hsl(var(--background-step-3));
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
.sui-input:active,
|
|
107
|
-
.sui-input:focus {
|
|
108
|
-
border: 1px solid hsl(var(--primary-base));
|
|
109
|
-
outline: none;
|
|
110
|
-
background: hsl(var(--background-step-2));
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.disabled .sui-input:active {
|
|
114
|
-
border: 1px solid hsl(var(--border));
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
.req-star {
|
|
118
|
-
color: hsl(var(--danger-base));
|
|
119
|
-
font-weight: 700;
|
|
120
|
-
}
|
|
121
|
-
</style>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
.sui-input-label {
|
|
2
|
+
width: 100%;
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
gap: .25rem;
|
|
6
|
+
}
|
|
7
|
+
.sui-input-label.disabled {
|
|
8
|
+
opacity: 0.5;
|
|
9
|
+
pointer-events: none;
|
|
10
|
+
color: hsl(var(--text-muted));
|
|
11
|
+
}
|
|
12
|
+
.label {
|
|
13
|
+
font-size: 14px;
|
|
14
|
+
}
|
|
15
|
+
.sui-input {
|
|
16
|
+
padding: .5rem 1rem;
|
|
17
|
+
border-radius: var(--radius-md);
|
|
18
|
+
border: 1px solid hsl(var(--border));
|
|
19
|
+
background: hsl(var(--background-step-2));
|
|
20
|
+
color: hsl(var(--text-normal));
|
|
21
|
+
transition: all .15s ease;
|
|
22
|
+
}
|
|
23
|
+
.sui-input:hover {
|
|
24
|
+
background: hsl(var(--background-step-3));
|
|
25
|
+
}
|
|
26
|
+
.sui-input:active,
|
|
27
|
+
.sui-input:focus {
|
|
28
|
+
border: 1px solid hsl(var(--primary-base));
|
|
29
|
+
outline: none;
|
|
30
|
+
background: hsl(var(--background-step-2));
|
|
31
|
+
}
|
|
32
|
+
.disabled .sui-input:active {
|
|
33
|
+
border: 1px solid hsl(var(--border));
|
|
34
|
+
}
|
|
35
|
+
.req-star {
|
|
36
|
+
color: hsl(var(--danger-base));
|
|
37
|
+
font-weight: 700;
|
|
38
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
|
-
import type { StudioCMSColorway } from '
|
|
3
|
-
import
|
|
4
|
-
import
|
|
2
|
+
import type { StudioCMSColorway } from '../../utils/colors.js';
|
|
3
|
+
import Button from '../Button/Button.astro';
|
|
4
|
+
import Icon from '../Icon/Icon.astro';
|
|
5
|
+
import './modal.css';
|
|
5
6
|
|
|
6
7
|
interface ButtonType {
|
|
7
8
|
label: string;
|
|
@@ -97,122 +98,3 @@ const {
|
|
|
97
98
|
</div>
|
|
98
99
|
</form>
|
|
99
100
|
</dialog>
|
|
100
|
-
<style>
|
|
101
|
-
.sui-modal {
|
|
102
|
-
border: 1px solid hsl(var(--border));
|
|
103
|
-
border-radius: .5rem;
|
|
104
|
-
padding: 1.5rem;
|
|
105
|
-
box-shadow: 0px 6px 8px hsl(var(--shadow));
|
|
106
|
-
animation: hide .25s ease;
|
|
107
|
-
overflow: visible;
|
|
108
|
-
margin: auto;
|
|
109
|
-
z-index: 50;
|
|
110
|
-
max-width: calc(100% - 4rem);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.sui-modal.sm {
|
|
114
|
-
width: 384px;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
.sui-modal.md {
|
|
118
|
-
width: 448px;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
.sui-modal.lg {
|
|
122
|
-
width: 608px;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
.sui-modal[open] {
|
|
126
|
-
animation: show .25s ease-in-out;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
html:has(.sui-modal[open]),
|
|
130
|
-
body:has(.sui-modal[open]) {
|
|
131
|
-
overflow: hidden;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
.sui-modal[open]::backdrop {
|
|
135
|
-
background-color: rgba(0, 0, 0, 0.75);
|
|
136
|
-
animation: backdrop .3s ease-in-out forwards;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
.sui-modal-header:has(*) {
|
|
140
|
-
margin-bottom: 1rem;
|
|
141
|
-
|
|
142
|
-
display: flex;
|
|
143
|
-
flex-direction: row;
|
|
144
|
-
justify-content: space-between;
|
|
145
|
-
gap: 1rem;
|
|
146
|
-
|
|
147
|
-
* {
|
|
148
|
-
margin: 0;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
.x-mark-container {
|
|
153
|
-
cursor: pointer;
|
|
154
|
-
height: 1.5rem;
|
|
155
|
-
width: 1.5rem;
|
|
156
|
-
display: flex;
|
|
157
|
-
align-items: center;
|
|
158
|
-
justify-content: center;
|
|
159
|
-
transition: background-color .15s ease;
|
|
160
|
-
border-radius: .25rem;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
.x-mark-container:hover {
|
|
164
|
-
background-color: hsl(var(--default-base));
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
.x-mark-container:focus-visible {
|
|
168
|
-
outline: 2px solid hsl(var(--text-normal));
|
|
169
|
-
outline-offset: 2px;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
.sui-modal-footer {
|
|
173
|
-
display: none;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
.sui-modal-footer:has(*) {
|
|
177
|
-
display: flex;
|
|
178
|
-
flex-direction: row;
|
|
179
|
-
gap: 1rem;
|
|
180
|
-
margin-top: 1rem;
|
|
181
|
-
justify-content: end;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
@keyframes hide {
|
|
185
|
-
0% {
|
|
186
|
-
scale: 1;
|
|
187
|
-
opacity: 1;
|
|
188
|
-
display: block;
|
|
189
|
-
}
|
|
190
|
-
100% {
|
|
191
|
-
scale: 0.85;
|
|
192
|
-
opacity: 0;
|
|
193
|
-
display: none;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
@keyframes show {
|
|
198
|
-
0% {
|
|
199
|
-
scale: 0.85;
|
|
200
|
-
opacity: 0;
|
|
201
|
-
display: none;
|
|
202
|
-
}
|
|
203
|
-
100% {
|
|
204
|
-
scale: 1;
|
|
205
|
-
opacity: 1;
|
|
206
|
-
display: block;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
@keyframes backdrop {
|
|
211
|
-
0% {
|
|
212
|
-
opacity: 0;
|
|
213
|
-
}
|
|
214
|
-
100% {
|
|
215
|
-
opacity: 1;
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
</style>
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
.sui-modal {
|
|
2
|
+
border: 1px solid hsl(var(--border));
|
|
3
|
+
border-radius: var(--radius-md);
|
|
4
|
+
padding: 1.5rem;
|
|
5
|
+
box-shadow: 0px 6px 8px hsl(var(--shadow));
|
|
6
|
+
animation: hide .25s ease;
|
|
7
|
+
overflow: visible;
|
|
8
|
+
margin: auto;
|
|
9
|
+
z-index: 50;
|
|
10
|
+
max-width: calc(100% - 4rem);
|
|
11
|
+
}
|
|
12
|
+
.sui-modal.sm {
|
|
13
|
+
width: 384px;
|
|
14
|
+
}
|
|
15
|
+
.sui-modal.md {
|
|
16
|
+
width: 448px;
|
|
17
|
+
}
|
|
18
|
+
.sui-modal.lg {
|
|
19
|
+
width: 608px;
|
|
20
|
+
}
|
|
21
|
+
.sui-modal[open] {
|
|
22
|
+
animation: show .25s ease-in-out;
|
|
23
|
+
}
|
|
24
|
+
html:has(.sui-modal[open]),
|
|
25
|
+
body:has(.sui-modal[open]) {
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
}
|
|
28
|
+
.sui-modal[open]::backdrop {
|
|
29
|
+
background-color: rgba(0, 0, 0, 0.75);
|
|
30
|
+
animation: backdrop .3s ease-in-out forwards;
|
|
31
|
+
}
|
|
32
|
+
.sui-modal-header:has(*) {
|
|
33
|
+
margin-bottom: 1rem;
|
|
34
|
+
display: flex;
|
|
35
|
+
flex-direction: row;
|
|
36
|
+
justify-content: space-between;
|
|
37
|
+
gap: 1rem;
|
|
38
|
+
* {
|
|
39
|
+
margin: 0;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
.x-mark-container {
|
|
43
|
+
cursor: pointer;
|
|
44
|
+
height: 1.5rem;
|
|
45
|
+
width: 1.5rem;
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
justify-content: center;
|
|
49
|
+
transition: background-color .15s ease;
|
|
50
|
+
border-radius: var(--radius-sm);
|
|
51
|
+
}
|
|
52
|
+
.x-mark-container:hover {
|
|
53
|
+
background-color: hsl(var(--default-base));
|
|
54
|
+
}
|
|
55
|
+
.x-mark-container:focus-visible {
|
|
56
|
+
outline: 2px solid hsl(var(--text-normal));
|
|
57
|
+
outline-offset: 2px;
|
|
58
|
+
}
|
|
59
|
+
.sui-modal-footer {
|
|
60
|
+
display: none;
|
|
61
|
+
}
|
|
62
|
+
.sui-modal-footer:has(*) {
|
|
63
|
+
display: flex;
|
|
64
|
+
flex-direction: row;
|
|
65
|
+
gap: 1rem;
|
|
66
|
+
margin-top: 1rem;
|
|
67
|
+
justify-content: end;
|
|
68
|
+
}
|
|
69
|
+
@keyframes hide {
|
|
70
|
+
0% {
|
|
71
|
+
scale: 1;
|
|
72
|
+
opacity: 1;
|
|
73
|
+
display: block;
|
|
74
|
+
}
|
|
75
|
+
100% {
|
|
76
|
+
scale: 0.85;
|
|
77
|
+
opacity: 0;
|
|
78
|
+
display: none;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
@keyframes show {
|
|
82
|
+
0% {
|
|
83
|
+
scale: 0.85;
|
|
84
|
+
opacity: 0;
|
|
85
|
+
display: none;
|
|
86
|
+
}
|
|
87
|
+
100% {
|
|
88
|
+
scale: 1;
|
|
89
|
+
opacity: 1;
|
|
90
|
+
display: block;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
@keyframes backdrop {
|
|
94
|
+
0% {
|
|
95
|
+
opacity: 0;
|
|
96
|
+
}
|
|
97
|
+
100% {
|
|
98
|
+
opacity: 1;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
declare class ModalHelper {
|
|
2
|
+
private element;
|
|
3
|
+
private cancelButton;
|
|
4
|
+
private confirmButton;
|
|
5
|
+
private isForm;
|
|
6
|
+
private modalForm;
|
|
7
|
+
/**
|
|
8
|
+
* A helper to manage modals.
|
|
9
|
+
* @param id The ID of the modal.
|
|
10
|
+
* @param triggerID The ID of the element that should trigger the modal.
|
|
11
|
+
*/
|
|
12
|
+
constructor(id: string, triggerID?: string);
|
|
13
|
+
/**
|
|
14
|
+
* A helper function which adds event listeners to the modal buttons to close the modal when clicked.
|
|
15
|
+
* @param id The ID of the modal.
|
|
16
|
+
* @param dismissable Whether the modal is dismissable.
|
|
17
|
+
*/
|
|
18
|
+
private addButtonListeners;
|
|
19
|
+
/**
|
|
20
|
+
* A helper function to close the modal when the user clicks outside of it.
|
|
21
|
+
*/
|
|
22
|
+
private addDismissiveClickListener;
|
|
23
|
+
/**
|
|
24
|
+
* A function to show the modal.
|
|
25
|
+
*/
|
|
26
|
+
show: () => void;
|
|
27
|
+
/**
|
|
28
|
+
* A function to hide the modal.
|
|
29
|
+
*/
|
|
30
|
+
hide: () => void;
|
|
31
|
+
/**
|
|
32
|
+
* A function to add another trigger to show the modal with.
|
|
33
|
+
* @param elementID The ID of the element that should trigger the modal when clicked.
|
|
34
|
+
*/
|
|
35
|
+
bindTrigger: (elementID: string) => void;
|
|
36
|
+
/**
|
|
37
|
+
* Registers a callback for the cancel button.
|
|
38
|
+
* @param func The callback function.
|
|
39
|
+
*/
|
|
40
|
+
registerCancelCallback: (func: () => void) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Registers a callback for the confirm button.
|
|
43
|
+
* @param func The callback function. If the modal is a form, the function will be called with
|
|
44
|
+
* the form data as the first argument.
|
|
45
|
+
*/
|
|
46
|
+
registerConfirmCallback: (func: (data?: FormData | undefined) => void) => void;
|
|
47
|
+
}
|
|
48
|
+
export { ModalHelper };
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
class ModalHelper {
|
|
2
|
+
element;
|
|
3
|
+
cancelButton;
|
|
4
|
+
confirmButton;
|
|
5
|
+
isForm = false;
|
|
6
|
+
modalForm;
|
|
7
|
+
/**
|
|
8
|
+
* A helper to manage modals.
|
|
9
|
+
* @param id The ID of the modal.
|
|
10
|
+
* @param triggerID The ID of the element that should trigger the modal.
|
|
11
|
+
*/
|
|
12
|
+
constructor(id, triggerID) {
|
|
13
|
+
const element = document.getElementById(id);
|
|
14
|
+
if (!element) {
|
|
15
|
+
throw new Error(`No modal with ID ${id} found.`);
|
|
16
|
+
}
|
|
17
|
+
this.element = element;
|
|
18
|
+
this.modalForm = document.getElementById(`${id}-form-element`);
|
|
19
|
+
const isDismissable = this.element.dataset.dismissable === "true";
|
|
20
|
+
const isForm = this.element.dataset.form === "true";
|
|
21
|
+
if (isDismissable) {
|
|
22
|
+
this.addDismissiveClickListener();
|
|
23
|
+
}
|
|
24
|
+
if (isForm) this.isForm = true;
|
|
25
|
+
this.addButtonListeners(id, isDismissable);
|
|
26
|
+
if (triggerID) {
|
|
27
|
+
this.bindTrigger(triggerID);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A helper function which adds event listeners to the modal buttons to close the modal when clicked.
|
|
32
|
+
* @param id The ID of the modal.
|
|
33
|
+
* @param dismissable Whether the modal is dismissable.
|
|
34
|
+
*/
|
|
35
|
+
addButtonListeners = (id, dismissable) => {
|
|
36
|
+
if (dismissable || !this.element.dataset.hasCancelButton && !this.element.dataset.hasActionButton) {
|
|
37
|
+
const xMarkButton = document.getElementById(`${id}-btn-x`);
|
|
38
|
+
xMarkButton.addEventListener("click", this.hide);
|
|
39
|
+
}
|
|
40
|
+
if (!!this.element.dataset.hasCancelButton && !this.element.dataset.hasActionButton) return;
|
|
41
|
+
if (this.element.dataset.hasCancelButton) {
|
|
42
|
+
this.cancelButton = document.getElementById(`${id}-btn-cancel`);
|
|
43
|
+
this.cancelButton.addEventListener("click", this.hide);
|
|
44
|
+
}
|
|
45
|
+
if (this.element.dataset.hasActionButton) {
|
|
46
|
+
this.confirmButton = document.getElementById(`${id}-btn-confirm`);
|
|
47
|
+
this.confirmButton.addEventListener("click", this.hide);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* A helper function to close the modal when the user clicks outside of it.
|
|
52
|
+
*/
|
|
53
|
+
addDismissiveClickListener = () => {
|
|
54
|
+
this.element.addEventListener("click", (e) => {
|
|
55
|
+
if (!e.target) return;
|
|
56
|
+
const { left, right, top, bottom } = this.element.getBoundingClientRect();
|
|
57
|
+
const clickWithinModalBox = e.clientX < right && e.clientX > left && e.clientY < bottom && e.clientY > top;
|
|
58
|
+
if (!clickWithinModalBox) {
|
|
59
|
+
this.element.close();
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* A function to show the modal.
|
|
65
|
+
*/
|
|
66
|
+
show = () => {
|
|
67
|
+
this.element.showModal();
|
|
68
|
+
this.element.focus();
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* A function to hide the modal.
|
|
72
|
+
*/
|
|
73
|
+
hide = () => {
|
|
74
|
+
this.element.close();
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* A function to add another trigger to show the modal with.
|
|
78
|
+
* @param elementID The ID of the element that should trigger the modal when clicked.
|
|
79
|
+
*/
|
|
80
|
+
bindTrigger = (elementID) => {
|
|
81
|
+
const element = document.getElementById(elementID);
|
|
82
|
+
if (!element) {
|
|
83
|
+
throw new Error(`No element with ID ${elementID} found.`);
|
|
84
|
+
}
|
|
85
|
+
element.addEventListener("click", this.show);
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Registers a callback for the cancel button.
|
|
89
|
+
* @param func The callback function.
|
|
90
|
+
*/
|
|
91
|
+
registerCancelCallback = (func) => {
|
|
92
|
+
if (!this.cancelButton) {
|
|
93
|
+
throw new Error("Unable to register cancel callback without a cancel button.");
|
|
94
|
+
}
|
|
95
|
+
this.cancelButton.removeEventListener("click", this.hide);
|
|
96
|
+
this.cancelButton.addEventListener("click", () => {
|
|
97
|
+
func();
|
|
98
|
+
this.hide();
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Registers a callback for the confirm button.
|
|
103
|
+
* @param func The callback function. If the modal is a form, the function will be called with
|
|
104
|
+
* the form data as the first argument.
|
|
105
|
+
*/
|
|
106
|
+
registerConfirmCallback = (func) => {
|
|
107
|
+
if (!this.confirmButton) {
|
|
108
|
+
throw new Error("Unable to register cancel callback without a confirmation button.");
|
|
109
|
+
}
|
|
110
|
+
this.confirmButton.removeEventListener("click", this.hide);
|
|
111
|
+
if (this.isForm) {
|
|
112
|
+
this.modalForm.addEventListener("submit", (e) => {
|
|
113
|
+
e.preventDefault();
|
|
114
|
+
const formData = new FormData(this.modalForm);
|
|
115
|
+
func(formData);
|
|
116
|
+
this.hide();
|
|
117
|
+
setTimeout(() => this.modalForm.reset(), 450);
|
|
118
|
+
});
|
|
119
|
+
} else {
|
|
120
|
+
this.confirmButton.addEventListener("click", () => {
|
|
121
|
+
func();
|
|
122
|
+
this.hide();
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
export {
|
|
128
|
+
ModalHelper
|
|
129
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { StudioCMSColorway } from '../../utils/colors.js';
|
|
3
|
+
import './progress.css';
|
|
4
|
+
import type { HTMLAttributes } from 'astro/types';
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
id: string;
|
|
8
|
+
value?: number;
|
|
9
|
+
max?: number;
|
|
10
|
+
color?: Omit<StudioCMSColorway, 'default'>;
|
|
11
|
+
} & HTMLAttributes<'div'>;
|
|
12
|
+
|
|
13
|
+
const { id, value = 0, max = 100, color = 'primary' } = Astro.props;
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
<div class="sui-progress" class:list={[color]} role="progressbar" id={id} data-max={max} data-value={value}>
|
|
17
|
+
<div class="sui-progress-slider" />
|
|
18
|
+
</div>
|
|
19
|
+
<script>
|
|
20
|
+
import 'studiocms:ui/scripts/progress';
|
|
21
|
+
</script>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
declare class ProgressHelper {
|
|
2
|
+
private bar;
|
|
3
|
+
private progress;
|
|
4
|
+
private value;
|
|
5
|
+
private max;
|
|
6
|
+
constructor(id: string);
|
|
7
|
+
getValue(): number;
|
|
8
|
+
setValue(value: number): void;
|
|
9
|
+
getMax(): number;
|
|
10
|
+
setMax(value: number): void;
|
|
11
|
+
getPercentage(): number;
|
|
12
|
+
}
|
|
13
|
+
export { ProgressHelper };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
class ProgressHelper {
|
|
2
|
+
bar;
|
|
3
|
+
progress;
|
|
4
|
+
value;
|
|
5
|
+
max;
|
|
6
|
+
constructor(id) {
|
|
7
|
+
this.bar = document.getElementById(id);
|
|
8
|
+
this.progress = this.bar.firstElementChild;
|
|
9
|
+
this.value = this.getValue();
|
|
10
|
+
this.max = this.getMax();
|
|
11
|
+
}
|
|
12
|
+
getValue() {
|
|
13
|
+
return Number.parseInt(this.bar.dataset.value, 10);
|
|
14
|
+
}
|
|
15
|
+
setValue(value) {
|
|
16
|
+
const max = Number.parseInt(this.bar.dataset.max, 10);
|
|
17
|
+
const percent = Math.round(value / max * 100);
|
|
18
|
+
this.progress.style.width = `${percent}%`;
|
|
19
|
+
}
|
|
20
|
+
getMax() {
|
|
21
|
+
return Number.parseInt(this.bar.dataset.max, 10);
|
|
22
|
+
}
|
|
23
|
+
setMax(value) {
|
|
24
|
+
this.bar.dataset.max = value.toString();
|
|
25
|
+
}
|
|
26
|
+
getPercentage() {
|
|
27
|
+
return Math.round(this.value / this.max * 100);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
ProgressHelper
|
|
32
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
.sui-progress {
|
|
2
|
+
width: 100%;
|
|
3
|
+
height: 1rem;
|
|
4
|
+
border: 1px solid hsl(var(--border));
|
|
5
|
+
border-radius: var(--radius-sm);
|
|
6
|
+
overflow: hidden;
|
|
7
|
+
}
|
|
8
|
+
.sui-progress-slider {
|
|
9
|
+
height: 100%;
|
|
10
|
+
width: 0;
|
|
11
|
+
transition: all .75s ease;
|
|
12
|
+
border-radius: var(--radius-sm);
|
|
13
|
+
background-color: hsl(var(--primary-base));
|
|
14
|
+
}
|
|
15
|
+
.sui-progress.success .sui-progress-slider {
|
|
16
|
+
background-color: hsl(var(--success-base));
|
|
17
|
+
}
|
|
18
|
+
.sui-progress.warning .sui-progress-slider {
|
|
19
|
+
background-color: hsl(var(--warning-base));
|
|
20
|
+
}
|
|
21
|
+
.sui-progress.danger .sui-progress-slider {
|
|
22
|
+
background-color: hsl(var(--danger-base));
|
|
23
|
+
}
|
|
24
|
+
.sui-progress.info .sui-progress-slider {
|
|
25
|
+
background-color: hsl(var(--info-base));
|
|
26
|
+
}
|
|
27
|
+
.sui-progress.monochrome .sui-progress-slider {
|
|
28
|
+
background-color: hsl(var(--mono-base));
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare const allBars: NodeListOf<HTMLDivElement>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const allBars = document.querySelectorAll(".sui-progress");
|
|
2
|
+
for (const bar of allBars) {
|
|
3
|
+
const value = bar.dataset.value;
|
|
4
|
+
const max = bar.dataset.max;
|
|
5
|
+
const progress = bar.firstElementChild;
|
|
6
|
+
if (value && max) {
|
|
7
|
+
const percent = Math.round(Number.parseInt(value, 10) / Number.parseInt(max, 10) * 100);
|
|
8
|
+
progress.style.width = `${percent}%`;
|
|
9
|
+
}
|
|
10
|
+
}
|