@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.
Files changed (156) 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/{src/components → dist/components/Divider}/Divider.astro +2 -25
  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 -3
  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/Dropdown/Dropdown.astro +0 -314
  116. package/src/components/Dropdown/dropdown.ts +0 -258
  117. package/src/components/Dropdown/index.ts +0 -2
  118. package/src/components/Footer.astro +0 -137
  119. package/src/components/Modal/index.ts +0 -2
  120. package/src/components/Modal/modal.ts +0 -163
  121. package/src/components/RadioGroup.astro +0 -299
  122. package/src/components/SearchSelect.astro +0 -486
  123. package/src/components/Select.astro +0 -467
  124. package/src/components/Sidebar/helpers.ts +0 -179
  125. package/src/components/Sidebar/index.ts +0 -3
  126. package/src/components/Tabs/Tabs.astro +0 -393
  127. package/src/components/Tabs/index.ts +0 -2
  128. package/src/components/ThemeToggle.astro +0 -46
  129. package/src/components/Toast/Toaster.astro +0 -470
  130. package/src/components/Toast/index.ts +0 -2
  131. package/src/components/Toast/toast.ts +0 -16
  132. package/src/components/Toggle.astro +0 -214
  133. package/src/components/index.ts +0 -27
  134. package/src/components.ts +0 -26
  135. package/src/css/colors.css +0 -106
  136. package/src/css/global.css +0 -2
  137. package/src/css/resets.css +0 -54
  138. package/src/env.d.ts +0 -15
  139. package/src/integration.ts +0 -31
  140. package/src/layouts/RootLayout.astro +0 -33
  141. package/src/layouts/index.ts +0 -2
  142. package/src/layouts.ts +0 -1
  143. package/src/types/index.ts +0 -11
  144. package/src/utils/ThemeHelper.ts +0 -145
  145. package/src/utils/create-resolver.ts +0 -30
  146. package/src/utils/generateID.ts +0 -5
  147. package/src/utils/headers.ts +0 -190
  148. package/src/utils/iconStrings.ts +0 -29
  149. package/src/utils/index.ts +0 -1
  150. package/src/utils/virtual-module-plugin-builder.ts +0 -37
  151. /package/{src → dist}/components/Sidebar/Double.astro +0 -0
  152. /package/{src → dist}/components/Sidebar/Single.astro +0 -0
  153. /package/{src → dist}/icons/Checkmark.astro +0 -0
  154. /package/{src → dist}/icons/ChevronUpDown.astro +0 -0
  155. /package/{src → dist}/icons/User.astro +0 -0
  156. /package/{src → dist}/icons/X-Mark.astro +0 -0
@@ -0,0 +1,166 @@
1
+ const allSearchSelects = document.querySelectorAll(".sui-search-select-label");
2
+ for (const container of allSearchSelects) {
3
+ let hideOnClickOutside = function(element) {
4
+ const outsideClickListener = (event) => {
5
+ if (!element.contains(event.target) && isVisible(element) && active === true) {
6
+ dropdown.classList.remove("active", "above");
7
+ active = false;
8
+ }
9
+ };
10
+ document.addEventListener("click", outsideClickListener);
11
+ }, constructOptionsBasedOnOptions = function(options2) {
12
+ dropdown.innerHTML = "";
13
+ if (options2.length === 0) {
14
+ const element = document.createElement("li");
15
+ element.classList.add("empty-search-results");
16
+ element.textContent = "No results found.";
17
+ dropdown.appendChild(element);
18
+ }
19
+ let i = 0;
20
+ for (const option of options2) {
21
+ const element = document.createElement("li");
22
+ element.classList.add(
23
+ ...[
24
+ "sui-search-select-option",
25
+ option.disabled && "disabled",
26
+ focusIndex === i && "focused"
27
+ ].filter((x) => typeof x === "string")
28
+ );
29
+ element.role = "option";
30
+ element.value = Number.parseInt(option.value);
31
+ element.id = "";
32
+ element.dataset.optionIndex = i.toString();
33
+ element.dataset.value = option.value;
34
+ element.textContent = option.label;
35
+ element.addEventListener("click", (e) => handleSelection(e, element));
36
+ dropdown.appendChild(element);
37
+ i++;
38
+ }
39
+ optionElements = container.querySelectorAll("li");
40
+ };
41
+ var hideOnClickOutside2 = hideOnClickOutside, constructOptionsBasedOnOptions2 = constructOptionsBasedOnOptions;
42
+ const hiddenSelect = container.querySelector("select");
43
+ const searchWrapper = container.querySelector(".sui-search-input-wrapper");
44
+ const searchInput = searchWrapper.querySelector("input");
45
+ const dropdown = container.querySelector(".sui-search-select-dropdown");
46
+ let optionElements = container.querySelectorAll("li");
47
+ let active = false;
48
+ const options = JSON.parse(container.dataset.options);
49
+ const id = container.dataset.id;
50
+ let filteredOptions = options;
51
+ searchWrapper.addEventListener("click", () => {
52
+ const { bottom, left, right, width, x, y, height } = searchWrapper.getBoundingClientRect();
53
+ const optionHeight = 36;
54
+ const totalBorderSize = 2;
55
+ const margin = 4;
56
+ const dropdownHeight = options.length * optionHeight + totalBorderSize + margin;
57
+ const CustomRect = {
58
+ top: bottom + margin,
59
+ left,
60
+ right,
61
+ bottom: bottom + margin + dropdownHeight,
62
+ width,
63
+ height: dropdownHeight,
64
+ x,
65
+ y: y + height + margin
66
+ };
67
+ if (active) {
68
+ searchInput.ariaExpanded = "false";
69
+ dropdown.classList.remove("active", "above");
70
+ active = false;
71
+ return;
72
+ }
73
+ active = true;
74
+ searchInput.ariaExpanded = "true";
75
+ if (CustomRect.top >= 0 && CustomRect.left >= 0 && CustomRect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && CustomRect.right <= (window.innerWidth || document.documentElement.clientWidth)) {
76
+ dropdown.classList.add("active");
77
+ } else {
78
+ dropdown.classList.add("active", "above");
79
+ }
80
+ });
81
+ const handleSelection = (e, option) => {
82
+ e.stopImmediatePropagation();
83
+ if (option.id === `${id}-selected` || !id) return;
84
+ const currentlySelected = document.getElementById(`${id}-selected`);
85
+ if (currentlySelected) {
86
+ currentlySelected.classList.remove("selected");
87
+ currentlySelected.id = "";
88
+ }
89
+ option.id = `${id}-selected`;
90
+ option.classList.add("selected");
91
+ const index = options.findIndex((x) => x.value === option.dataset.value);
92
+ focusIndex = index;
93
+ const opt = options[index];
94
+ hiddenSelect.value = opt.value;
95
+ searchInput.placeholder = opt.label;
96
+ dropdown.classList.remove("active", "above");
97
+ searchInput.value = "";
98
+ filteredOptions = options;
99
+ constructOptionsBasedOnOptions(options);
100
+ active = false;
101
+ };
102
+ for (const option of optionElements) {
103
+ option.addEventListener("click", (e) => handleSelection(e, option));
104
+ }
105
+ window.addEventListener("scroll", () => {
106
+ dropdown.classList.remove("active", "above");
107
+ active = false;
108
+ });
109
+ hideOnClickOutside(container);
110
+ const isVisible = (elem) => !!elem && !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
111
+ let focusIndex = 0;
112
+ const recomputeOptions = () => {
113
+ for (const entry of optionElements) {
114
+ if (Number.parseInt(entry.dataset.optionIndex) === focusIndex) {
115
+ entry.classList.add("focused");
116
+ } else {
117
+ entry.classList.remove("focused");
118
+ }
119
+ }
120
+ };
121
+ searchInput.addEventListener("keydown", (e) => {
122
+ if (e.key === "Escape") {
123
+ e.preventDefault();
124
+ e.stopImmediatePropagation();
125
+ active = false;
126
+ dropdown.classList.remove("active", "above");
127
+ searchInput.blur();
128
+ return;
129
+ }
130
+ if (e.key === "ArrowUp" && focusIndex > 0) {
131
+ e.preventDefault();
132
+ e.stopImmediatePropagation();
133
+ focusIndex--;
134
+ recomputeOptions();
135
+ return;
136
+ }
137
+ if (e.key === "ArrowDown" && focusIndex + 1 < filteredOptions.filter((x) => !x.disabled).length) {
138
+ e.preventDefault();
139
+ e.stopImmediatePropagation();
140
+ focusIndex++;
141
+ recomputeOptions();
142
+ return;
143
+ }
144
+ if (e.key === "Enter") {
145
+ e.preventDefault();
146
+ e.stopImmediatePropagation();
147
+ for (const entry of optionElements) {
148
+ if (Number.parseInt(entry.dataset.optionIndex) === focusIndex) {
149
+ entry.click();
150
+ }
151
+ }
152
+ return;
153
+ }
154
+ });
155
+ searchInput.addEventListener("keyup", (e) => {
156
+ if (["Enter", "ArrowUp", "ArrowDown"].includes(e.key)) return;
157
+ if (searchInput.value.trim().length === 0) {
158
+ constructOptionsBasedOnOptions(options);
159
+ filteredOptions = options;
160
+ return;
161
+ }
162
+ filteredOptions = options.filter((x) => x.label.includes(searchInput.value));
163
+ focusIndex = 0;
164
+ constructOptionsBasedOnOptions(filteredOptions);
165
+ });
166
+ }
@@ -0,0 +1,147 @@
1
+ ---
2
+ import { generateID } from '../../utils/generateID.js';
3
+ import Icon from '../Icon/Icon.astro';
4
+ import './select.css';
5
+
6
+ /**
7
+ * The props for the select component.
8
+ */
9
+ interface Option {
10
+ /**
11
+ * The label of the option.
12
+ */
13
+ label: string;
14
+ /**
15
+ * The value of the option.
16
+ */
17
+ value: string;
18
+ /**
19
+ * Whether the option is disabled. Defaults to `false`.
20
+ */
21
+ disabled?: boolean;
22
+ }
23
+
24
+ /**
25
+ * The props for the select component.
26
+ */
27
+ interface Props {
28
+ /**
29
+ * The label of the select.
30
+ */
31
+ label?: string;
32
+ /**
33
+ * The default value of the select.
34
+ */
35
+ defaultValue?: string;
36
+ /**
37
+ * Additional classes to apply to the select.
38
+ */
39
+ class?: string;
40
+ /**
41
+ * The name of the select. Required because of the helper.
42
+ */
43
+ name?: string;
44
+ /**
45
+ * Whether the select is required. Defaults to `false`.
46
+ */
47
+ isRequired?: boolean;
48
+ /**
49
+ * The options to display in the select.
50
+ */
51
+ options: Option[];
52
+ /**
53
+ * Whether the select is disabled. Defaults to `false`.
54
+ */
55
+ disabled?: boolean;
56
+ /**
57
+ * Whether the select is full width. Defaults to `false`.
58
+ */
59
+ fullWidth?: boolean;
60
+ /**
61
+ * The placeholder of the select. Defaults to `Select`.
62
+ */
63
+ placeholder?: string;
64
+ }
65
+
66
+ const {
67
+ label,
68
+ defaultValue,
69
+ class: className,
70
+ name = generateID('select'),
71
+ isRequired,
72
+ options = [],
73
+ disabled,
74
+ fullWidth,
75
+ placeholder = 'Select',
76
+ } = Astro.props;
77
+ ---
78
+
79
+ <div
80
+ id={`${name}-container`}
81
+ class="sui-select-label"
82
+ class:list={[disabled && "disabled", className, fullWidth && "full"]}
83
+ data-options={JSON.stringify(options)}
84
+ data-id={name}
85
+ >
86
+ {label && (
87
+ <label class="label" for={`${name}-select-btn`}>
88
+ {label}
89
+ <span class="req-star">{isRequired && "*"}</span>
90
+ </label>
91
+ )}
92
+ <button
93
+ class="sui-select-button"
94
+ role="combobox"
95
+ aria-controls={`${name}-dropdown`}
96
+ aria-expanded="false"
97
+ id={`${name}-select-btn`}
98
+ type="button"
99
+ aria-label={placeholder}
100
+ title={placeholder}
101
+ >
102
+ <span class="sui-select-value-span" id={`${name}-value-span`}>
103
+ {
104
+ defaultValue
105
+ ? options.find((x) => x.value === defaultValue)?.label
106
+ : placeholder
107
+ }
108
+ </span>
109
+ <Icon name="chevron-up-down" width={24} height={24} />
110
+ </button>
111
+ <ul class="sui-select-dropdown" role="listbox" id={`${name}-dropdown`}>
112
+ {
113
+ options.map((x, i) => (
114
+ <li
115
+ class="sui-select-option"
116
+ role="option"
117
+ value={x.value}
118
+ class:list={[
119
+ defaultValue === x.value && `selected`,
120
+ x.disabled && "disabled",
121
+ ]}
122
+ id={defaultValue === x.value ? `${name}-selected` : ""}
123
+ data-option-index={i}
124
+ >
125
+ {x.label}
126
+ </li>
127
+ ))
128
+ }
129
+ </ul>
130
+ <select class="sui-hidden-select" id={name} name={name} required={isRequired} hidden tabindex="-1">
131
+ <option value={""}> Select </option>
132
+ {
133
+ options.map((x) => (
134
+ <option
135
+ value={x.value}
136
+ selected={defaultValue === x.value}
137
+ disabled={x.disabled}
138
+ >
139
+ {x.label}
140
+ </option>
141
+ ))
142
+ }
143
+ </select>
144
+ </div>
145
+ <script>
146
+ import "studiocms:ui/scripts/select"
147
+ </script>
@@ -0,0 +1,110 @@
1
+ .sui-select-label {
2
+ width: fit-content;
3
+ display: flex;
4
+ flex-direction: column;
5
+ gap: 0.25rem;
6
+ min-width: 200px;
7
+ position: relative;
8
+ height: fit-content;
9
+ }
10
+ .sui-select-label.full,
11
+ .sui-select-label.full .sui-select-button {
12
+ width: 100%;
13
+ }
14
+ .sui-select-label.disabled {
15
+ opacity: 0.5;
16
+ pointer-events: none;
17
+ color: hsl(var(--text-muted));
18
+ }
19
+ .label {
20
+ font-size: 14px;
21
+ }
22
+ .req-star {
23
+ color: hsl(var(--danger-base));
24
+ font-weight: 700;
25
+ }
26
+ .sui-select-button {
27
+ padding: 0.5rem 0.75rem 0.5rem 1rem;
28
+ border-radius: var(--radius-md);
29
+ border: 1px solid hsl(var(--border));
30
+ background: hsl(var(--background-step-2));
31
+ color: hsl(var(--text-normal));
32
+ transition: background border 0.15s ease;
33
+ display: flex;
34
+ flex-direction: row;
35
+ align-items: center;
36
+ justify-content: space-between;
37
+ cursor: pointer;
38
+ gap: 1rem;
39
+ }
40
+ .sui-select-button:focus {
41
+ border: 1px solid hsl(var(--primary-base));
42
+ }
43
+ .sui-select-button:hover,
44
+ .sui-select-button:focus {
45
+ background: hsl(var(--background-step-3));
46
+ }
47
+ .sui-select-button.active,
48
+ .sui-select-button:active,
49
+ .sui-select-button:has(+ .sui-select-dropdown.active) {
50
+ border: 1px solid hsl(var(--primary-base));
51
+ background: hsl(var(--background-step-2));
52
+ }
53
+ .sui-select-dropdown {
54
+ position: absolute;
55
+ width: 100%;
56
+ border: 1px solid hsl(var(--border));
57
+ list-style: none;
58
+ margin: 0;
59
+ padding: 0;
60
+ flex-direction: column;
61
+ border-radius: var(--radius-md);
62
+ background-color: hsl(var(--background-step-2));
63
+ overflow: hidden;
64
+ top: calc(100% + 0.25rem);
65
+ left: 0;
66
+ display: none;
67
+ z-index: 90;
68
+ box-shadow: 0px 4px 8px hsl(var(--shadow), 0.5);
69
+ }
70
+ .sui-select-dropdown.active {
71
+ display: flex;
72
+ }
73
+ .sui-select-dropdown.above {
74
+ top: auto;
75
+ bottom: calc(100% - 18px + 0.25rem);
76
+ }
77
+ .sui-select-option {
78
+ padding: 0.5rem;
79
+ cursor: pointer;
80
+ font-size: 0.975em;
81
+ transition: all 0.15s ease;
82
+ }
83
+ .sui-select-option.disabled {
84
+ pointer-events: none;
85
+ color: hsl(var(--text-muted));
86
+ }
87
+ .sui-select-option:hover,
88
+ .sui-select-option:focus,
89
+ .sui-select-option.focused {
90
+ background-color: hsl(var(--background-step-3));
91
+ }
92
+ .sui-select-option:focus {
93
+ outline: none;
94
+ border: none;
95
+ }
96
+ .sui-select-option.selected {
97
+ background-color: hsl(var(--primary-base));
98
+ color: hsl(var(--text-inverted));
99
+ cursor: default;
100
+ }
101
+ .sui-hidden-select {
102
+ height: 0;
103
+ width: 0;
104
+ border: none;
105
+ outline: none;
106
+ position: absolute;
107
+ background-color: transparent;
108
+ pointer-events: none;
109
+ opacity: 0;
110
+ }
@@ -0,0 +1 @@
1
+ declare function loadSelects(): void;
@@ -0,0 +1,143 @@
1
+ function loadSelects() {
2
+ const allSelects = document.querySelectorAll(".sui-select-label");
3
+ for (const container of allSelects) {
4
+ let hideOnClickOutside2 = function(element) {
5
+ const outsideClickListener = (event) => {
6
+ if (!element.contains(event.target) && isVisible(element) && active === true) {
7
+ closeDropdown();
8
+ }
9
+ };
10
+ document.addEventListener("click", outsideClickListener);
11
+ };
12
+ var hideOnClickOutside = hideOnClickOutside2;
13
+ const hiddenSelect = container.querySelector("select");
14
+ const button = container.querySelector("button");
15
+ const valueSpan = container.querySelector(".sui-select-value-span");
16
+ const dropdown = container.querySelector(".sui-select-dropdown");
17
+ const optionElements = container.querySelectorAll(".sui-select-option");
18
+ const options = JSON.parse(container.dataset.options);
19
+ const id = container.dataset.id;
20
+ let active = false;
21
+ const closeDropdown = () => {
22
+ dropdown.classList.remove("active", "above");
23
+ active = false;
24
+ button.ariaExpanded = "false";
25
+ focusIndex = -1;
26
+ for (const entry of optionElements) {
27
+ entry.classList.remove("focused");
28
+ }
29
+ };
30
+ const openDropdown = (toggle) => {
31
+ const { bottom, left, right, width, x, y, height } = button.getBoundingClientRect();
32
+ const optionHeight = 36;
33
+ const totalBorderSize = 2;
34
+ const margin = 4;
35
+ const dropdownHeight = options.length * optionHeight + totalBorderSize + margin;
36
+ const CustomRect = {
37
+ top: bottom + margin,
38
+ left,
39
+ right,
40
+ bottom: bottom + margin + dropdownHeight,
41
+ width,
42
+ height: dropdownHeight,
43
+ x,
44
+ y: y + height + margin
45
+ };
46
+ if (active && toggle) {
47
+ closeDropdown();
48
+ return;
49
+ }
50
+ active = true;
51
+ button.ariaExpanded = "true";
52
+ focusIndex = Array.from(optionElements).findIndex((x2) => x2.classList.contains("selected"));
53
+ if (CustomRect.top >= 0 && CustomRect.left >= 0 && CustomRect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && CustomRect.right <= (window.innerWidth || document.documentElement.clientWidth)) {
54
+ dropdown.classList.add("active");
55
+ } else {
56
+ dropdown.classList.add("active", "above");
57
+ }
58
+ };
59
+ button.addEventListener("click", () => openDropdown(true));
60
+ let focusIndex = -1;
61
+ const recomputeOptions = () => {
62
+ for (const entry of optionElements) {
63
+ if (Number.parseInt(entry.dataset.optionIndex) === focusIndex) {
64
+ entry.classList.add("focused");
65
+ } else {
66
+ entry.classList.remove("focused");
67
+ }
68
+ }
69
+ };
70
+ button.addEventListener("keydown", (e) => {
71
+ if (e.key === "Tab" || e.key === "Escape") {
72
+ closeDropdown();
73
+ return;
74
+ }
75
+ if (e.key === " " && !active) openDropdown(false);
76
+ if (e.key === "Enter") {
77
+ const currentlyFocused = container.querySelector(".focused");
78
+ if (currentlyFocused) {
79
+ currentlyFocused.classList.remove("focused");
80
+ currentlyFocused.click();
81
+ e.preventDefault();
82
+ e.stopImmediatePropagation();
83
+ }
84
+ return;
85
+ }
86
+ e.preventDefault();
87
+ e.stopImmediatePropagation();
88
+ const neighbor = (offset) => {
89
+ return optionElements.item(
90
+ (Array.from(optionElements).findIndex((x) => x.classList.contains("selected")) ?? -1) + offset
91
+ );
92
+ };
93
+ if (e.key === "ArrowUp" && (focusIndex > 0 || !active)) {
94
+ if (!active) return neighbor(-1)?.click();
95
+ focusIndex--;
96
+ recomputeOptions();
97
+ }
98
+ if (e.key === "ArrowDown" && focusIndex + 1 < optionElements.length) {
99
+ if (!active) return neighbor(1)?.click();
100
+ focusIndex++;
101
+ recomputeOptions();
102
+ }
103
+ if (e.key === "PageUp") {
104
+ focusIndex = 0;
105
+ if (!active) return optionElements.item(focusIndex)?.click();
106
+ recomputeOptions();
107
+ }
108
+ if (e.key === "PageDown") {
109
+ focusIndex = optionElements.length - 1;
110
+ if (!active) return optionElements.item(focusIndex)?.click();
111
+ recomputeOptions();
112
+ }
113
+ });
114
+ const handleSelection = (e, option) => {
115
+ e.stopImmediatePropagation();
116
+ if (option.id === `${id}-selected` || !id) return;
117
+ const currentlySelected = document.getElementById(`${id}-selected`);
118
+ if (currentlySelected) {
119
+ currentlySelected.classList.remove("selected");
120
+ currentlySelected.id = "";
121
+ }
122
+ option.id = `${id}-selected`;
123
+ option.classList.add("selected");
124
+ const opt = options[Number.parseInt(option.dataset.optionIndex)];
125
+ hiddenSelect.value = opt.value;
126
+ valueSpan.textContent = opt.label;
127
+ closeDropdown();
128
+ };
129
+ for (const option of optionElements) {
130
+ const handleSelectionForOption = (e) => handleSelection(e, option);
131
+ option.addEventListener("click", handleSelectionForOption);
132
+ }
133
+ window.addEventListener("scroll", closeDropdown);
134
+ document.addEventListener("keydown", (e) => {
135
+ if (e.key === "Escape" && dropdown.classList.contains("active")) {
136
+ closeDropdown();
137
+ }
138
+ });
139
+ hideOnClickOutside2(container);
140
+ const isVisible = (elem) => !!elem && !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
141
+ }
142
+ }
143
+ document.addEventListener("astro:page-load", loadSelects);
@@ -0,0 +1,76 @@
1
+ declare class SingleSidebarHelper {
2
+ private sidebar;
3
+ private sidebarToggle?;
4
+ /**
5
+ * A helper to manage the sidebar with.
6
+ * @param toggleID The ID of the element that should toggle the sidebar.
7
+ */
8
+ constructor(toggleID?: string);
9
+ /**
10
+ * A helper function register an element which should toggle the sidebar.
11
+ * @param elementID The ID of the element that should toggle the sidebar.
12
+ */
13
+ toggleSidebarOnClick: (elementID: string) => void;
14
+ /**
15
+ * A helper function to hide the sidebar when an element is clicked.
16
+ * @param elementID The ID of the element that should hide the sidebar.
17
+ */
18
+ hideSidebarOnClick: (elementID: string) => void;
19
+ /**
20
+ * A helper function to show the sidebar when an element is clicked.
21
+ * @param elementID The ID of the element that should show the sidebar.
22
+ */
23
+ showSidebarOnClick: (elementID: string) => void;
24
+ /**
25
+ * A function to hide the sidebar.
26
+ */
27
+ hideSidebar: () => void;
28
+ /**
29
+ * A function to show the sidebar.
30
+ */
31
+ showSidebar: () => void;
32
+ }
33
+ declare class DoubleSidebarHelper {
34
+ private sidebarsContainer;
35
+ /**
36
+ * A helper to manage the double sidebar with.
37
+ */
38
+ constructor();
39
+ /**
40
+ * A helper function to hide the sidebar when an element is clicked.
41
+ * @param elementID The ID of the element that should hide the sidebar.
42
+ */
43
+ hideSidebarOnClick: (elementID: string) => void;
44
+ /**
45
+ * A helper function to show the outer sidebar when an element is clicked.
46
+ * @param elementID The ID of the element that should show the outer sidebar.
47
+ */
48
+ showOuterOnClick: (elementID: string) => void;
49
+ /**
50
+ * A helper function to show the inner sidebar when an element is clicked.
51
+ * @param elementID The ID of the element that should show the inner sidebar.
52
+ */
53
+ showInnerOnClick: (elementID: string) => void;
54
+ /**
55
+ * A helper function to toggle between the outer and inner sidebar when an element is clicked.
56
+ * @param elementID The ID of the element that should toggle the sidebar view.
57
+ */
58
+ toggleStateOnClick: (elementID: string) => void;
59
+ /**
60
+ * A function to show the inner sidebar.
61
+ */
62
+ showInnerSidebar: () => void;
63
+ /**
64
+ * A function to show the outer sidebar.
65
+ */
66
+ showOuterSidebar: () => void;
67
+ /**
68
+ * A function to toggle between the outer and inner sidebar.
69
+ */
70
+ toggleSidebarState: () => void;
71
+ /**
72
+ * A function to hide the sidebar altogether.
73
+ */
74
+ hideSidebar: () => void;
75
+ }
76
+ export { SingleSidebarHelper, DoubleSidebarHelper };