@insymetri/styleguide 0.1.78 → 0.1.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/IIDropdownInput/IIDropdownInput.svelte +51 -2
- package/dist/IIDropdownInput/IIDropdownInput.svelte.d.ts +21 -0
- package/dist/IIDropdownInput/IIDropdownInputStories.svelte +23 -0
- package/dist/{IIDropdownMenu/IIDropdownMenu.svelte → IIMenu/IIMenu.svelte} +12 -6
- package/dist/{IIDropdownMenu/IIDropdownMenu.svelte.d.ts → IIMenu/IIMenu.svelte.d.ts} +7 -3
- package/dist/{IIDropdownMenu/IIDropdownMenuStories.svelte → IIMenu/IIMenuStories.svelte} +7 -7
- package/dist/{IIDropdownMenu/IIDropdownMenuStories.svelte.d.ts → IIMenu/IIMenuStories.svelte.d.ts} +3 -3
- package/dist/{IIDropdownMenu/IIDropdownMenuSub.svelte.d.ts → IIMenu/IIMenuSub.svelte.d.ts} +3 -3
- package/dist/{IIDropdownMenu/IIDropdownMenuSubSimple.svelte.d.ts → IIMenu/IIMenuSubSimple.svelte.d.ts} +3 -3
- package/dist/IIMenu/index.d.ts +1 -0
- package/dist/IIMenu/index.js +1 -0
- package/dist/IIModal/IIModal.svelte +23 -10
- package/dist/IIModal/IIModal.svelte.d.ts +6 -1
- package/dist/IIModal/IIModalFocusStories.svelte +12 -11
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/style/base.css +23 -0
- package/dist/style/tailwind/animations.d.ts +3 -3
- package/dist/style/tailwind/animations.js +18 -7
- package/dist/style/tailwind/preset.d.ts +3 -3
- package/dist/utils/menu/MenuSearchInput.svelte +1 -1
- package/dist/utils/menu/menu-styles.d.ts +3 -3
- package/dist/utils/menu/menu-styles.js +6 -3
- package/dist/utils/menu/use-floating.svelte.d.ts +4 -0
- package/dist/utils/menu/use-floating.svelte.js +11 -5
- package/package.json +1 -1
- package/dist/IIDropdownMenu/index.d.ts +0 -1
- package/dist/IIDropdownMenu/index.js +0 -1
- /package/dist/{IIDropdownMenu/IIDropdownMenuSub.svelte → IIMenu/IIMenuSub.svelte} +0 -0
- /package/dist/{IIDropdownMenu/IIDropdownMenuSubSimple.svelte → IIMenu/IIMenuSubSimple.svelte} +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type {Snippet} from 'svelte'
|
|
3
|
+
import {createAttachmentKey} from 'svelte/attachments'
|
|
3
4
|
import {fly} from 'svelte/transition'
|
|
4
5
|
import {IIIcon} from '../IIIcon'
|
|
5
6
|
import {cn} from '../utils/cn'
|
|
@@ -18,15 +19,34 @@
|
|
|
18
19
|
disabled?: boolean
|
|
19
20
|
error?: boolean
|
|
20
21
|
errorMessage?: string
|
|
22
|
+
/** Fired when the selected value changes. */
|
|
23
|
+
onValueChange?: (value: string) => void
|
|
24
|
+
/** @deprecated Use `onValueChange`. */
|
|
21
25
|
onSelect?: (value: string) => void
|
|
22
26
|
onblur?: () => void
|
|
23
27
|
matchTriggerWidth?: boolean
|
|
24
28
|
renderItem?: Snippet<[item: MenuItem, selected: boolean]>
|
|
25
29
|
renderSelected?: Snippet<[item: MenuItem]>
|
|
30
|
+
/**
|
|
31
|
+
* Replace the default combobox field with a custom trigger. Spread `props`
|
|
32
|
+
* onto your trigger element/component — it carries the ref, click/keydown
|
|
33
|
+
* handlers, and combobox aria attributes. `open`, `selectedItem`, and
|
|
34
|
+
* `selectedLabel` are provided for rendering. When set, `class`, `label`,
|
|
35
|
+
* and `renderSelected` no longer affect the (now custom) trigger.
|
|
36
|
+
*/
|
|
37
|
+
trigger?: Snippet<[{
|
|
38
|
+
props: Record<string, unknown>
|
|
39
|
+
open: boolean
|
|
40
|
+
selectedItem: MenuItem | undefined
|
|
41
|
+
selectedLabel: string
|
|
42
|
+
}]>
|
|
26
43
|
searchable?: boolean
|
|
27
44
|
searchPlaceholder?: string
|
|
28
45
|
autofocus?: boolean
|
|
46
|
+
/** Classes for the trigger (root) element. */
|
|
29
47
|
class?: string
|
|
48
|
+
/** Classes for the dropdown panel (popover surface). */
|
|
49
|
+
contentClass?: string
|
|
30
50
|
}
|
|
31
51
|
|
|
32
52
|
let {
|
|
@@ -37,15 +57,18 @@
|
|
|
37
57
|
disabled = false,
|
|
38
58
|
error = false,
|
|
39
59
|
errorMessage,
|
|
60
|
+
onValueChange,
|
|
40
61
|
onSelect,
|
|
41
62
|
onblur,
|
|
42
63
|
matchTriggerWidth = false,
|
|
43
64
|
renderItem,
|
|
44
65
|
renderSelected,
|
|
66
|
+
trigger,
|
|
45
67
|
searchable = false,
|
|
46
68
|
searchPlaceholder = 'Search...',
|
|
47
69
|
autofocus = false,
|
|
48
70
|
class: className,
|
|
71
|
+
contentClass,
|
|
49
72
|
}: Props = $props()
|
|
50
73
|
|
|
51
74
|
const showError = $derived(error || !!errorMessage)
|
|
@@ -79,6 +102,25 @@
|
|
|
79
102
|
const selectedItem = $derived(items.find(i => i.value === value))
|
|
80
103
|
const selectedLabel = $derived(selectedItem?.label ?? placeholder)
|
|
81
104
|
|
|
105
|
+
// Props a custom `trigger` snippet spreads onto its element. The attachment
|
|
106
|
+
// key and function are stable, so recomputing this derived object when `open`
|
|
107
|
+
// changes (for aria-expanded) does not re-run the ref attachment.
|
|
108
|
+
const attachTrigger = (node: Element) => {
|
|
109
|
+
triggerEl = node as HTMLElement
|
|
110
|
+
return () => { if (triggerEl === node) triggerEl = null }
|
|
111
|
+
}
|
|
112
|
+
const triggerAttachmentKey = createAttachmentKey()
|
|
113
|
+
const triggerProps = $derived({
|
|
114
|
+
role: 'combobox',
|
|
115
|
+
'aria-haspopup': 'listbox',
|
|
116
|
+
'aria-expanded': open,
|
|
117
|
+
type: 'button',
|
|
118
|
+
disabled: disabled || undefined,
|
|
119
|
+
onclick: toggle,
|
|
120
|
+
onkeydown: handleTriggerKeydown,
|
|
121
|
+
[triggerAttachmentKey]: attachTrigger,
|
|
122
|
+
})
|
|
123
|
+
|
|
82
124
|
function scrollHighlightedIntoView() {
|
|
83
125
|
requestAnimationFrame(() => {
|
|
84
126
|
const el = floatingEl?.querySelector<HTMLElement>(`[role="option"][data-index="${highlightedIndex}"]`)
|
|
@@ -111,12 +153,14 @@
|
|
|
111
153
|
placement: 'bottom-start',
|
|
112
154
|
offset: 2,
|
|
113
155
|
matchWidth: matchTriggerWidth,
|
|
156
|
+
constrainHeight: true,
|
|
114
157
|
})
|
|
115
158
|
|
|
116
159
|
function handleSelect(item: MenuItem) {
|
|
117
160
|
if (item.disabled) return
|
|
118
161
|
value = item.value
|
|
119
162
|
open = false
|
|
163
|
+
onValueChange?.(item.value)
|
|
120
164
|
onSelect?.(item.value)
|
|
121
165
|
onblur?.()
|
|
122
166
|
triggerEl?.focus()
|
|
@@ -151,6 +195,7 @@
|
|
|
151
195
|
const match = items[matchIndex]
|
|
152
196
|
if (!wasOpen) {
|
|
153
197
|
value = match.value
|
|
198
|
+
onValueChange?.(match.value)
|
|
154
199
|
onSelect?.(match.value)
|
|
155
200
|
} else {
|
|
156
201
|
highlightedIndex = matchIndex
|
|
@@ -239,6 +284,9 @@
|
|
|
239
284
|
{#if label}
|
|
240
285
|
<span class="text-small-emphasis text-secondary mb-4">{label}</span>
|
|
241
286
|
{/if}
|
|
287
|
+
{#if trigger}
|
|
288
|
+
{@render trigger({props: triggerProps, open, selectedItem, selectedLabel})}
|
|
289
|
+
{:else}
|
|
242
290
|
<button
|
|
243
291
|
bind:this={triggerEl}
|
|
244
292
|
type="button"
|
|
@@ -265,6 +313,7 @@
|
|
|
265
313
|
{/if}
|
|
266
314
|
<IIIcon iconName="caret-down" />
|
|
267
315
|
</button>
|
|
316
|
+
{/if}
|
|
268
317
|
|
|
269
318
|
{#if open}
|
|
270
319
|
<div use:portal use:clickOutside={{onClose: close, ignore: () => triggerEl}}>
|
|
@@ -272,7 +321,7 @@
|
|
|
272
321
|
bind:this={floatingEl}
|
|
273
322
|
role="listbox"
|
|
274
323
|
data-menu-content
|
|
275
|
-
class=
|
|
324
|
+
class={cn('flex flex-col min-w-100 bg-dropdown-bg border-[0.5px] border-dropdown-border rounded-10 shadow-dropdown p-4 z-16 pointer-events-auto outline-none overflow-hidden', contentClass)}
|
|
276
325
|
transition:fly={{y: -4, duration: 150}}
|
|
277
326
|
>
|
|
278
327
|
{#if searchable}
|
|
@@ -283,7 +332,7 @@
|
|
|
283
332
|
onkeydown={(e) => search.handleKeydown(e, '[data-menu-content]')}
|
|
284
333
|
/>
|
|
285
334
|
{/if}
|
|
286
|
-
<div class="
|
|
335
|
+
<div class="ii-menu-scroll min-h-0 overflow-y-auto -mr-2">
|
|
287
336
|
{#each (searchable ? search.filteredItems as MenuItem[] : items) as item, listIndex (item.value)}
|
|
288
337
|
{@const index = searchable ? search.getItemIndex(item) : listIndex}
|
|
289
338
|
{@const isHighlighted = searchable
|
|
@@ -8,15 +8,36 @@ type Props = {
|
|
|
8
8
|
disabled?: boolean;
|
|
9
9
|
error?: boolean;
|
|
10
10
|
errorMessage?: string;
|
|
11
|
+
/** Fired when the selected value changes. */
|
|
12
|
+
onValueChange?: (value: string) => void;
|
|
13
|
+
/** @deprecated Use `onValueChange`. */
|
|
11
14
|
onSelect?: (value: string) => void;
|
|
12
15
|
onblur?: () => void;
|
|
13
16
|
matchTriggerWidth?: boolean;
|
|
14
17
|
renderItem?: Snippet<[item: MenuItem, selected: boolean]>;
|
|
15
18
|
renderSelected?: Snippet<[item: MenuItem]>;
|
|
19
|
+
/**
|
|
20
|
+
* Replace the default combobox field with a custom trigger. Spread `props`
|
|
21
|
+
* onto your trigger element/component — it carries the ref, click/keydown
|
|
22
|
+
* handlers, and combobox aria attributes. `open`, `selectedItem`, and
|
|
23
|
+
* `selectedLabel` are provided for rendering. When set, `class`, `label`,
|
|
24
|
+
* and `renderSelected` no longer affect the (now custom) trigger.
|
|
25
|
+
*/
|
|
26
|
+
trigger?: Snippet<[
|
|
27
|
+
{
|
|
28
|
+
props: Record<string, unknown>;
|
|
29
|
+
open: boolean;
|
|
30
|
+
selectedItem: MenuItem | undefined;
|
|
31
|
+
selectedLabel: string;
|
|
32
|
+
}
|
|
33
|
+
]>;
|
|
16
34
|
searchable?: boolean;
|
|
17
35
|
searchPlaceholder?: string;
|
|
18
36
|
autofocus?: boolean;
|
|
37
|
+
/** Classes for the trigger (root) element. */
|
|
19
38
|
class?: string;
|
|
39
|
+
/** Classes for the dropdown panel (popover surface). */
|
|
40
|
+
contentClass?: string;
|
|
20
41
|
};
|
|
21
42
|
declare const IIDropdownInput: import("svelte").Component<Props, {}, "value">;
|
|
22
43
|
type IIDropdownInput = ReturnType<typeof IIDropdownInput>;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import IIDropdownInput from './IIDropdownInput.svelte'
|
|
3
3
|
import {IIIcon} from '../IIIcon'
|
|
4
|
+
import {cn} from '../utils/cn'
|
|
4
5
|
import type {IconName} from '../icons'
|
|
5
6
|
|
|
6
7
|
let basicValue = $state<string | undefined>(undefined)
|
|
7
8
|
let disabledItemValue = $state<string | undefined>(undefined)
|
|
9
|
+
let customTriggerValue = $state<string | undefined>(undefined)
|
|
8
10
|
|
|
9
11
|
const statusItems = [
|
|
10
12
|
{label: 'Active', value: 'active'},
|
|
@@ -85,4 +87,25 @@
|
|
|
85
87
|
</IIDropdownInput>
|
|
86
88
|
</div>
|
|
87
89
|
</section>
|
|
90
|
+
|
|
91
|
+
<!-- Custom Trigger -->
|
|
92
|
+
<section>
|
|
93
|
+
<h2 class="text-default-emphasis text-primary mb-8">Custom Trigger</h2>
|
|
94
|
+
<p class="text-small text-secondary mb-12">Use the <code>trigger</code> snippet to replace the default field with any element. Spread <code>props</code> to wire up the ref, click/keyboard handling, and combobox aria attributes.</p>
|
|
95
|
+
<IIDropdownInput items={statusItems} bind:value={customTriggerValue}>
|
|
96
|
+
{#snippet trigger({props, open, selectedItem, selectedLabel})}
|
|
97
|
+
<button
|
|
98
|
+
{...props}
|
|
99
|
+
class={cn(
|
|
100
|
+
'inline-flex items-center gap-6 py-6 px-12 rounded-control border border-button-secondary bg-input-bg text-small text-button-secondary cursor-default outline-none transition-colors hover:border-button-secondary-hover focus-visible:ring-3 focus-visible:ring-primary',
|
|
101
|
+
open && 'border-button-secondary-hover'
|
|
102
|
+
)}
|
|
103
|
+
>
|
|
104
|
+
<IIIcon iconName="funnel" class="w-14 h-14" />
|
|
105
|
+
<span>{selectedItem ? selectedLabel : 'Filter'}</span>
|
|
106
|
+
<IIIcon iconName="caret-down" class="w-12 h-12" />
|
|
107
|
+
</button>
|
|
108
|
+
{/snippet}
|
|
109
|
+
</IIDropdownInput>
|
|
110
|
+
</section>
|
|
88
111
|
</div>
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
import MenuSearchInput from '../utils/menu/MenuSearchInput.svelte'
|
|
10
10
|
import MenuNoResults from '../utils/menu/MenuNoResults.svelte'
|
|
11
11
|
import MenuItemTooltip from '../utils/menu/MenuItemTooltip.svelte'
|
|
12
|
-
import
|
|
13
|
-
import
|
|
12
|
+
import IIMenuSub from './IIMenuSub.svelte'
|
|
13
|
+
import IIMenuSubSimple from './IIMenuSubSimple.svelte'
|
|
14
14
|
|
|
15
15
|
type Props = {
|
|
16
16
|
items: MenuEntry[]
|
|
@@ -21,10 +21,14 @@
|
|
|
21
21
|
side?: 'top' | 'right' | 'bottom' | 'left'
|
|
22
22
|
align?: 'start' | 'center' | 'end'
|
|
23
23
|
collisionPadding?: number
|
|
24
|
+
/** @deprecated Use `class` — it now targets the trigger. */
|
|
24
25
|
triggerClass?: string
|
|
25
26
|
searchable?: boolean
|
|
26
27
|
searchPlaceholder?: string
|
|
28
|
+
/** Classes for the trigger (root) element. */
|
|
27
29
|
class?: string
|
|
30
|
+
/** Classes for the menu panel (popover surface). */
|
|
31
|
+
contentClass?: string
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
let {
|
|
@@ -40,6 +44,7 @@
|
|
|
40
44
|
searchable = false,
|
|
41
45
|
searchPlaceholder = 'Search...',
|
|
42
46
|
class: className,
|
|
47
|
+
contentClass,
|
|
43
48
|
}: Props = $props()
|
|
44
49
|
|
|
45
50
|
let triggerEl = $state<HTMLElement | null>(null)
|
|
@@ -64,6 +69,7 @@
|
|
|
64
69
|
placement: placement as any,
|
|
65
70
|
offset: 4,
|
|
66
71
|
shift: {padding: collisionPadding},
|
|
72
|
+
constrainHeight: true,
|
|
67
73
|
})
|
|
68
74
|
|
|
69
75
|
const search = createMenuSearch({
|
|
@@ -270,7 +276,7 @@
|
|
|
270
276
|
</div>
|
|
271
277
|
{#if isOpen}
|
|
272
278
|
{#if entry.searchable}
|
|
273
|
-
<
|
|
279
|
+
<IIMenuSub
|
|
274
280
|
items={entry.items}
|
|
275
281
|
onSelect={handleSelect}
|
|
276
282
|
onClose={() => {
|
|
@@ -282,7 +288,7 @@
|
|
|
282
288
|
renderItemContent={itemContent}
|
|
283
289
|
/>
|
|
284
290
|
{:else}
|
|
285
|
-
<
|
|
291
|
+
<IIMenuSubSimple
|
|
286
292
|
items={entry.items}
|
|
287
293
|
onSelect={handleSelect}
|
|
288
294
|
onClose={() => {
|
|
@@ -331,7 +337,7 @@
|
|
|
331
337
|
aria-haspopup="menu"
|
|
332
338
|
aria-expanded={open}
|
|
333
339
|
data-state={open ? 'open' : 'closed'}
|
|
334
|
-
class={cn(children ?
|
|
340
|
+
class={cn(children ? '[all:unset] cursor-default' : defaultTriggerClass, triggerClass, className)}
|
|
335
341
|
onclick={toggle}
|
|
336
342
|
>
|
|
337
343
|
{#if children}
|
|
@@ -347,7 +353,7 @@
|
|
|
347
353
|
bind:this={floatingEl}
|
|
348
354
|
role="menu"
|
|
349
355
|
data-menu-content
|
|
350
|
-
class={cn(menuStyles.content,
|
|
356
|
+
class={cn(menuStyles.content, contentClass)}
|
|
351
357
|
onkeydown={handleMenuKeydown}
|
|
352
358
|
transition:fly={{y: -4, duration: 150}}
|
|
353
359
|
>
|
|
@@ -9,11 +9,15 @@ type Props = {
|
|
|
9
9
|
side?: 'top' | 'right' | 'bottom' | 'left';
|
|
10
10
|
align?: 'start' | 'center' | 'end';
|
|
11
11
|
collisionPadding?: number;
|
|
12
|
+
/** @deprecated Use `class` — it now targets the trigger. */
|
|
12
13
|
triggerClass?: string;
|
|
13
14
|
searchable?: boolean;
|
|
14
15
|
searchPlaceholder?: string;
|
|
16
|
+
/** Classes for the trigger (root) element. */
|
|
15
17
|
class?: string;
|
|
18
|
+
/** Classes for the menu panel (popover surface). */
|
|
19
|
+
contentClass?: string;
|
|
16
20
|
};
|
|
17
|
-
declare const
|
|
18
|
-
type
|
|
19
|
-
export default
|
|
21
|
+
declare const IIMenu: import("svelte").Component<Props, {}, "open">;
|
|
22
|
+
type IIMenu = ReturnType<typeof IIMenu>;
|
|
23
|
+
export default IIMenu;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import
|
|
2
|
+
import IIMenu from './IIMenu.svelte'
|
|
3
3
|
import {IIButton} from '../IIButton'
|
|
4
4
|
import {IIIcon} from '../IIIcon'
|
|
5
5
|
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<section>
|
|
14
14
|
<h2 class="text-default-emphasis text-primary mb-8">With Separators</h2>
|
|
15
15
|
<p class="text-small text-secondary mb-12">Menu entries can include separator dividers.</p>
|
|
16
|
-
<
|
|
16
|
+
<IIMenu
|
|
17
17
|
items={[
|
|
18
18
|
{label: 'Edit', value: 'edit'},
|
|
19
19
|
{label: 'Duplicate', value: 'duplicate'},
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
<section>
|
|
30
30
|
<h2 class="text-default-emphasis text-primary mb-8">With Groups</h2>
|
|
31
31
|
<p class="text-small text-secondary mb-12">Items organized into labeled groups with headings.</p>
|
|
32
|
-
<
|
|
32
|
+
<IIMenu
|
|
33
33
|
items={[
|
|
34
34
|
{
|
|
35
35
|
type: 'group',
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
<section>
|
|
58
58
|
<h2 class="text-default-emphasis text-primary mb-8">Custom Trigger</h2>
|
|
59
59
|
<p class="text-small text-secondary mb-12">Using the children snippet with triggerClass for custom trigger styling.</p>
|
|
60
|
-
<
|
|
60
|
+
<IIMenu
|
|
61
61
|
items={[
|
|
62
62
|
{label: 'Profile', value: 'profile'},
|
|
63
63
|
{label: 'Settings', value: 'settings'},
|
|
@@ -72,14 +72,14 @@
|
|
|
72
72
|
<span>Account</span>
|
|
73
73
|
<IIIcon iconName="caret-down" class="w-12 h-12" />
|
|
74
74
|
{/snippet}
|
|
75
|
-
</
|
|
75
|
+
</IIMenu>
|
|
76
76
|
</section>
|
|
77
77
|
|
|
78
78
|
<!-- Searchable -->
|
|
79
79
|
<section>
|
|
80
80
|
<h2 class="text-default-emphasis text-primary mb-8">Searchable</h2>
|
|
81
81
|
<p class="text-small text-secondary mb-12">A search input at the top filters menu items as you type.</p>
|
|
82
|
-
<
|
|
82
|
+
<IIMenu
|
|
83
83
|
items={[
|
|
84
84
|
{label: 'Edit', value: 'edit'},
|
|
85
85
|
{label: 'Duplicate', value: 'duplicate'},
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
<!-- Mixed Entries -->
|
|
99
99
|
<section>
|
|
100
100
|
<h2 class="text-default-emphasis text-primary mb-8">Mixed: Items + Separators + Groups</h2>
|
|
101
|
-
<
|
|
101
|
+
<IIMenu
|
|
102
102
|
items={[
|
|
103
103
|
{label: 'Quick Action', value: 'quick'},
|
|
104
104
|
{type: 'separator'},
|
package/dist/{IIDropdownMenu/IIDropdownMenuStories.svelte.d.ts → IIMenu/IIMenuStories.svelte.d.ts}
RENAMED
|
@@ -11,8 +11,8 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
|
|
|
11
11
|
};
|
|
12
12
|
z_$$bindings?: Bindings;
|
|
13
13
|
}
|
|
14
|
-
declare const
|
|
14
|
+
declare const IIMenuStories: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
15
|
[evt: string]: CustomEvent<any>;
|
|
16
16
|
}, {}, {}, string>;
|
|
17
|
-
type
|
|
18
|
-
export default
|
|
17
|
+
type IIMenuStories = InstanceType<typeof IIMenuStories>;
|
|
18
|
+
export default IIMenuStories;
|
|
@@ -8,6 +8,6 @@ type Props = {
|
|
|
8
8
|
searchPlaceholder?: string;
|
|
9
9
|
renderItemContent: Snippet<[MenuItem]>;
|
|
10
10
|
};
|
|
11
|
-
declare const
|
|
12
|
-
type
|
|
13
|
-
export default
|
|
11
|
+
declare const IIMenuSub: import("svelte").Component<Props, {}, "">;
|
|
12
|
+
type IIMenuSub = ReturnType<typeof IIMenuSub>;
|
|
13
|
+
export default IIMenuSub;
|
|
@@ -8,6 +8,6 @@ type Props = {
|
|
|
8
8
|
renderItemContent: Snippet<[MenuItem]>;
|
|
9
9
|
renderSubMenu: Snippet<[SubEntry]>;
|
|
10
10
|
};
|
|
11
|
-
declare const
|
|
12
|
-
type
|
|
13
|
-
export default
|
|
11
|
+
declare const IIMenuSubSimple: import("svelte").Component<Props, {}, "">;
|
|
12
|
+
type IIMenuSubSimple = ReturnType<typeof IIMenuSubSimple>;
|
|
13
|
+
export default IIMenuSubSimple;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as IIMenu } from './IIMenu.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as IIMenu } from './IIMenu.svelte';
|
|
@@ -15,7 +15,12 @@
|
|
|
15
15
|
showCloseButton?: boolean
|
|
16
16
|
size?: 'sm' | 'md' | 'lg' | 'xl' | 'full'
|
|
17
17
|
overlay?: 'dark' | 'light' | 'none'
|
|
18
|
-
/**
|
|
18
|
+
/** Vertically center the modal instead of anchoring it 15% from the top. */
|
|
19
|
+
centered?: boolean
|
|
20
|
+
/** Cap the modal height (any CSS value, e.g. "60vh"). Defaults to 78vh
|
|
21
|
+
* (90vh when `centered`). Note: when anchored (not centered) the modal
|
|
22
|
+
* sits 15% from the top, so a value above ~83vh pushes the bottom edge
|
|
23
|
+
* off-screen. */
|
|
19
24
|
maxHeight?: string
|
|
20
25
|
/** Replace the body wrapper's padding/scroll defaults — e.g. for a full-height flex body. */
|
|
21
26
|
bodyClass?: string
|
|
@@ -33,6 +38,7 @@
|
|
|
33
38
|
showCloseButton = true,
|
|
34
39
|
size = 'md',
|
|
35
40
|
overlay = 'dark',
|
|
41
|
+
centered = false,
|
|
36
42
|
maxHeight,
|
|
37
43
|
bodyClass,
|
|
38
44
|
class: className,
|
|
@@ -43,7 +49,7 @@
|
|
|
43
49
|
onOpenChange?.(newOpen)
|
|
44
50
|
}
|
|
45
51
|
|
|
46
|
-
// Portaled menu/listbox content (
|
|
52
|
+
// Portaled menu/listbox content (IIMenu, bits-ui DropdownMenu/Popover/Select, etc.)
|
|
47
53
|
// lives in document.body outside Dialog.Content, so bits-ui's DismissibleLayer would treat
|
|
48
54
|
// interactions with them as "outside" the modal and close it. Preserve those events.
|
|
49
55
|
function isInsidePortaledMenu(target: Element | null): boolean {
|
|
@@ -61,7 +67,7 @@
|
|
|
61
67
|
<Dialog.Portal>
|
|
62
68
|
<Dialog.Overlay
|
|
63
69
|
class={cn(
|
|
64
|
-
'fixed inset-0 z-14 data-[state=open]:animate-
|
|
70
|
+
'fixed inset-0 z-14 data-[state=open]:animate-modal-overlay-in data-[state=closed]:animate-modal-overlay-out motion-reduce:animate-none',
|
|
65
71
|
overlay === 'dark' && 'bg-black/30',
|
|
66
72
|
overlay === 'light' && 'bg-black/10',
|
|
67
73
|
overlay === 'none' && 'pointer-events-none'
|
|
@@ -78,16 +84,23 @@
|
|
|
78
84
|
if (isInsidePortaledMenu(target)) e.preventDefault()
|
|
79
85
|
}}
|
|
80
86
|
class={cn(
|
|
81
|
-
//
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
|
|
85
|
-
|
|
87
|
+
// Centering is deliberately kept OFF `transform`: horizontal uses left-0/right-0 +
|
|
88
|
+
// mx-auto, and vertical centering (when `centered`) uses the standalone `translate`
|
|
89
|
+
// property — both compose with the open/close slide animation, which owns `transform`
|
|
90
|
+
// (translateY). A transform-based center would be clobbered by the animation and
|
|
91
|
+
// shift the modal for the animation's duration.
|
|
92
|
+
'fixed left-0 right-0 mx-auto bg-surface border border-primary rounded-12 w-[calc(100%-20px)] flex flex-col z-15 data-[state=open]:animate-modal-in data-[state=closed]:animate-modal-out motion-reduce:animate-none focus:outline-none',
|
|
93
|
+
// Vertical: anchored 15% from the top (default) vs. centered. When anchored, height
|
|
94
|
+
// is capped so a tall modal still clears the bottom (15% + 78vh leaves ~7vh below);
|
|
95
|
+
// centered can safely use the full 90vh since -50% keeps it within the viewport.
|
|
96
|
+
centered ? 'top-1/2 [translate:0_-50%] max-h-[90vh]' : 'top-[15%] max-h-[78vh]',
|
|
97
|
+
// Same edge for every overlay: shadow-modal (previously no-overlay used shadow-floating).
|
|
98
|
+
'shadow-modal',
|
|
86
99
|
size === 'sm' && 'max-w-400',
|
|
87
100
|
size === 'md' && 'max-w-500',
|
|
88
101
|
size === 'lg' && 'max-w-700',
|
|
89
102
|
size === 'xl' && 'max-w-[1100px]',
|
|
90
|
-
size === 'full' && 'max-w-[95vw] h-[
|
|
103
|
+
size === 'full' && 'max-w-[95vw] h-[78vh]',
|
|
91
104
|
className
|
|
92
105
|
)}
|
|
93
106
|
style={maxHeight ? `max-height: ${maxHeight}` : undefined}
|
|
@@ -95,7 +108,7 @@
|
|
|
95
108
|
<div class="flex items-start justify-between gap-12 px-24 pt-24 shrink-0">
|
|
96
109
|
<div class="flex flex-col min-w-0 flex-1">
|
|
97
110
|
<div class="flex items-center gap-12 min-w-0">
|
|
98
|
-
<Dialog.Title class="text-
|
|
111
|
+
<Dialog.Title class="text-h3 text-body m-0 shrink-0">{title}</Dialog.Title>
|
|
99
112
|
{#if titleAccessory}
|
|
100
113
|
{@render titleAccessory()}
|
|
101
114
|
{/if}
|
|
@@ -10,7 +10,12 @@ type Props = {
|
|
|
10
10
|
showCloseButton?: boolean;
|
|
11
11
|
size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
12
12
|
overlay?: 'dark' | 'light' | 'none';
|
|
13
|
-
/**
|
|
13
|
+
/** Vertically center the modal instead of anchoring it 15% from the top. */
|
|
14
|
+
centered?: boolean;
|
|
15
|
+
/** Cap the modal height (any CSS value, e.g. "60vh"). Defaults to 78vh
|
|
16
|
+
* (90vh when `centered`). Note: when anchored (not centered) the modal
|
|
17
|
+
* sits 15% from the top, so a value above ~83vh pushes the bottom edge
|
|
18
|
+
* off-screen. */
|
|
14
19
|
maxHeight?: string;
|
|
15
20
|
/** Replace the body wrapper's padding/scroll defaults — e.g. for a full-height flex body. */
|
|
16
21
|
bodyClass?: string;
|
|
@@ -19,14 +19,15 @@
|
|
|
19
19
|
|
|
20
20
|
<IIButton onclick={() => (open = true)}>Open modal</IIButton>
|
|
21
21
|
|
|
22
|
-
{#if open}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
<!-- Keep IIModal mounted unconditionally (no {#if open}) so bits-ui's Dialog can
|
|
23
|
+
play its exit animation on close — wrapping it in {#if} unmounts the whole
|
|
24
|
+
dialog instantly and skips the modal-out/fade-out transitions. -->
|
|
25
|
+
<IIModal bind:open title="Add a note" onOpenChange={v => (open = v)}>
|
|
26
|
+
<IITextarea
|
|
27
|
+
bind:ref
|
|
28
|
+
bind:value
|
|
29
|
+
label="Note"
|
|
30
|
+
placeholder="The focus ring should be fully visible on the left, right, and bottom."
|
|
31
|
+
rows={4}
|
|
32
|
+
/>
|
|
33
|
+
</IIModal>
|
package/dist/index.d.ts
CHANGED
|
@@ -16,7 +16,9 @@ export { IICombobox } from './IICombobox';
|
|
|
16
16
|
export { IIContextMenu } from './IIContextMenu';
|
|
17
17
|
export { IIDateInput } from './IIDateInput';
|
|
18
18
|
export { IIDropdownInput } from './IIDropdownInput';
|
|
19
|
-
export {
|
|
19
|
+
export { IIMenu } from './IIMenu';
|
|
20
|
+
/** @deprecated Renamed to `IIMenu` (it is an action menu, not a select). Use `IIMenu`. */
|
|
21
|
+
export { IIMenu as IIDropdownMenu } from './IIMenu';
|
|
20
22
|
export { IIEditableBadges } from './IIEditableBadges';
|
|
21
23
|
export { IIEditableText } from './IIEditableText';
|
|
22
24
|
export { IIEmptyState } from './IIEmptyState';
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,9 @@ export { IICombobox } from './IICombobox';
|
|
|
20
20
|
export { IIContextMenu } from './IIContextMenu';
|
|
21
21
|
export { IIDateInput } from './IIDateInput';
|
|
22
22
|
export { IIDropdownInput } from './IIDropdownInput';
|
|
23
|
-
export {
|
|
23
|
+
export { IIMenu } from './IIMenu';
|
|
24
|
+
/** @deprecated Renamed to `IIMenu` (it is an action menu, not a select). Use `IIMenu`. */
|
|
25
|
+
export { IIMenu as IIDropdownMenu } from './IIMenu';
|
|
24
26
|
export { IIEditableBadges } from './IIEditableBadges';
|
|
25
27
|
export { IIEditableText } from './IIEditableText';
|
|
26
28
|
export { IIEmptyState } from './IIEmptyState';
|
package/dist/style/base.css
CHANGED
|
@@ -77,3 +77,26 @@
|
|
|
77
77
|
background-color: var(--ii-gray-400);
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
+
|
|
81
|
+
/* Shared narrow, rounded scrollbar for menu/dropdown scroll areas. Unlayered so
|
|
82
|
+
it outranks the @layer base `*` rules above. Setting scrollbar-width/color to
|
|
83
|
+
auto opts this element back into ::-webkit-scrollbar styling — the global
|
|
84
|
+
`scrollbar-width: thin` otherwise disables the WebKit pseudo-elements in
|
|
85
|
+
Chromium, so a custom (narrow) thumb width can't be applied. */
|
|
86
|
+
.ii-menu-scroll {
|
|
87
|
+
scrollbar-width: auto;
|
|
88
|
+
scrollbar-color: auto;
|
|
89
|
+
}
|
|
90
|
+
.ii-menu-scroll::-webkit-scrollbar {
|
|
91
|
+
width: 4px;
|
|
92
|
+
}
|
|
93
|
+
.ii-menu-scroll::-webkit-scrollbar-track {
|
|
94
|
+
background: transparent;
|
|
95
|
+
}
|
|
96
|
+
.ii-menu-scroll::-webkit-scrollbar-thumb {
|
|
97
|
+
background-color: var(--ii-gray-300);
|
|
98
|
+
border-radius: 9999px;
|
|
99
|
+
}
|
|
100
|
+
.ii-menu-scroll::-webkit-scrollbar-thumb:hover {
|
|
101
|
+
background-color: var(--ii-gray-400);
|
|
102
|
+
}
|
|
@@ -25,13 +25,11 @@ export declare const keyframes: {
|
|
|
25
25
|
transform: string;
|
|
26
26
|
};
|
|
27
27
|
};
|
|
28
|
-
|
|
28
|
+
modalSlideIn: {
|
|
29
29
|
from: {
|
|
30
|
-
opacity: string;
|
|
31
30
|
transform: string;
|
|
32
31
|
};
|
|
33
32
|
to: {
|
|
34
|
-
opacity: string;
|
|
35
33
|
transform: string;
|
|
36
34
|
};
|
|
37
35
|
};
|
|
@@ -161,6 +159,8 @@ export declare const animation: {
|
|
|
161
159
|
skeleton: string;
|
|
162
160
|
'modal-in': string;
|
|
163
161
|
'modal-out': string;
|
|
162
|
+
'modal-overlay-in': string;
|
|
163
|
+
'modal-overlay-out': string;
|
|
164
164
|
'fade-out': string;
|
|
165
165
|
'login-fade-in-up': string;
|
|
166
166
|
'login-pulse': string;
|
|
@@ -12,9 +12,13 @@ export const keyframes = {
|
|
|
12
12
|
'0%': { transform: 'translate(-50%, -50%) rotate(0deg) translateX(24px)' },
|
|
13
13
|
'100%': { transform: 'translate(-50%, -50%) rotate(360deg) translateX(24px)' },
|
|
14
14
|
},
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
modalSlideIn: {
|
|
16
|
+
// Transform-only slide into place. Opacity is handled by a separate, faster
|
|
17
|
+
// `fadeIn` animation (see modal-in) so the fade can match the overlay while
|
|
18
|
+
// the slide runs on its own long duration. (IIModal centers via mx-auto, not
|
|
19
|
+
// transform, so translateY here is free of the horizontal centering.)
|
|
20
|
+
from: { transform: 'translateY(-10px)' },
|
|
21
|
+
to: { transform: 'translateY(0)' },
|
|
18
22
|
},
|
|
19
23
|
spin: {
|
|
20
24
|
to: { transform: 'rotate(360deg)' },
|
|
@@ -60,8 +64,9 @@ export const keyframes = {
|
|
|
60
64
|
to: { opacity: '1', transform: 'translateY(0)' },
|
|
61
65
|
},
|
|
62
66
|
modalOut: {
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
// Fade out while sliding up.
|
|
68
|
+
from: { opacity: '1', transform: 'translateY(0)' },
|
|
69
|
+
to: { opacity: '0', transform: 'translateY(-6px)' },
|
|
65
70
|
},
|
|
66
71
|
fadeOut: {
|
|
67
72
|
from: { opacity: '1' },
|
|
@@ -76,8 +81,14 @@ export const animation = {
|
|
|
76
81
|
shake: 'shake 0.4s ease-out',
|
|
77
82
|
shimmer: 'shimmer 1.5s infinite',
|
|
78
83
|
skeleton: 'skeleton-loading 1.2s ease-in-out infinite',
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
// Two decoupled animations: the opacity fade matches the overlay exactly
|
|
85
|
+
// (fadeIn 130ms ease-out), while the slide glides in slowly over 2500ms.
|
|
86
|
+
'modal-in': 'fadeIn 130ms ease-out, modalSlideIn 2500ms cubic-bezier(0.1, 1, 0.1, 1)',
|
|
87
|
+
'modal-out': 'modalOut 90ms ease-in',
|
|
88
|
+
// Modal-specific overlay fades — snappy, to match the modal's timing rather
|
|
89
|
+
// than the slower shared fade-in/fade-out used by menus, tooltips, etc.
|
|
90
|
+
'modal-overlay-in': 'fadeIn 130ms ease-out',
|
|
91
|
+
'modal-overlay-out': 'fadeOut 90ms ease-in',
|
|
81
92
|
'fade-out': 'fadeOut 150ms ease-in',
|
|
82
93
|
'login-fade-in-up': 'loginFadeInUp 0.6s ease-out',
|
|
83
94
|
'login-pulse': 'loginPulse 2s ease-in-out infinite',
|
|
@@ -442,13 +442,11 @@ declare const _default: {
|
|
|
442
442
|
transform: string;
|
|
443
443
|
};
|
|
444
444
|
};
|
|
445
|
-
|
|
445
|
+
modalSlideIn: {
|
|
446
446
|
from: {
|
|
447
|
-
opacity: string;
|
|
448
447
|
transform: string;
|
|
449
448
|
};
|
|
450
449
|
to: {
|
|
451
|
-
opacity: string;
|
|
452
450
|
transform: string;
|
|
453
451
|
};
|
|
454
452
|
};
|
|
@@ -578,6 +576,8 @@ declare const _default: {
|
|
|
578
576
|
skeleton: string;
|
|
579
577
|
'modal-in': string;
|
|
580
578
|
'modal-out': string;
|
|
579
|
+
'modal-overlay-in': string;
|
|
580
|
+
'modal-overlay-out': string;
|
|
581
581
|
'fade-out': string;
|
|
582
582
|
'login-fade-in-up': string;
|
|
583
583
|
'login-pulse': string;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
}: Props = $props()
|
|
15
15
|
</script>
|
|
16
16
|
|
|
17
|
-
<div class="-mx-4 -mt-4 px-14 mb-4 border-b-[0.5px] border-dropdown-border">
|
|
17
|
+
<div class="shrink-0 -mx-4 -mt-4 px-14 mb-4 border-b-[0.5px] border-dropdown-border">
|
|
18
18
|
<input
|
|
19
19
|
bind:this={inputEl}
|
|
20
20
|
bind:value={searchQuery}
|
|
@@ -2,10 +2,10 @@ export declare const menuStyles: {
|
|
|
2
2
|
readonly item: "flex items-center gap-8 px-12 py-8 rounded-4 text-small cursor-default select-none outline-none data-[disabled]:opacity-50 motion-reduce:transition-none";
|
|
3
3
|
readonly itemDefault: "text-dropdown-item hover:bg-dropdown-item-hover focus:bg-dropdown-item-hover data-[highlighted]:bg-dropdown-item-hover data-[highlighted]:outline-none data-[state=open]:bg-dropdown-item-hover data-[disabled]:hover:bg-transparent data-[disabled]:focus:bg-transparent";
|
|
4
4
|
readonly itemDestructive: "text-error hover:bg-error-bg focus:bg-error-bg data-[highlighted]:bg-error-bg data-[highlighted]:outline-none data-[disabled]:hover:bg-transparent data-[disabled]:focus:bg-transparent";
|
|
5
|
-
readonly content: "min-w-48
|
|
6
|
-
readonly subContent: "min-w-48 max-h-300 overflow-y-auto bg-dropdown-bg border-[0.5px] border-dropdown-border rounded-10 shadow-submenu p-4 z-12 outline-none animate-fade-in motion-reduce:animate-none";
|
|
5
|
+
readonly content: "ii-menu-scroll min-w-48 overflow-y-auto bg-dropdown-bg border-[0.5px] border-dropdown-border rounded-10 shadow-dropdown p-4 z-12 pointer-events-auto outline-none";
|
|
6
|
+
readonly subContent: "ii-menu-scroll min-w-48 max-h-300 overflow-y-auto bg-dropdown-bg border-[0.5px] border-dropdown-border rounded-10 shadow-submenu p-4 z-12 outline-none animate-fade-in motion-reduce:animate-none";
|
|
7
7
|
readonly searchableSubContent: "min-w-48 bg-dropdown-bg border-[0.5px] border-dropdown-border rounded-10 shadow-submenu p-4 z-12 pointer-events-auto outline-none overflow-hidden animate-fade-in motion-reduce:animate-none";
|
|
8
|
-
readonly scrollableItems: "max-h-250 overflow-y-auto overflow-x-hidden";
|
|
8
|
+
readonly scrollableItems: "ii-menu-scroll max-h-250 overflow-y-auto overflow-x-hidden";
|
|
9
9
|
readonly separator: "h-1 bg-muted -mx-4 my-4";
|
|
10
10
|
readonly groupHeading: "text-tiny-emphasis text-secondary px-12 py-4 uppercase select-none";
|
|
11
11
|
};
|
|
@@ -3,10 +3,13 @@ export const menuStyles = {
|
|
|
3
3
|
item: 'flex items-center gap-8 px-12 py-8 rounded-4 text-small cursor-default select-none outline-none data-[disabled]:opacity-50 motion-reduce:transition-none',
|
|
4
4
|
itemDefault: 'text-dropdown-item hover:bg-dropdown-item-hover focus:bg-dropdown-item-hover data-[highlighted]:bg-dropdown-item-hover data-[highlighted]:outline-none data-[state=open]:bg-dropdown-item-hover data-[disabled]:hover:bg-transparent data-[disabled]:focus:bg-transparent',
|
|
5
5
|
itemDestructive: 'text-error hover:bg-error-bg focus:bg-error-bg data-[highlighted]:bg-error-bg data-[highlighted]:outline-none data-[disabled]:hover:bg-transparent data-[disabled]:focus:bg-transparent',
|
|
6
|
-
content:
|
|
7
|
-
|
|
6
|
+
// content: no fixed max-height — IIMenu passes constrainHeight to
|
|
7
|
+
// useFloating, which sizes maxHeight to the available viewport space so the
|
|
8
|
+
// menu grows to fit its items and only scrolls near the screen edge.
|
|
9
|
+
content: 'ii-menu-scroll min-w-48 overflow-y-auto bg-dropdown-bg border-[0.5px] border-dropdown-border rounded-10 shadow-dropdown p-4 z-12 pointer-events-auto outline-none',
|
|
10
|
+
subContent: 'ii-menu-scroll min-w-48 max-h-300 overflow-y-auto bg-dropdown-bg border-[0.5px] border-dropdown-border rounded-10 shadow-submenu p-4 z-12 outline-none animate-fade-in motion-reduce:animate-none',
|
|
8
11
|
searchableSubContent: 'min-w-48 bg-dropdown-bg border-[0.5px] border-dropdown-border rounded-10 shadow-submenu p-4 z-12 pointer-events-auto outline-none overflow-hidden animate-fade-in motion-reduce:animate-none',
|
|
9
|
-
scrollableItems: 'max-h-250 overflow-y-auto overflow-x-hidden',
|
|
12
|
+
scrollableItems: 'ii-menu-scroll max-h-250 overflow-y-auto overflow-x-hidden',
|
|
10
13
|
separator: 'h-1 bg-muted -mx-4 my-4',
|
|
11
14
|
groupHeading: 'text-tiny-emphasis text-secondary px-12 py-4 uppercase select-none',
|
|
12
15
|
};
|
|
@@ -9,5 +9,9 @@ export type UseFloatingOptions = {
|
|
|
9
9
|
padding?: number;
|
|
10
10
|
};
|
|
11
11
|
matchWidth?: boolean;
|
|
12
|
+
/** Constrain the floating element's height to the space available in the
|
|
13
|
+
* viewport (via the size middleware). Lets the panel grow to fit its
|
|
14
|
+
* content and only cap/scroll when it would run off-screen. */
|
|
15
|
+
constrainHeight?: boolean;
|
|
12
16
|
};
|
|
13
17
|
export declare function useFloating(opts: UseFloatingOptions): void;
|
|
@@ -13,12 +13,18 @@ export function useFloating(opts) {
|
|
|
13
13
|
const padding = typeof opts.shift === 'object' ? opts.shift.padding : 8;
|
|
14
14
|
middleware.push(shiftMiddleware({ padding }));
|
|
15
15
|
}
|
|
16
|
-
if (opts.matchWidth) {
|
|
16
|
+
if (opts.matchWidth || opts.constrainHeight) {
|
|
17
17
|
middleware.push(sizeMiddleware({
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
padding: 8,
|
|
19
|
+
apply({ rects, availableHeight }) {
|
|
20
|
+
const styles = {};
|
|
21
|
+
if (opts.matchWidth) {
|
|
22
|
+
styles.minWidth = `${rects.reference.width}px`;
|
|
23
|
+
}
|
|
24
|
+
if (opts.constrainHeight) {
|
|
25
|
+
styles.maxHeight = `${availableHeight}px`;
|
|
26
|
+
}
|
|
27
|
+
Object.assign(floating.style, styles);
|
|
22
28
|
},
|
|
23
29
|
}));
|
|
24
30
|
}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default as IIDropdownMenu } from './IIDropdownMenu.svelte';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default as IIDropdownMenu } from './IIDropdownMenu.svelte';
|
|
File without changes
|
/package/dist/{IIDropdownMenu/IIDropdownMenuSubSimple.svelte → IIMenu/IIMenuSubSimple.svelte}
RENAMED
|
File without changes
|