@sveltia/ui 0.7.5 → 0.8.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 (112) hide show
  1. package/package/components/alert/alert.svelte +4 -4
  2. package/package/components/alert/alert.svelte.d.ts +2 -2
  3. package/package/components/button/button.svelte +5 -3
  4. package/package/components/button/button.svelte.d.ts +6 -4
  5. package/package/components/button/select-button-group.svelte +9 -5
  6. package/package/components/button/select-button.svelte +5 -4
  7. package/package/components/button/select-button.svelte.d.ts +2 -0
  8. package/package/components/calendar/calendar.svelte +20 -14
  9. package/package/components/checkbox/checkbox-group.svelte +6 -5
  10. package/package/components/checkbox/checkbox.svelte +6 -4
  11. package/package/components/checkbox/checkbox.svelte.d.ts +2 -2
  12. package/package/components/dialog/alert-dialog.svelte +50 -0
  13. package/package/components/dialog/alert-dialog.svelte.d.ts +55 -0
  14. package/package/components/dialog/confirmation-dialog.svelte +55 -0
  15. package/package/components/dialog/confirmation-dialog.svelte.d.ts +57 -0
  16. package/package/components/dialog/dialog.svelte +165 -221
  17. package/package/components/dialog/dialog.svelte.d.ts +20 -12
  18. package/package/components/dialog/prompt-dialog.svelte +78 -0
  19. package/package/components/dialog/prompt-dialog.svelte.d.ts +72 -0
  20. package/package/components/disclosure/disclosure.svelte +3 -2
  21. package/package/components/divider/divider.svelte +1 -1
  22. package/package/components/divider/spacer.svelte +1 -12
  23. package/package/components/divider/spacer.svelte.d.ts +0 -2
  24. package/package/components/drawer/drawer.svelte +119 -209
  25. package/package/components/drawer/drawer.svelte.d.ts +13 -9
  26. package/package/components/grid/grid-body.svelte +51 -0
  27. package/package/components/grid/grid-body.svelte.d.ts +36 -0
  28. package/package/components/grid/grid-cell.svelte +22 -0
  29. package/package/components/grid/grid-cell.svelte.d.ts +34 -0
  30. package/package/components/grid/grid-col-header.svelte +22 -0
  31. package/package/components/grid/grid-col-header.svelte.d.ts +34 -0
  32. package/package/components/grid/grid-foot.svelte +27 -0
  33. package/package/components/grid/grid-foot.svelte.d.ts +34 -0
  34. package/package/components/grid/grid-head.svelte +27 -0
  35. package/package/components/grid/grid-head.svelte.d.ts +34 -0
  36. package/package/components/grid/grid-row-header.svelte +23 -0
  37. package/package/components/grid/grid-row-header.svelte.d.ts +34 -0
  38. package/package/components/grid/grid-row.svelte +37 -0
  39. package/package/components/grid/grid-row.svelte.d.ts +44 -0
  40. package/package/components/grid/grid.svelte +52 -0
  41. package/package/components/grid/grid.svelte.d.ts +42 -0
  42. package/package/components/icon/icon.svelte +6 -7
  43. package/package/components/icon/icon.svelte.d.ts +0 -2
  44. package/package/components/listbox/listbox.svelte +3 -3
  45. package/package/components/listbox/option-group.svelte +6 -5
  46. package/package/components/listbox/option.svelte +7 -28
  47. package/package/components/listbox/option.svelte.d.ts +2 -0
  48. package/package/components/menu/menu-button.svelte +26 -16
  49. package/package/components/menu/menu-button.svelte.d.ts +2 -2
  50. package/package/components/menu/menu-item-checkbox.svelte +5 -4
  51. package/package/components/menu/menu-item-checkbox.svelte.d.ts +2 -0
  52. package/package/components/menu/menu-item-group.svelte +4 -3
  53. package/package/components/menu/menu-item-radio.svelte +5 -4
  54. package/package/components/menu/menu-item-radio.svelte.d.ts +2 -0
  55. package/package/components/menu/menu-item.svelte +7 -5
  56. package/package/components/menu/menu-item.svelte.d.ts +4 -2
  57. package/package/components/menu/menu.svelte +1 -1
  58. package/package/components/radio/radio-group.svelte +5 -5
  59. package/package/components/radio/radio.svelte +5 -2
  60. package/package/components/radio/radio.svelte.d.ts +2 -0
  61. package/package/components/select/combobox.svelte +11 -9
  62. package/package/components/slider/slider.svelte +12 -5
  63. package/package/components/switch/switch.svelte +3 -2
  64. package/package/components/switch/switch.svelte.d.ts +2 -2
  65. package/package/components/table/table-body.svelte +31 -3
  66. package/package/components/table/table-body.svelte.d.ts +2 -0
  67. package/package/components/table/table-cell.svelte +3 -4
  68. package/package/components/table/table-cell.svelte.d.ts +1 -1
  69. package/package/components/table/table-col-header.svelte +1 -2
  70. package/package/components/table/table-foot.svelte +7 -3
  71. package/package/components/table/table-head.svelte +7 -3
  72. package/package/components/table/table-row-header.svelte +1 -2
  73. package/package/components/table/table-row.svelte +1 -14
  74. package/package/components/table/table-row.svelte.d.ts +0 -8
  75. package/package/components/table/table.svelte +5 -17
  76. package/package/components/table/table.svelte.d.ts +1 -7
  77. package/package/components/tabs/tab-list.svelte +7 -5
  78. package/package/components/tabs/tab-panel.svelte +1 -1
  79. package/package/components/tabs/tab.svelte +2 -1
  80. package/package/components/tabs/tab.svelte.d.ts +2 -0
  81. package/package/components/text-field/markdown-editor.svelte +30 -6
  82. package/package/components/text-field/markdown-editor.svelte.d.ts +2 -0
  83. package/package/components/text-field/number-input.svelte +36 -6
  84. package/package/components/text-field/number-input.svelte.d.ts +2 -0
  85. package/package/components/text-field/password-input.svelte +34 -8
  86. package/package/components/text-field/password-input.svelte.d.ts +2 -0
  87. package/package/components/text-field/search-bar.svelte +39 -11
  88. package/package/components/text-field/search-bar.svelte.d.ts +5 -0
  89. package/package/components/text-field/text-area.svelte +21 -2
  90. package/package/components/text-field/text-area.svelte.d.ts +2 -0
  91. package/package/components/text-field/text-input.svelte +22 -4
  92. package/package/components/text-field/text-input.svelte.d.ts +7 -2
  93. package/package/components/toast/toast.svelte +6 -16
  94. package/package/components/toast/toast.svelte.d.ts +2 -2
  95. package/package/components/toolbar/toolbar.svelte +3 -4
  96. package/package/components/util/app-shell.svelte +26 -27
  97. package/package/components/util/group.svelte +2 -2
  98. package/package/components/util/modal.svelte +220 -0
  99. package/package/components/util/modal.svelte.d.ts +83 -0
  100. package/package/components/util/popup.svelte +81 -127
  101. package/package/components/util/popup.svelte.d.ts +22 -18
  102. package/package/components/util/portal.svelte +1 -1
  103. package/package/index.d.ts +12 -0
  104. package/package/index.js +12 -0
  105. package/package/locales/en.d.ts +1 -0
  106. package/package/locales/en.js +1 -0
  107. package/package/locales/ja.d.ts +1 -0
  108. package/package/locales/ja.js +1 -0
  109. package/package/services/group.js +51 -13
  110. package/package/styles/core.scss +9 -26
  111. package/package/styles/variables.scss +12 -0
  112. package/package.json +97 -1
@@ -0,0 +1,220 @@
1
+ <!--
2
+ @component
3
+ A generic modal top-layer helper based on the HTML `<dialog>` element.
4
+ -->
5
+ <svelte:options accessors={true} />
6
+
7
+ <script>
8
+ import { createEventDispatcher, onMount } from 'svelte';
9
+
10
+ /**
11
+ * The `class` attribute on the `<dialog>` element.
12
+ * @type {string}
13
+ */
14
+ let className = '';
15
+ export { className as class };
16
+ /**
17
+ * The `role` attribute on the `<dialog>` element.
18
+ * @type {'dialog' | 'alertdialog' | 'none'}
19
+ */
20
+ export let role = 'dialog';
21
+ /**
22
+ * Whether to show the modal.
23
+ * @type {boolean}
24
+ */
25
+ export let open = false;
26
+ /**
27
+ * Whether to show the backdrop.
28
+ * @type {boolean}
29
+ */
30
+ export let showBackdrop = false;
31
+ /**
32
+ * Whether to close the modal when the backdrop (outside of the modal) is clicked.
33
+ * @type {boolean}
34
+ */
35
+ export let lightDismiss = false;
36
+ /**
37
+ * Whether to close the modal when the Escape key is pressed.
38
+ * @type {boolean}
39
+ */
40
+ export let escapeDismiss = true;
41
+ /**
42
+ * Whether to keep the content in the DOM tree when the modal is not displayed.
43
+ * @type {boolean}
44
+ */
45
+ export let keepContent = false;
46
+ /**
47
+ * A reference to the `<dialog>` element.
48
+ * @type {HTMLDialogElement}
49
+ */
50
+ export let dialog = undefined;
51
+ /**
52
+ * Close the modal.
53
+ * @param {string} returnValue Return value to be used for `<dialog>`.
54
+ */
55
+ export const close = (returnValue) => {
56
+ dialog.returnValue = returnValue;
57
+ open = false;
58
+ };
59
+
60
+ const dispatch = createEventDispatcher();
61
+ let setOpenClass = false;
62
+ let setActiveClass = false;
63
+ let showContent = false;
64
+
65
+ /**
66
+ * Resolve once the transition is complete.
67
+ * @returns {Promise<void>} Nothing.
68
+ */
69
+ const waitForTransition = async () =>
70
+ new Promise((resolve) => {
71
+ /**
72
+ * @param {TransitionEvent} event `transition` event.
73
+ */
74
+ const listener = (event) => {
75
+ if (event.target === dialog) {
76
+ dialog.removeEventListener('transitionend', listener);
77
+ resolve();
78
+ }
79
+ };
80
+
81
+ dialog.addEventListener('transitionend', listener);
82
+ });
83
+
84
+ /**
85
+ * Show the modal.
86
+ */
87
+ const openDialog = async () => {
88
+ dispatch('opening');
89
+ (document.querySelector('.sui.app-shell') ?? document.body).appendChild(dialog);
90
+ showContent = true;
91
+ dialog.showModal();
92
+
93
+ window.requestAnimationFrame(async () => {
94
+ dispatch('open');
95
+ setOpenClass = true;
96
+ await waitForTransition();
97
+ setActiveClass = true;
98
+ });
99
+ };
100
+
101
+ /**
102
+ * Hide the modal.
103
+ */
104
+ const closeDialog = async () => {
105
+ dispatch('closing');
106
+ setActiveClass = false;
107
+ setOpenClass = false;
108
+ await waitForTransition();
109
+ showContent = false;
110
+ dialog.close();
111
+ dialog.remove();
112
+
113
+ if (['ok', 'cancel'].includes(dialog?.returnValue)) {
114
+ dispatch(dialog?.returnValue);
115
+ }
116
+
117
+ dispatch('close', dialog?.returnValue);
118
+ dialog.returnValue = undefined;
119
+ };
120
+
121
+ /**
122
+ * Toggle the modal.
123
+ */
124
+ const toggleDialog = () => {
125
+ if (dialog) {
126
+ if (open) {
127
+ openDialog();
128
+ } else {
129
+ closeDialog();
130
+ }
131
+ }
132
+ };
133
+
134
+ $: {
135
+ void open;
136
+ void dialog;
137
+ toggleDialog();
138
+ }
139
+
140
+ onMount(() => {
141
+ dialog.remove();
142
+
143
+ // onUnmount
144
+ return () => {
145
+ dialog?.close();
146
+ dialog?.remove();
147
+ };
148
+ });
149
+ </script>
150
+
151
+ <dialog
152
+ {role}
153
+ class="sui modal {className}"
154
+ class:backdrop={showBackdrop}
155
+ class:open={setOpenClass}
156
+ class:active={setActiveClass}
157
+ {...$$restProps}
158
+ bind:this={dialog}
159
+ on:click={({ target }) => {
160
+ if (lightDismiss && /** @type {HTMLElement?} */ (target)?.matches('dialog')) {
161
+ dialog.returnValue = 'cancel';
162
+ open = false;
163
+ }
164
+ }}
165
+ on:cancel|preventDefault={() => {
166
+ // Escape key is pressed
167
+ if (escapeDismiss) {
168
+ open = false;
169
+ }
170
+ }}
171
+ >
172
+ <slot name="always-show" />
173
+ {#if showContent || keepContent}
174
+ <slot />
175
+ {/if}
176
+ </dialog>
177
+
178
+ <style>dialog {
179
+ position: fixed;
180
+ inset: 0;
181
+ display: flex;
182
+ justify-content: center;
183
+ align-items: center;
184
+ overflow: hidden;
185
+ outline: 0;
186
+ margin: 0;
187
+ border: 0;
188
+ padding: 0;
189
+ width: 100dvw;
190
+ max-width: 100dvw;
191
+ height: 100dvh;
192
+ max-height: 100dvh;
193
+ color: var(--sui-primary-foreground-color);
194
+ background: transparent;
195
+ -webkit-user-select: none;
196
+ user-select: none;
197
+ touch-action: none;
198
+ pointer-events: all;
199
+ cursor: default;
200
+ }
201
+ dialog::backdrop {
202
+ background: transparent;
203
+ }
204
+ dialog.backdrop {
205
+ background-color: var(--sui-popup-backdrop-color);
206
+ }
207
+ dialog.open {
208
+ transition-duration: 200ms;
209
+ opacity: 1;
210
+ }
211
+ dialog:not(.open) {
212
+ transition-duration: 400ms;
213
+ opacity: 0;
214
+ }
215
+ dialog:not(.active) {
216
+ pointer-events: none !important;
217
+ }
218
+ dialog:not(.active) :global(*) {
219
+ pointer-events: none !important;
220
+ }</style>
@@ -0,0 +1,83 @@
1
+ /** @typedef {typeof __propDef.props} ModalProps */
2
+ /** @typedef {typeof __propDef.events} ModalEvents */
3
+ /** @typedef {typeof __propDef.slots} ModalSlots */
4
+ /** A generic modal top-layer helper based on the HTML `<dialog>` element. */
5
+ export default class Modal extends SvelteComponent<{
6
+ [x: string]: any;
7
+ class?: string;
8
+ close?: (returnValue: string) => void;
9
+ dialog?: HTMLDialogElement;
10
+ role?: "dialog" | "none" | "alertdialog";
11
+ open?: boolean;
12
+ showBackdrop?: boolean;
13
+ lightDismiss?: boolean;
14
+ escapeDismiss?: boolean;
15
+ keepContent?: boolean;
16
+ }, {
17
+ opening: CustomEvent<any>;
18
+ open: CustomEvent<any>;
19
+ closing: CustomEvent<any>;
20
+ close: CustomEvent<any>;
21
+ } & {
22
+ [evt: string]: CustomEvent<any>;
23
+ }, {
24
+ 'always-show': {};
25
+ default: {};
26
+ }> {
27
+ get close(): (returnValue: string) => void;
28
+ /**accessor*/
29
+ set class(arg: string);
30
+ get class(): string;
31
+ /**accessor*/
32
+ set role(arg: "dialog" | "none" | "alertdialog");
33
+ get role(): "dialog" | "none" | "alertdialog";
34
+ /**accessor*/
35
+ set open(arg: boolean);
36
+ get open(): boolean;
37
+ /**accessor*/
38
+ set showBackdrop(arg: boolean);
39
+ get showBackdrop(): boolean;
40
+ /**accessor*/
41
+ set lightDismiss(arg: boolean);
42
+ get lightDismiss(): boolean;
43
+ /**accessor*/
44
+ set escapeDismiss(arg: boolean);
45
+ get escapeDismiss(): boolean;
46
+ /**accessor*/
47
+ set keepContent(arg: boolean);
48
+ get keepContent(): boolean;
49
+ /**accessor*/
50
+ set dialog(arg: HTMLDialogElement);
51
+ get dialog(): HTMLDialogElement;
52
+ }
53
+ export type ModalProps = typeof __propDef.props;
54
+ export type ModalEvents = typeof __propDef.events;
55
+ export type ModalSlots = typeof __propDef.slots;
56
+ import { SvelteComponent } from "svelte";
57
+ declare const __propDef: {
58
+ props: {
59
+ [x: string]: any;
60
+ class?: string;
61
+ close?: (returnValue: string) => void;
62
+ dialog?: HTMLDialogElement;
63
+ role?: 'dialog' | 'alertdialog' | 'none';
64
+ open?: boolean;
65
+ showBackdrop?: boolean;
66
+ lightDismiss?: boolean;
67
+ escapeDismiss?: boolean;
68
+ keepContent?: boolean;
69
+ };
70
+ events: {
71
+ opening: CustomEvent<any>;
72
+ open: CustomEvent<any>;
73
+ closing: CustomEvent<any>;
74
+ close: CustomEvent<any>;
75
+ } & {
76
+ [evt: string]: CustomEvent<any>;
77
+ };
78
+ slots: {
79
+ 'always-show': {};
80
+ default: {};
81
+ };
82
+ };
83
+ export {};
@@ -9,40 +9,34 @@
9
9
  import { writable } from 'svelte/store';
10
10
  import { activatePopup } from '../../services/popup';
11
11
  import { sleep } from '../../services/util';
12
+ import Modal from './modal.svelte';
12
13
 
13
14
  /**
14
- * The `class` attribute on the `<button>` element.
15
+ * The `class` attribute on the content element.
15
16
  * @type {string}
16
17
  */
17
18
  let className = '';
18
19
  export { className as class };
19
-
20
- /** @type {HTMLElement | undefined} */
21
- export let anchor = undefined;
22
-
23
20
  /**
24
- * Reference to the popup element.
25
- * @type {HTMLDialogElement | undefined}
21
+ * Whether to open the popup.
22
+ * @type {import('svelte/store').Writable<boolean>}
26
23
  */
27
- export let dialog = undefined;
28
-
24
+ export let open = writable(false);
25
+ /**
26
+ * A reference to the anchor element that opens the popup. Typically a `<button>`.
27
+ * @type {HTMLElement}
28
+ */
29
+ export let anchor;
29
30
  /**
30
- * Reference to the content element.
31
- * @type {HTMLElement | undefined}
31
+ * A reference to the content element.
32
+ * @type {HTMLElement}
32
33
  */
33
34
  export let content = undefined;
34
-
35
35
  /**
36
- * Where to show the dropdown menu.
36
+ * Where to show the popup.
37
37
  * @type {PopupPosition}
38
38
  */
39
39
  export let position = 'bottom-left';
40
-
41
- /**
42
- * Whether to keep the content when the dialog is not displayed.
43
- */
44
- export let keepContent = false;
45
-
46
40
  /**
47
41
  * Whether to show the popup at the center of the screen on mobile/tablet and ignore the defined
48
42
  * dropdown `position`.
@@ -50,14 +44,27 @@
50
44
  */
51
45
  export let touchOptimized = false;
52
46
 
53
- export let open = writable(false);
54
-
55
- let showDialog = false;
56
- let showContent = false;
47
+ /**
48
+ * A reference to the modal component.
49
+ * @type {Modal}
50
+ */
51
+ let modal;
52
+ /**
53
+ * Whether the touch is enabled on the user device.
54
+ * @type {boolean}
55
+ */
57
56
  let touchEnabled = false;
58
- /** @type {string | undefined} */
57
+ /**
58
+ * The type of the content displayed in the popup, defined with the `aria-haspopup` attribute on
59
+ * the anchor element.
60
+ * @type {string}
61
+ * @see https://w3c.github.io/aria/#aria-haspopup
62
+ */
59
63
  let contentType;
60
-
64
+ /**
65
+ * Style to be applied to the content.
66
+ * @type {import('svelte/store').Writable<any>}
67
+ */
61
68
  let style = writable({
62
69
  inset: undefined,
63
70
  zIndex: undefined,
@@ -66,156 +73,103 @@
66
73
  });
67
74
 
68
75
  $: {
69
- if (anchor && dialog) {
70
- ({ open, style } = activatePopup(anchor, dialog, position));
76
+ if (anchor && modal?.dialog) {
77
+ ({ open, style } = activatePopup(anchor, modal.dialog, position));
71
78
  contentType = anchor.getAttribute('aria-haspopup');
72
79
  }
73
80
  }
74
81
 
75
- /**
76
- *
77
- */
78
- const openDialog = () => {
79
- (document.querySelector('.sui.app-shell') ?? document.body).appendChild(dialog);
80
- showContent = true;
81
- dialog.showModal();
82
-
83
- window.requestAnimationFrame(async () => {
84
- showDialog = true;
85
- await sleep(100);
86
-
87
- const target = /** @type {HTMLElement} */ (
88
- content.querySelector('[tabindex]:not([aria-disabled="true"])')
89
- );
90
-
91
- if (target) {
92
- target.focus();
93
- } else {
94
- content.tabIndex = -1;
95
- content.focus();
96
- }
97
- });
98
- };
99
-
100
- /**
101
- *
102
- */
103
- const closeDialog = async () => {
104
- showDialog = false;
105
-
106
- await new Promise((resolve) => {
107
- content.addEventListener('transitionend', () => resolve(), { once: true });
108
- });
109
-
110
- showContent = false;
111
- dialog?.close();
112
- dialog?.remove();
113
- };
114
-
115
- /**
116
- *
117
- */
118
- const toggleDialog = () => {
119
- if (dialog) {
120
- if ($open) {
121
- openDialog();
122
- } else {
123
- closeDialog();
124
- }
125
- }
126
- };
127
-
128
- $: {
129
- void $open;
130
- toggleDialog();
131
- }
82
+ $: touch = touchOptimized && touchEnabled;
132
83
 
133
84
  onMount(() => {
134
- dialog.remove();
135
-
136
85
  touchEnabled = window.matchMedia('(pointer: coarse)').matches;
137
-
138
- // onUnmount
139
- return () => {
140
- dialog?.close();
141
- dialog?.remove();
142
- };
143
86
  });
144
87
  </script>
145
88
 
146
- <dialog
147
- class="sui popup {className}"
89
+ <Modal
148
90
  role="none"
149
- bind:this={dialog}
150
- class:touch={touchOptimized && touchEnabled}
151
- class:open={showDialog}
91
+ class="popup"
92
+ bind:open={$open}
93
+ showBackdrop={touch}
94
+ lightDismiss={true}
95
+ keepContent={true}
96
+ bind:this={modal}
152
97
  {...$$restProps}
98
+ on:opening
99
+ on:open
100
+ on:ok
101
+ on:cancel
102
+ on:closing
103
+ on:close
104
+ on:open={async () => {
105
+ await sleep(100);
106
+
107
+ const target = /** @type {HTMLElement} */ (
108
+ content.querySelector('[tabindex]:not([aria-disabled="true"])')
109
+ );
110
+
111
+ if (target) {
112
+ target.focus();
113
+ } else {
114
+ content.tabIndex = -1;
115
+ content.focus();
116
+ }
117
+ }}
153
118
  >
154
119
  <div
155
- bind:this={content}
156
- class="content {contentType}"
120
+ role="none"
121
+ class="content {className} {contentType}"
122
+ class:touch
157
123
  style:inset={$style.inset}
158
124
  style:z-index={$style.zIndex}
159
125
  style:min-width={$style.width}
160
126
  style:max-height={$style.height}
161
127
  style:visibility={$style.inset ? undefined : 'hidden'}
128
+ bind:this={content}
162
129
  >
163
- {#if keepContent || showContent}
164
- <slot />
165
- {/if}
130
+ <slot />
166
131
  </div>
167
- </dialog>
132
+ </Modal>
168
133
 
169
- <style>.popup.touch {
170
- display: flex;
171
- align-items: center;
172
- justify-content: center;
173
- background-color: var(--sui-popup-backdrop-color);
174
- }
175
- .popup.touch .content {
134
+ <style>.content.touch {
176
135
  position: static;
177
136
  border-width: 0 !important;
178
137
  border-radius: 4px !important;
179
138
  padding: 8px;
180
139
  min-width: 320px !important;
181
- max-width: calc(100vw - 32px) !important;
182
- max-height: calc(100vh - 32px) !important;
140
+ max-width: calc(100dvw - 32px) !important;
141
+ max-height: calc(100dvh - 32px) !important;
183
142
  }
184
- .popup.touch.open .content {
143
+ :global(dialog.open) .content.touch {
185
144
  transform: scale(100%) !important;
186
145
  }
187
- .popup.touch:not(.open) .content {
146
+ :global(dialog:not(.open)) .content.touch {
188
147
  transform: scale(90%);
189
148
  }
190
- .popup.touch.combobox :global(.sui.listbox) {
149
+ .content.touch.combobox :global(.sui.listbox) {
191
150
  gap: 4px;
192
151
  padding: 8px 4px !important;
193
152
  }
194
- .popup.open .content {
153
+ :global(dialog.open) .content {
154
+ transition-duration: 150ms;
195
155
  opacity: 1;
196
156
  transform: translateY(2px);
197
- transition-duration: 100ms;
198
- }
199
- .popup:not(.open) {
200
- pointer-events: none;
201
157
  }
202
- .popup:not(.open) .content {
158
+ :global(dialog:not(.open)) .content {
159
+ transition-duration: 300ms;
203
160
  opacity: 0;
204
161
  transform: translateY(-8px);
205
- pointer-events: none;
206
- transition-duration: 200ms;
207
162
  }
208
163
 
209
164
  .content {
210
- position: fixed;
165
+ position: absolute;
211
166
  overflow-y: auto;
212
167
  outline-width: 0 !important;
213
168
  color: var(--sui-primary-foreground-color);
214
169
  background-color: var(--sui-secondary-background-color-translucent);
215
- -webkit-backdrop-filter: blur(32px);
216
- backdrop-filter: blur(32px);
217
170
  box-shadow: 0 8px 16px var(--sui-popup-shadow-color);
218
- will-change: opacity, transform;
171
+ -webkit-backdrop-filter: blur(16px);
172
+ backdrop-filter: blur(16px);
219
173
  transition-property: opacity, transform;
220
174
  }
221
175
  .content.listbox, .content.menu {
@@ -4,15 +4,20 @@
4
4
  /** Generic popup helper. */
5
5
  export default class Popup extends SvelteComponent<{
6
6
  [x: string]: any;
7
+ anchor: HTMLElement;
7
8
  class?: string;
8
- dialog?: HTMLDialogElement;
9
9
  position?: PopupPosition;
10
- anchor?: HTMLElement;
10
+ open?: import("svelte/store").Writable<boolean>;
11
11
  content?: HTMLElement;
12
- keepContent?: boolean;
13
12
  touchOptimized?: boolean;
14
- open?: import("svelte/store").Writable<boolean>;
15
13
  }, {
14
+ opening: CustomEvent<any>;
15
+ open: CustomEvent<any>;
16
+ ok: CustomEvent<any>;
17
+ cancel: CustomEvent<any>;
18
+ closing: CustomEvent<any>;
19
+ close: CustomEvent<any>;
20
+ } & {
16
21
  [evt: string]: CustomEvent<any>;
17
22
  }, {
18
23
  default: {};
@@ -21,26 +26,20 @@ export default class Popup extends SvelteComponent<{
21
26
  set class(arg: string);
22
27
  get class(): string;
23
28
  /**accessor*/
29
+ set open(arg: import("svelte/store").Writable<boolean>);
30
+ get open(): import("svelte/store").Writable<boolean>;
31
+ /**accessor*/
24
32
  set anchor(arg: HTMLElement);
25
33
  get anchor(): HTMLElement;
26
34
  /**accessor*/
27
- set dialog(arg: HTMLDialogElement);
28
- get dialog(): HTMLDialogElement;
29
- /**accessor*/
30
35
  set content(arg: HTMLElement);
31
36
  get content(): HTMLElement;
32
37
  /**accessor*/
33
38
  set position(arg: PopupPosition);
34
39
  get position(): PopupPosition;
35
40
  /**accessor*/
36
- set keepContent(arg: boolean);
37
- get keepContent(): boolean;
38
- /**accessor*/
39
41
  set touchOptimized(arg: boolean);
40
42
  get touchOptimized(): boolean;
41
- /**accessor*/
42
- set open(arg: import("svelte/store").Writable<boolean>);
43
- get open(): import("svelte/store").Writable<boolean>;
44
43
  }
45
44
  export type PopupProps = typeof __propDef.props;
46
45
  export type PopupEvents = typeof __propDef.events;
@@ -49,16 +48,21 @@ import { SvelteComponent } from "svelte";
49
48
  declare const __propDef: {
50
49
  props: {
51
50
  [x: string]: any;
51
+ anchor: HTMLElement;
52
52
  class?: string;
53
- dialog?: HTMLDialogElement | undefined;
54
53
  position?: PopupPosition;
55
- anchor?: HTMLElement | undefined;
56
- content?: HTMLElement | undefined;
57
- keepContent?: boolean;
54
+ open?: import('svelte/store').Writable<boolean>;
55
+ content?: HTMLElement;
58
56
  touchOptimized?: boolean;
59
- open?: import("svelte/store").Writable<boolean>;
60
57
  };
61
58
  events: {
59
+ opening: CustomEvent<any>;
60
+ open: CustomEvent<any>;
61
+ ok: CustomEvent<any>;
62
+ cancel: CustomEvent<any>;
63
+ closing: CustomEvent<any>;
64
+ close: CustomEvent<any>;
65
+ } & {
62
66
  [evt: string]: CustomEvent<any>;
63
67
  };
64
68
  slots: {
@@ -25,7 +25,7 @@
25
25
  });
26
26
  </script>
27
27
 
28
- <div class="sui portal {className}" {...$$restProps} bind:this={ref}>
28
+ <div role="none" class="sui portal {className}" {...$$restProps} bind:this={ref}>
29
29
  <slot />
30
30
  </div>
31
31