@sveltia/ui 0.1.5 → 0.2.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 (105) hide show
  1. package/package.json +22 -11
  2. package/package/components/composite/calendar.svelte +0 -240
  3. package/package/components/composite/calendar.svelte.d.ts +0 -20
  4. package/package/components/composite/checkbox-group.svelte +0 -43
  5. package/package/components/composite/checkbox-group.svelte.d.ts +0 -24
  6. package/package/components/composite/combobox.svelte +0 -206
  7. package/package/components/composite/combobox.svelte.d.ts +0 -32
  8. package/package/components/composite/disclosure.svelte +0 -60
  9. package/package/components/composite/disclosure.svelte.d.ts +0 -26
  10. package/package/components/composite/grid.svelte +0 -24
  11. package/package/components/composite/grid.svelte.d.ts +0 -22
  12. package/package/components/composite/listbox.svelte +0 -63
  13. package/package/components/composite/listbox.svelte.d.ts +0 -39
  14. package/package/components/composite/menu-item-group.svelte +0 -31
  15. package/package/components/composite/menu-item-group.svelte.d.ts +0 -23
  16. package/package/components/composite/menu.svelte +0 -44
  17. package/package/components/composite/menu.svelte.d.ts +0 -32
  18. package/package/components/composite/radio-button-group.svelte +0 -45
  19. package/package/components/composite/radio-button-group.svelte.d.ts +0 -27
  20. package/package/components/composite/select-button-group.svelte +0 -71
  21. package/package/components/composite/select-button-group.svelte.d.ts +0 -31
  22. package/package/components/composite/select.svelte +0 -34
  23. package/package/components/composite/select.svelte.d.ts +0 -26
  24. package/package/components/composite/tab-list.svelte +0 -76
  25. package/package/components/composite/tab-list.svelte.d.ts +0 -42
  26. package/package/components/core/button.svelte +0 -205
  27. package/package/components/core/button.svelte.d.ts +0 -78
  28. package/package/components/core/checkbox.svelte +0 -104
  29. package/package/components/core/checkbox.svelte.d.ts +0 -30
  30. package/package/components/core/dialog.svelte +0 -274
  31. package/package/components/core/dialog.svelte.d.ts +0 -45
  32. package/package/components/core/grid-cell.svelte +0 -14
  33. package/package/components/core/grid-cell.svelte.d.ts +0 -21
  34. package/package/components/core/group.svelte +0 -31
  35. package/package/components/core/group.svelte.d.ts +0 -23
  36. package/package/components/core/icon.svelte +0 -21
  37. package/package/components/core/icon.svelte.d.ts +0 -20
  38. package/package/components/core/menu-button.svelte +0 -57
  39. package/package/components/core/menu-button.svelte.d.ts +0 -30
  40. package/package/components/core/menu-item-checkbox.svelte +0 -24
  41. package/package/components/core/menu-item-checkbox.svelte.d.ts +0 -24
  42. package/package/components/core/menu-item-radio.svelte +0 -19
  43. package/package/components/core/menu-item-radio.svelte.d.ts +0 -24
  44. package/package/components/core/menu-item.svelte +0 -113
  45. package/package/components/core/menu-item.svelte.d.ts +0 -29
  46. package/package/components/core/number-input.svelte +0 -112
  47. package/package/components/core/number-input.svelte.d.ts +0 -28
  48. package/package/components/core/option.svelte +0 -59
  49. package/package/components/core/option.svelte.d.ts +0 -35
  50. package/package/components/core/password-input.svelte +0 -81
  51. package/package/components/core/password-input.svelte.d.ts +0 -25
  52. package/package/components/core/radio-button.svelte +0 -93
  53. package/package/components/core/radio-button.svelte.d.ts +0 -27
  54. package/package/components/core/row-group.svelte +0 -14
  55. package/package/components/core/row-group.svelte.d.ts +0 -21
  56. package/package/components/core/row.svelte +0 -14
  57. package/package/components/core/row.svelte.d.ts +0 -23
  58. package/package/components/core/search-bar.svelte +0 -90
  59. package/package/components/core/search-bar.svelte.d.ts +0 -35
  60. package/package/components/core/select-button.svelte +0 -31
  61. package/package/components/core/select-button.svelte.d.ts +0 -35
  62. package/package/components/core/separator.svelte +0 -28
  63. package/package/components/core/separator.svelte.d.ts +0 -20
  64. package/package/components/core/slider.svelte +0 -270
  65. package/package/components/core/slider.svelte.d.ts +0 -35
  66. package/package/components/core/spacer.svelte +0 -22
  67. package/package/components/core/spacer.svelte.d.ts +0 -19
  68. package/package/components/core/switch.svelte +0 -80
  69. package/package/components/core/switch.svelte.d.ts +0 -27
  70. package/package/components/core/tab-panel.svelte +0 -23
  71. package/package/components/core/tab-panel.svelte.d.ts +0 -25
  72. package/package/components/core/tab.svelte +0 -22
  73. package/package/components/core/tab.svelte.d.ts +0 -31
  74. package/package/components/core/text-area.svelte +0 -90
  75. package/package/components/core/text-area.svelte.d.ts +0 -43
  76. package/package/components/core/text-input.svelte +0 -145
  77. package/package/components/core/text-input.svelte.d.ts +0 -53
  78. package/package/components/core/toolbar.svelte +0 -74
  79. package/package/components/core/toolbar.svelte.d.ts +0 -26
  80. package/package/components/editor/markdown.svelte +0 -78
  81. package/package/components/editor/markdown.svelte.d.ts +0 -19
  82. package/package/components/helpers/group.d.ts +0 -37
  83. package/package/components/helpers/group.js +0 -246
  84. package/package/components/helpers/popup.d.ts +0 -26
  85. package/package/components/helpers/popup.js +0 -154
  86. package/package/components/helpers/util.d.ts +0 -1
  87. package/package/components/helpers/util.js +0 -8
  88. package/package/components/util/app-shell.svelte +0 -284
  89. package/package/components/util/app-shell.svelte.d.ts +0 -28
  90. package/package/components/util/misc.d.ts +0 -2
  91. package/package/components/util/misc.js +0 -22
  92. package/package/components/util/popup.svelte +0 -145
  93. package/package/components/util/popup.svelte.d.ts +0 -37
  94. package/package/components/util/portal.svelte +0 -34
  95. package/package/components/util/portal.svelte.d.ts +0 -21
  96. package/package/index.d.ts +0 -41
  97. package/package/index.js +0 -66
  98. package/package/locales/en.d.ts +0 -42
  99. package/package/locales/en.js +0 -41
  100. package/package/locales/ja.d.ts +0 -42
  101. package/package/locales/ja.js +0 -41
  102. package/package/styles/core.scss +0 -134
  103. package/package/styles/variables.scss +0 -114
  104. package/package/typedef.d.ts +0 -0
  105. package/package/typedef.js +0 -0
@@ -1,246 +0,0 @@
1
- /* eslint-disable no-plusplus */
2
- /* eslint-disable no-param-reassign */
3
-
4
- import { sleep } from '../util/misc';
5
- import { getRandomId } from './util';
6
-
7
- const config = {
8
- grid: {
9
- orientation: 'vertical',
10
- childRoles: ['row'],
11
- childSelectedAttr: 'aria-selected',
12
- },
13
- listbox: {
14
- orientation: 'vertical',
15
- childRoles: ['option'],
16
- childSelectedAttr: 'aria-selected',
17
- },
18
- menu: {
19
- orientation: 'vertical',
20
- childRoles: ['menuitem', 'menuitemcheckbox', 'menuitemradio'],
21
- childSelectedAttr: 'aria-checked',
22
- },
23
- menubar: {
24
- orientation: 'horizontal',
25
- childRoles: ['menuitem', 'menuitemcheckbox', 'menuitemradio'],
26
- childSelectedAttr: 'aria-checked',
27
- },
28
- radiogroup: {
29
- orientation: 'horizontal',
30
- childRoles: ['radio'],
31
- childSelectedAttr: 'aria-checked',
32
- },
33
- tablist: {
34
- orientation: 'horizontal',
35
- childRoles: ['tab'],
36
- childSelectedAttr: 'aria-selected',
37
- },
38
- };
39
-
40
- /**
41
- * Implement keyboard and mouse interactions for a grouping composite widget.
42
- */
43
- class Group {
44
- /**
45
- *
46
- * @param {HTMLElement} parent
47
- * @todo Check for added elements probably with `MutationObserver`.
48
- */
49
- constructor(parent) {
50
- this.parent = parent;
51
- this.role = parent.getAttribute('role');
52
- this.grid = this.role === 'listbox' && parent.matches('.grid');
53
- this.multi = this.parent.getAttribute('aria-multiselectable') === 'true';
54
- this.id = getRandomId(this.role);
55
- this.parentGroupSelector = `[role="group"], [role="${this.role}"]`;
56
-
57
- const { orientation, childSelectedAttr } = config[this.role];
58
-
59
- this.orientation = this.grid
60
- ? 'horizontal'
61
- : this.parent.getAttribute('aria-orientation') || orientation;
62
- this.childSelectedAttr = childSelectedAttr;
63
-
64
- const { allMembers } = this;
65
-
66
- const hasSelected = allMembers.some((element) =>
67
- element.matches(`[${childSelectedAttr}="true"]`),
68
- );
69
-
70
- allMembers.forEach((element, index) => {
71
- const isSelected = element.matches(`[${childSelectedAttr}="true"]`);
72
- const controls = document.querySelector(`#${element.getAttribute('aria-controls')}`);
73
-
74
- element.id ||= `${this.id}-item-${index}`;
75
- element.tabIndex ||= isSelected || (!hasSelected && index === 0) ? 0 : -1;
76
- element.setAttribute(this.childSelectedAttr, isSelected);
77
- controls?.setAttribute('aria-labelledby', element.id);
78
- controls?.setAttribute('aria-hidden', !isSelected);
79
- });
80
-
81
- parent.addEventListener('click', (event) => {
82
- this.onClick(event);
83
- });
84
-
85
- parent.addEventListener('keydown', (event) => {
86
- this.onKeyDown(event);
87
- });
88
- }
89
-
90
- /** @type {string} */
91
- get selector() {
92
- const roles = config[this.role].childRoles;
93
-
94
- return roles ? roles.map((role) => `[role="${role}"]`).join(',') : '';
95
- }
96
-
97
- /** @type {HTMLElement[]} */
98
- get allMembers() {
99
- return [...this.parent.querySelectorAll(this.selector)];
100
- }
101
-
102
- /** @type {HTMLElement[]} */
103
- get activeMembers() {
104
- return this.allMembers.filter((element) => !element.matches('[aria-disabled="true"]'));
105
- }
106
-
107
- /**
108
- *
109
- * @param {KeyboardEvent}
110
- */
111
- onClick(event) {
112
- const { target } = event;
113
-
114
- if (!target.matches(this.selector)) {
115
- return;
116
- }
117
-
118
- const targetParentGroup = target.closest(this.parentGroupSelector);
119
-
120
- this.allMembers.forEach((element) => {
121
- const isTarget = element === target;
122
-
123
- element.tabIndex = element === target ? 0 : -1;
124
-
125
- // Groups can be nested, e.g. `menu` > `group` > `menuitem`, so check if the parent is the
126
- // same as the target’s parent
127
- if (
128
- (element.matches('[role="radio"], [role="menuitemradio"]') ||
129
- (element.matches('[role="row"], [role="option"], [role="tab"]') && !this.multi)) &&
130
- element.closest(this.parentGroupSelector) === targetParentGroup
131
- ) {
132
- element.setAttribute(this.childSelectedAttr, isTarget);
133
- }
134
-
135
- const controls = element.getAttribute('aria-controls');
136
-
137
- if (controls) {
138
- document.getElementById(controls)?.setAttribute('aria-hidden', !isTarget);
139
- }
140
- });
141
-
142
- this.parent.dispatchEvent(
143
- new CustomEvent('select', {
144
- detail: {
145
- value: target.value,
146
- name: target.name,
147
- },
148
- }),
149
- );
150
- }
151
-
152
- /**
153
- *
154
- * @param {KeyboardEvent}
155
- */
156
- onKeyDown(event) {
157
- const { target, key, ctrlKey, metaKey, shiftKey, altKey } = event;
158
-
159
- if (target.matches(this.selector) && !ctrlKey && !metaKey && !shiftKey && !altKey) {
160
- if ([' ', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(key)) {
161
- event.preventDefault();
162
- }
163
-
164
- if (key === ' ' || (key === 'Enter' && !target.matches('button'))) {
165
- event.preventDefault();
166
- target.click();
167
-
168
- return;
169
- }
170
-
171
- const { allMembers, activeMembers } = this;
172
- let index;
173
- let newTarget;
174
-
175
- if (this.grid) {
176
- const colCount = Math.floor(this.parent.clientWidth / target.clientWidth);
177
-
178
- index = allMembers.indexOf(target);
179
-
180
- if (key === 'ArrowUp' && index > 0) {
181
- newTarget = allMembers[index - colCount];
182
- }
183
-
184
- if (key === 'ArrowDown' && index < allMembers.length - 1) {
185
- newTarget = allMembers[index + colCount];
186
- }
187
-
188
- if (key === 'ArrowLeft' && index > 0) {
189
- newTarget = allMembers[index - 1];
190
- }
191
-
192
- if (key === 'ArrowRight' && index < allMembers.length - 1) {
193
- newTarget = allMembers[index + 1];
194
- }
195
-
196
- if (newTarget?.getAttribute('aria-disabled') === 'true') {
197
- newTarget = undefined;
198
- }
199
- } else {
200
- index = activeMembers.indexOf(target);
201
-
202
- if (key === (this.orientation === 'horizontal' ? 'ArrowLeft' : 'ArrowUp')) {
203
- if (index > 0) {
204
- // Previous member
205
- newTarget = activeMembers[index - 1];
206
- }
207
-
208
- if (index === 0) {
209
- // Last member
210
- newTarget = activeMembers[activeMembers.length - 1];
211
- }
212
- }
213
-
214
- if (key === (this.orientation === 'horizontal' ? 'ArrowRight' : 'ArrowDown')) {
215
- if (index < activeMembers.length - 1) {
216
- // Next member
217
- newTarget = activeMembers[index + 1];
218
- }
219
-
220
- if (index === activeMembers.length - 1) {
221
- // First member
222
- [newTarget] = activeMembers;
223
- }
224
- }
225
- }
226
-
227
- if (newTarget && newTarget !== target) {
228
- activeMembers.forEach((element) => {
229
- element.tabIndex = element === newTarget ? 0 : -1;
230
- });
231
-
232
- newTarget.focus();
233
- }
234
- }
235
- }
236
- }
237
-
238
- /**
239
- *
240
- */
241
- export const activateGroup = async (...args) => {
242
- // Wait a bit before the relevant components, including the `aria-controls` target are mounted
243
- await sleep(100);
244
-
245
- return new Group(...args);
246
- };
@@ -1,26 +0,0 @@
1
- export function activatePopup(...args: any[]): Popup;
2
- export type PopupPosition = ('top-left' | 'top-right' | 'right-top' | 'right-bottom' | 'bottom-left' | 'bottom-right' | 'left-top' | 'left-bottom');
3
- /**
4
- * @typedef {('top-left'|'top-right'|'right-top'|'right-bottom'|'bottom-left'|'bottom-right'|'left-top'|'left-bottom')} PopupPosition
5
- */
6
- declare class Popup {
7
- /**
8
- *
9
- * @param {HTMLElement} anchorElement
10
- * @param {HTMLElement} popupElement
11
- * @param {PopupPosition} position
12
- */
13
- constructor(anchorElement: HTMLElement, popupElement: HTMLElement, position: PopupPosition);
14
- open: any;
15
- style: any;
16
- observer: IntersectionObserver;
17
- anchorElement: HTMLElement;
18
- popupElement: HTMLElement;
19
- position: PopupPosition;
20
- id: string;
21
- /**
22
- * Continue checking the position in case the window or parent element resizes.
23
- */
24
- checkPosition(): void;
25
- }
26
- export {};
@@ -1,154 +0,0 @@
1
- /* eslint-disable max-len */
2
- /* eslint-disable no-nested-ternary */
3
-
4
- import { get, writable } from 'svelte/store';
5
- import { getRandomId } from './util';
6
-
7
- /**
8
- * @typedef {('top-left'|'top-right'|'right-top'|'right-bottom'|'bottom-left'|'bottom-right'|'left-top'|'left-bottom')} PopupPosition
9
- */
10
-
11
- class Popup {
12
- open = writable(false);
13
-
14
- style = writable({ inset: undefined, zIndex: undefined, width: undefined, height: undefined });
15
-
16
- observer = new IntersectionObserver((entries) => {
17
- entries.forEach(({ intersectionRect, rootBounds }) => {
18
- if (!intersectionRect || !rootBounds) {
19
- return;
20
- }
21
-
22
- const contentHeight = this.popupElement.querySelector('.content').scrollHeight;
23
- const topMargin = intersectionRect.top - 8;
24
- const bottomMargin = rootBounds.height - intersectionRect.bottom - 8;
25
- let { position } = this;
26
- let height;
27
-
28
- // Alter the position if the space is limited
29
- // @todo Handle more overflow cases
30
- if (position.startsWith('bottom-')) {
31
- if (contentHeight > bottomMargin) {
32
- if (topMargin > bottomMargin) {
33
- position = position.replace('bottom-', 'top-');
34
- height = topMargin;
35
- } else {
36
- height = bottomMargin;
37
- }
38
- }
39
- }
40
-
41
- const top = position.startsWith('bottom-')
42
- ? `${Math.round(intersectionRect.bottom)}px`
43
- : position.endsWith('-top')
44
- ? `${Math.round(intersectionRect.top)}px`
45
- : 'auto';
46
-
47
- const right = position.startsWith('left-')
48
- ? `${Math.round(rootBounds.width - intersectionRect.left)}px`
49
- : position.endsWith('-right')
50
- ? `${Math.round(rootBounds.width - intersectionRect.right)}px`
51
- : 'auto';
52
-
53
- const bottom = position.startsWith('top-')
54
- ? `${Math.round(rootBounds.height - intersectionRect.top)}px`
55
- : position.endsWith('-bottom')
56
- ? `${Math.round(rootBounds.height - intersectionRect.bottom)}px`
57
- : 'auto';
58
-
59
- const left = position.startsWith('right-')
60
- ? `${Math.round(intersectionRect.right)}px`
61
- : position.endsWith('-left')
62
- ? `${Math.round(intersectionRect.left)}px`
63
- : 'auto';
64
-
65
- const anchorPopup = this.anchorElement.closest('.popup');
66
-
67
- const style = {
68
- inset: [top, right, bottom, left].join(' '),
69
- zIndex: anchorPopup ? Number(anchorPopup.style.zIndex) + 1 : 1000,
70
- width: `${Math.round(intersectionRect.width)}px`,
71
- height: height ? `${Math.round(height)}px` : 'auto',
72
- };
73
-
74
- if (JSON.stringify(style) !== JSON.stringify(get(this.style))) {
75
- this.style.set(style);
76
- }
77
- });
78
- });
79
-
80
- /**
81
- *
82
- * @param {HTMLElement} anchorElement
83
- * @param {HTMLElement} popupElement
84
- * @param {PopupPosition} position
85
- */
86
- constructor(anchorElement, popupElement, position) {
87
- this.anchorElement = anchorElement;
88
- this.popupElement = popupElement; // = backdrop
89
- this.position = position;
90
- this.id = getRandomId('popup');
91
-
92
- this.anchorElement.setAttribute('aria-controls', this.id);
93
- this.popupElement.setAttribute('id', this.id);
94
-
95
- this.anchorElement.addEventListener('click', () => {
96
- if (!this.anchorElement.matches('[aria-disabled="true"]')) {
97
- this.open.set(!get(this.open));
98
- }
99
- });
100
-
101
- this.popupElement.addEventListener('click', (event) => {
102
- if (get(this.open) && event.target !== this.anchorElement) {
103
- this.open.set(false);
104
- }
105
- });
106
-
107
- [this.anchorElement, this.popupElement].forEach((element) => {
108
- element.addEventListener('keydown', (event) => {
109
- const { key, ctrlKey, metaKey, shiftKey, altKey } = event;
110
-
111
- if (
112
- get(this.open) &&
113
- ['Escape'].includes(key) &&
114
- !ctrlKey &&
115
- !metaKey &&
116
- !shiftKey &&
117
- !altKey
118
- ) {
119
- this.open.set(false);
120
- }
121
- });
122
- });
123
-
124
- this.open.subscribe((open) => {
125
- if (open) {
126
- this.checkPosition();
127
- } else if (this.anchorElement.getAttribute('aria-expanded') === 'true') {
128
- this.anchorElement.focus();
129
- }
130
-
131
- this.anchorElement.setAttribute('aria-expanded', open);
132
- });
133
- }
134
-
135
- /**
136
- * Continue checking the position in case the window or parent element resizes.
137
- */
138
- checkPosition() {
139
- this.observer.observe(this.anchorElement);
140
-
141
- window.requestAnimationFrame(() => {
142
- this.observer.unobserve(this.anchorElement);
143
-
144
- if (get(this.open)) {
145
- this.checkPosition();
146
- }
147
- });
148
- }
149
- }
150
-
151
- /**
152
- *
153
- */
154
- export const activatePopup = (...args) => new Popup(...args);
@@ -1 +0,0 @@
1
- export function getRandomId(prefix?: string, length?: number): string;
@@ -1,8 +0,0 @@
1
- export const getRandomId = (prefix = '', length = 7) =>
2
- [
3
- prefix,
4
- new Array(length)
5
- .fill()
6
- .map(() => '0123456789abcdef'[Math.floor(Math.random() * 12)])
7
- .join(''),
8
- ].join('-');