@studiocms/ui 0.3.1 → 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.
Files changed (157) hide show
  1. package/dist/components/Accordion/Accordion.astro +23 -0
  2. package/dist/components/Accordion/Item.astro +21 -0
  3. package/dist/components/Accordion/accordion.css +64 -0
  4. package/dist/components/Accordion/accordion.d.ts +1 -0
  5. package/dist/components/Accordion/accordion.js +70 -0
  6. package/dist/components/Badge/Badge.astro +49 -0
  7. package/dist/components/Badge/badge.css +111 -0
  8. package/dist/components/Breadcrumbs/Breadcrumbs.astro +31 -0
  9. package/dist/components/Breadcrumbs/breadcrumbs.css +15 -0
  10. package/dist/components/Button/Button.astro +75 -0
  11. package/dist/components/Button/button.css +292 -0
  12. package/{src/components → dist/components/Card}/Card.astro +1 -48
  13. package/dist/components/Card/card.css +38 -0
  14. package/dist/components/Center/Center.astro +7 -0
  15. package/dist/components/Center/center.css +8 -0
  16. package/dist/components/Checkbox/Checkbox.astro +95 -0
  17. package/dist/components/Checkbox/checkbox.css +119 -0
  18. package/dist/components/Checkbox/checkbox.d.ts +2 -0
  19. package/dist/components/Checkbox/checkbox.js +20 -0
  20. package/dist/components/Divider/Divider.astro +26 -0
  21. package/dist/components/Divider/divider.css +21 -0
  22. package/dist/components/Dropdown/Dropdown.astro +116 -0
  23. package/dist/components/Dropdown/dropdown.css +180 -0
  24. package/dist/components/Dropdown/dropdown.d.ts +48 -0
  25. package/dist/components/Dropdown/dropdown.js +201 -0
  26. package/dist/components/Footer/Footer.astro +58 -0
  27. package/dist/components/Footer/footer.css +68 -0
  28. package/dist/components/Group/Group.astro +7 -0
  29. package/dist/components/Group/group.css +19 -0
  30. package/{src/utils → dist/components/Icon}/Icon.astro +1 -1
  31. package/{src/utils/iconType.ts → dist/components/Icon/iconType.d.ts} +0 -1
  32. package/dist/components/Icon/iconType.js +0 -0
  33. package/{src/components → dist/components/Input}/Input.astro +2 -48
  34. package/dist/components/Input/input.css +38 -0
  35. package/{src → dist}/components/Modal/Modal.astro +4 -122
  36. package/dist/components/Modal/modal.css +100 -0
  37. package/dist/components/Modal/modal.d.ts +48 -0
  38. package/dist/components/Modal/modal.js +129 -0
  39. package/dist/components/Progress/Progress.astro +21 -0
  40. package/dist/components/Progress/helper.d.ts +13 -0
  41. package/dist/components/Progress/helper.js +32 -0
  42. package/dist/components/Progress/progress.css +29 -0
  43. package/dist/components/Progress/progress.d.ts +1 -0
  44. package/dist/components/Progress/progress.js +10 -0
  45. package/dist/components/RadioGroup/RadioGroup.astro +124 -0
  46. package/dist/components/RadioGroup/radiogroup.css +96 -0
  47. package/dist/components/RadioGroup/radiogroup.d.ts +1 -0
  48. package/dist/components/RadioGroup/radiogroup.js +48 -0
  49. package/{src/components → dist/components/Row}/Row.astro +1 -24
  50. package/dist/components/Row/row.css +18 -0
  51. package/dist/components/SearchSelect/SearchSelect.astro +135 -0
  52. package/dist/components/SearchSelect/searchselect.css +95 -0
  53. package/dist/components/SearchSelect/searchselect.d.ts +6 -0
  54. package/dist/components/SearchSelect/searchselect.js +166 -0
  55. package/dist/components/Select/Select.astro +147 -0
  56. package/dist/components/Select/select.css +110 -0
  57. package/dist/components/Select/select.d.ts +1 -0
  58. package/dist/components/Select/select.js +143 -0
  59. package/dist/components/Sidebar/helpers.d.ts +76 -0
  60. package/dist/components/Sidebar/helpers.js +160 -0
  61. package/{src → dist}/components/Tabs/TabItem.astro +3 -4
  62. package/dist/components/Tabs/Tabs.astro +150 -0
  63. package/dist/components/Tabs/tabs.css +121 -0
  64. package/dist/components/Tabs/tabs.d.ts +1 -0
  65. package/dist/components/Tabs/tabs.js +82 -0
  66. package/{src/components → dist/components/Textarea}/Textarea.astro +2 -61
  67. package/dist/components/Textarea/textarea.css +49 -0
  68. package/dist/components/ThemeToggle/ThemeToggle.astro +21 -0
  69. package/dist/components/ThemeToggle/themetoggle.css +17 -0
  70. package/dist/components/ThemeToggle/themetoggle.d.ts +1 -0
  71. package/dist/components/ThemeToggle/themetoggle.js +4 -0
  72. package/dist/components/Toast/Toaster.astro +69 -0
  73. package/dist/components/Toast/toast.d.ts +8 -0
  74. package/dist/components/Toast/toast.js +9 -0
  75. package/dist/components/Toast/toaster.css +168 -0
  76. package/dist/components/Toast/toaster.d.ts +1 -0
  77. package/dist/components/Toast/toaster.js +160 -0
  78. package/dist/components/Toggle/Toggle.astro +84 -0
  79. package/dist/components/Toggle/toggle.css +93 -0
  80. package/dist/components/Toggle/toggle.d.ts +2 -0
  81. package/dist/components/Toggle/toggle.js +20 -0
  82. package/{src/components → dist/components/User}/User.astro +3 -43
  83. package/dist/components/User/user.css +35 -0
  84. package/dist/css/colors.css +95 -0
  85. package/dist/css/global.css +3 -0
  86. package/dist/css/radii.css +6 -0
  87. package/dist/css/resets.css +46 -0
  88. package/dist/index.d.ts +12 -0
  89. package/dist/index.js +379 -0
  90. package/dist/toolbar/ColorPicker.d.ts +7 -0
  91. package/dist/toolbar/ColorPicker.js +85 -0
  92. package/dist/toolbar/icon.d.ts +1 -0
  93. package/dist/toolbar/icon.js +4 -0
  94. package/dist/toolbar/index.d.ts +2 -0
  95. package/dist/toolbar/index.js +292 -0
  96. package/dist/types/index.d.ts +11 -0
  97. package/dist/types/index.js +0 -0
  98. package/dist/utils/ThemeHelper.d.ts +49 -0
  99. package/dist/utils/ThemeHelper.js +113 -0
  100. package/{src/utils/colors.ts → dist/utils/colors.d.ts} +1 -1
  101. package/dist/utils/colors.js +0 -0
  102. package/dist/utils/generateID.d.ts +2 -0
  103. package/dist/utils/generateID.js +6 -0
  104. package/dist/utils/headers.d.ts +43 -0
  105. package/dist/utils/headers.js +129 -0
  106. package/dist/utils/iconStrings.d.ts +4 -0
  107. package/dist/utils/iconStrings.js +13 -0
  108. package/dist/utils/integration-utils.d.ts +130 -0
  109. package/dist/utils/integration-utils.js +161 -0
  110. package/package.json +25 -9
  111. package/src/components/BaseHead.astro +0 -22
  112. package/src/components/Button.astro +0 -372
  113. package/src/components/Center.astro +0 -16
  114. package/src/components/Checkbox.astro +0 -250
  115. package/src/components/Divider.astro +0 -46
  116. package/src/components/Dropdown/Dropdown.astro +0 -314
  117. package/src/components/Dropdown/dropdown.ts +0 -258
  118. package/src/components/Dropdown/index.ts +0 -2
  119. package/src/components/Footer.astro +0 -137
  120. package/src/components/Modal/index.ts +0 -2
  121. package/src/components/Modal/modal.ts +0 -163
  122. package/src/components/RadioGroup.astro +0 -299
  123. package/src/components/SearchSelect.astro +0 -486
  124. package/src/components/Select.astro +0 -467
  125. package/src/components/Sidebar/helpers.ts +0 -179
  126. package/src/components/Sidebar/index.ts +0 -3
  127. package/src/components/Tabs/Tabs.astro +0 -376
  128. package/src/components/Tabs/index.ts +0 -2
  129. package/src/components/ThemeToggle.astro +0 -46
  130. package/src/components/Toast/Toaster.astro +0 -470
  131. package/src/components/Toast/index.ts +0 -2
  132. package/src/components/Toast/toast.ts +0 -16
  133. package/src/components/Toggle.astro +0 -214
  134. package/src/components/index.ts +0 -27
  135. package/src/components.ts +0 -26
  136. package/src/css/colors.css +0 -106
  137. package/src/css/global.css +0 -2
  138. package/src/css/resets.css +0 -54
  139. package/src/env.d.ts +0 -15
  140. package/src/integration.ts +0 -31
  141. package/src/layouts/RootLayout.astro +0 -33
  142. package/src/layouts/index.ts +0 -2
  143. package/src/layouts.ts +0 -1
  144. package/src/types/index.ts +0 -11
  145. package/src/utils/ThemeHelper.ts +0 -145
  146. package/src/utils/create-resolver.ts +0 -30
  147. package/src/utils/generateID.ts +0 -5
  148. package/src/utils/headers.ts +0 -190
  149. package/src/utils/iconStrings.ts +0 -29
  150. package/src/utils/index.ts +0 -1
  151. package/src/utils/virtual-module-plugin-builder.ts +0 -37
  152. /package/{src → dist}/components/Sidebar/Double.astro +0 -0
  153. /package/{src → dist}/components/Sidebar/Single.astro +0 -0
  154. /package/{src → dist}/icons/Checkmark.astro +0 -0
  155. /package/{src → dist}/icons/ChevronUpDown.astro +0 -0
  156. /package/{src → dist}/icons/User.astro +0 -0
  157. /package/{src → dist}/icons/X-Mark.astro +0 -0
@@ -1,376 +0,0 @@
1
- ---
2
- import { Icon } from '../../utils';
3
- import type { StudioCMSColorway } from '../../utils/colors';
4
- import { generateID } from '../../utils/generateID';
5
- import type { HeroIconName } from '../../utils/iconType';
6
-
7
- interface Tab {
8
- icon?: HeroIconName;
9
- label: string;
10
- color: Exclude<StudioCMSColorway, 'default'>;
11
- tabId: string;
12
- }
13
-
14
- /**
15
- * The props for the Tabs component.
16
- */
17
- interface Props {
18
- /**
19
- * The sync key for the tabs. If provided, the active tab will be synced across all instances of the tabs with the same sync key.
20
- * Additionally, the active tab will be stored session- or local storage depending on the `storage` prop.
21
- */
22
- syncKey?: string;
23
- /**
24
- * The storage type for the tabs. Defaults to `session`.
25
- */
26
- storage?: 'session' | 'persistent';
27
- /**
28
- * The variant of the tabs. Defaults to `default`.
29
- */
30
- variant?: 'default' | 'starlight';
31
- /**
32
- * The alignment of the tabs. Defaults to `left`.
33
- */
34
- align?: 'left' | 'center' | 'right';
35
- }
36
-
37
- const extractTabInfoWithRegex = (input: string) => {
38
- const tabItemRegex = /<sui-tab-item([^>]*)>/g;
39
-
40
- const attributeRegex = /data-([\w-]+)="([^"]*)"/g;
41
-
42
- const tabs: Tab[] = [];
43
- let tabMatch: RegExpExecArray | null;
44
-
45
- // biome-ignore lint/suspicious/noAssignInExpressions: Nop
46
- while ((tabMatch = tabItemRegex.exec(input)) !== null) {
47
- let attributes: { [key: string]: string } = {};
48
-
49
- let attributeMatch: RegExpExecArray | null;
50
-
51
- if (!tabMatch[1]) continue;
52
-
53
- // biome-ignore lint/suspicious/noAssignInExpressions: Nop
54
- while ((attributeMatch = attributeRegex.exec(tabMatch[1])) !== null) {
55
- if (!attributeMatch[1] || !attributeMatch[2]) continue;
56
-
57
- if (
58
- attributeMatch[1] === 'icon' ||
59
- attributeMatch[1] === 'label' ||
60
- attributeMatch[1] === 'color'
61
- ) {
62
- attributes[attributeMatch[1]] = attributeMatch[2];
63
- }
64
-
65
- if (attributeMatch[1] === 'tab-id') {
66
- attributes.tabId = attributeMatch[2];
67
- }
68
- }
69
-
70
- tabs.push(attributes as unknown as Tab);
71
- }
72
-
73
- return tabs;
74
- };
75
-
76
- const markTabAsActive = (tabId: string, html: string): string => {
77
- if (!tabId) return html;
78
-
79
- const updatedHtml = html.replace(
80
- new RegExp(`(<sui-tab-item[^>]*data-tab-id="${tabId}"[^>]*class=")([^"]*)(")`, 'g'),
81
- '$1$2 active$3'
82
- );
83
-
84
- return updatedHtml;
85
- };
86
-
87
- const uniqueId = generateID('sui-tabs-container');
88
-
89
- const {
90
- syncKey: originalSyncKey,
91
- storage = 'session',
92
- variant = 'default',
93
- align = 'left',
94
- } = Astro.props;
95
-
96
- const syncKey = originalSyncKey ? `sui-tabs-${originalSyncKey}` : undefined;
97
-
98
- const tabContents = await Astro.slots.render('default');
99
- const tabs = extractTabInfoWithRegex(tabContents);
100
- const finalizedTabContents = markTabAsActive(tabs[0]?.tabId || '', tabContents);
101
- const containerId = generateID('sui-tabs-container');
102
- ---
103
-
104
- <div
105
- class="sui-tabs-container"
106
- id={containerId}
107
- data-sync-key={syncKey}
108
- data-unique-id={uniqueId}
109
- data-storage-strategy={storage}
110
- class:list={[variant, align]}
111
- >
112
- <div class="sui-tabs-list" role="tablist">
113
- {tabs.map((tab, i) => (
114
- <button
115
- role="tab"
116
- class="sui-tab-header"
117
- id={syncKey ? `${syncKey}-${i}` : undefined}
118
- tabindex={i === 0 ? 0 : -1}
119
- data-tab-child={tab.tabId}
120
- class:list={[i === 0 && "active", tab.color, syncKey && `${syncKey}:${i}`]}
121
- >
122
- {tab.icon && (
123
- <Icon name={tab.icon} width={24} height={24} />
124
- )}
125
- <span>{tab.label}</span>
126
- </button>
127
- ))}
128
- </div>
129
- <div class="sui-tabs-content">
130
- <Fragment set:html={finalizedTabContents} />
131
- </div>
132
- </div>
133
- <script>
134
- const tabContainers = document.querySelectorAll<HTMLDivElement>('.sui-tabs-container');
135
-
136
- for (const tabContainer of tabContainers) {
137
- const storage = tabContainer.dataset.storageStrategy!;
138
- const syncKey = tabContainer.dataset.syncKey!;
139
-
140
- let storageLayer = storage === 'session' ? sessionStorage : localStorage;
141
-
142
- const constructCustomEvent = (tabIndex: number, uniqueId: string) => {
143
- return new CustomEvent(`sui-tab-switch:${syncKey}`, {
144
- detail: {
145
- tabIndex,
146
- uniqueId
147
- }
148
- });
149
- }
150
-
151
- const switchTab = (target: HTMLElement, container: HTMLElement, originatedFromSync = false) => {
152
- const activeChildren = container.querySelectorAll<HTMLElement>('.active');
153
-
154
- for (const child of activeChildren) {
155
- child.tabIndex = -1;
156
- child.classList.remove('active');
157
- }
158
-
159
- const newActiveTab = target as HTMLElement;
160
- newActiveTab.classList.add('active');
161
- newActiveTab.tabIndex = 0;
162
-
163
- const newActiveTabContentId = newActiveTab.dataset.tabChild;
164
- const newActiveTabContent = container.querySelector<HTMLElement>(`sui-tab-item[data-tab-id="${newActiveTabContentId}"]`)!;
165
-
166
- newActiveTabContent.classList.add('active');
167
-
168
- if (syncKey && !originatedFromSync) {
169
- const tabIndex = Array.prototype.indexOf.call(newActiveTab.parentElement!.children, newActiveTab);
170
- storageLayer.setItem(syncKey, tabIndex.toString());
171
-
172
- document.dispatchEvent(constructCustomEvent(tabIndex, container.dataset.uniqueId!));
173
- }
174
-
175
- }
176
-
177
- const tabHeaders = tabContainer.querySelectorAll<HTMLElement>('.sui-tab-header');
178
-
179
- for (const tab of tabHeaders) {
180
- tab.addEventListener('click', (e) => switchTab(e.target as HTMLElement, tabContainer));
181
-
182
- tab.addEventListener('keydown', (e) => {
183
- if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
184
- const activeTabIndex = Array.prototype.indexOf.call(tab.parentElement!.children, tab);
185
- const nextTabIndex = e.key === 'ArrowLeft' ? activeTabIndex - 1 : activeTabIndex + 1;
186
-
187
-
188
- if (nextTabIndex >= 0 && nextTabIndex < tab.parentElement!.children.length) {
189
- tab.tabIndex = -1;
190
-
191
- const nextTab = tab.parentElement!.children[nextTabIndex]! as HTMLElement;
192
-
193
- nextTab.tabIndex = 0;
194
- nextTab.click();
195
- nextTab.focus();
196
- } else if (nextTabIndex < 0) {
197
- tab.tabIndex = -1;
198
-
199
- const lastTab = tab.parentElement!.children[tab.parentElement!.children.length - 1] as HTMLElement;
200
-
201
- lastTab.tabIndex = 0;
202
- lastTab.click();
203
- lastTab.focus();
204
- } else {
205
- tab.tabIndex = -1;
206
-
207
- const firstTab = tab.parentElement!.children[0] as HTMLElement;
208
-
209
- firstTab.tabIndex = 0;
210
- firstTab.click();
211
- firstTab.focus();
212
- }
213
- }
214
- });
215
- }
216
-
217
- if (syncKey) {
218
- // Retrieve the sync key value from localstorage, set the tab.
219
- const activeTabIndex = storageLayer.getItem(syncKey);
220
-
221
- if (activeTabIndex) {
222
- const activeTab = tabContainer.querySelector<HTMLElement>(`#${syncKey}-${activeTabIndex}`);
223
-
224
- if (activeTab) {
225
- activeTab.click();
226
- }
227
- }
228
-
229
- document.addEventListener(`sui-tab-switch:${syncKey}`, (e) => {
230
- const event = e as CustomEvent<{ tabIndex: number, uniqueId: string }>;
231
- const { tabIndex, uniqueId } = event.detail;
232
-
233
- if (uniqueId === tabContainer.dataset.uniqueId) return;
234
-
235
- const newTab = tabContainer.querySelector<HTMLElement>(`#${syncKey}-${tabIndex}`)!;
236
-
237
- switchTab(newTab, tabContainer, true);
238
- });
239
- }
240
- }
241
- </script>
242
- <style>
243
- .sui-tabs-container {
244
- width: 100%;
245
- }
246
-
247
- .sui-tabs-list {
248
- display: flex;
249
- flex-direction: row;
250
- gap: 1rem;
251
- align-items: center;
252
- width: 100%;
253
- overflow-x: auto;
254
- overflow-y: visible;
255
- position: relative;
256
- }
257
-
258
- .default .sui-tabs-list {
259
- margin-top: -4px;
260
- margin-bottom: calc(2rem - 4px);
261
- padding: 4px 4px;
262
- margin-left: -4px;
263
- }
264
-
265
- .center .sui-tabs-list {
266
- justify-content: center;
267
- }
268
-
269
- .right .sui-tabs-list {
270
- justify-content: flex-end;
271
- }
272
-
273
- .sui-tab-header {
274
- margin-top: 0 !important;
275
- display: flex;
276
- flex-direction: row;
277
- gap: .5rem;
278
- cursor: pointer;
279
- position: relative;
280
- min-width: fit-content;
281
- }
282
-
283
- .default .sui-tab-header {
284
- border-radius: 0.5rem;
285
- height: 40px;
286
- padding: 0.5rem 0.75rem;
287
- transition: all .15s ease;
288
- font-size: 0.875em;
289
- outline: 2px solid transparent;
290
- outline-offset: 2px;
291
- }
292
-
293
- .sui-tab-header * {
294
- pointer-events: none;
295
- }
296
-
297
- .default .sui-tab-header:focus-visible {
298
- outline: 2px solid hsl(var(--text-normal));
299
- outline-offset: 2px;
300
- }
301
-
302
- .default .sui-tab-header:hover {
303
- background-color: hsla(var(--default-flat-active)) !important;
304
- }
305
-
306
- .default .sui-tab-header.active {
307
- background-color: hsla(var(--primary-flat-active)) !important;
308
- }
309
-
310
- .default .sui-tab-header.success.active {
311
- background-color: hsla(var(--success-flat-active)) !important;
312
- }
313
-
314
- .default .sui-tab-header.warning.active {
315
- background-color: hsla(var(--warning-flat-active)) !important;
316
- }
317
-
318
- .default .sui-tab-header.danger.active {
319
- background-color: hsla(var(--danger-flat-active)) !important;
320
- }
321
-
322
- .starlight .sui-tabs-list {
323
- margin-bottom: 1rem;
324
- gap: 0;
325
- }
326
-
327
- .starlight .sui-tabs-list::before {
328
- content: "";
329
- position: absolute;
330
- bottom: 0;
331
- left: 0;
332
- width: 100%;
333
- height: 2px;
334
- background-color: hsl(var(--border));
335
- }
336
-
337
- .starlight .sui-tab-header {
338
- padding: 0.25rem 1.25rem;
339
- color: hsl(var(--text-muted));
340
- }
341
-
342
- .starlight .sui-tab-header.active {
343
- font-weight: 600;
344
- color: hsl(var(--text-normal));
345
- }
346
-
347
- .starlight .sui-tab-header.active::after {
348
- content: "";
349
- width: 100%;
350
- height: 2px;
351
- background-color: hsl(var(--primary-base));
352
- position: absolute;
353
- bottom: 0;
354
- left: 0;
355
- z-index: 15;
356
- }
357
-
358
- .starlight .sui-tab-header:focus-visible::after {
359
- height: calc(100% - 2px);
360
- width: calc(100% - 2px);
361
- bottom: 1px;
362
- left: 1px;
363
- border: 2px solid hsl(var(--primary-base));
364
- background-color: transparent;
365
- outline: 1px solid hsl(var(--text-normal));
366
- }
367
-
368
- .default .sui-tab-header.active {
369
- background-color: hsla(var(--primary-flat-active)) !important;
370
- }
371
-
372
- .sui-tabs-content {
373
- width: 100%;
374
- margin: 0 !important;
375
- }
376
- </style>
@@ -1,2 +0,0 @@
1
- export { default as TabItem } from './TabItem.astro';
2
- export { default as Tabs } from './Tabs.astro';
@@ -1,46 +0,0 @@
1
- ---
2
- import Button, { type Props as ButtonProps } from './Button.astro';
3
-
4
- interface Props extends ButtonProps {}
5
-
6
- const props = Astro.props;
7
- ---
8
-
9
- <Button id='sui-theme-toggle' {...props}>
10
- <div id="dark-content">
11
- <slot name="dark" />
12
- </div>
13
- <div id="light-content">
14
- <slot name="light" />
15
- </div>
16
- </Button>
17
-
18
- <script>
19
- import { ThemeHelper } from '../utils/ThemeHelper';
20
-
21
- const themeToggle = document.getElementById('sui-theme-toggle');
22
- const themeHelper = new ThemeHelper();
23
-
24
- themeHelper.registerToggle(themeToggle);
25
- </script>
26
-
27
- <style is:global>
28
- #sui-theme-toggle, #sui-theme-toggle * {
29
- color: hsl(var(--text-normal));
30
- }
31
-
32
- #sui-theme-toggle #dark-content, #sui-theme-toggle #light-content {
33
- display: none;
34
- width: fit-content;
35
- height: fit-content;
36
- max-height: 100%;
37
- }
38
-
39
- [data-theme="dark"] #sui-theme-toggle #dark-content {
40
- display: block;
41
- }
42
-
43
- [data-theme="light"] #sui-theme-toggle #light-content {
44
- display: block;
45
- }
46
- </style>