@insymetri/styleguide 0.1.90 → 0.1.92
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/IIPillTabs/IIPillTabs.svelte +6 -2
- package/dist/IIPopover/IIPopover.svelte +49 -0
- package/dist/IIPopover/IIPopover.svelte.d.ts +21 -0
- package/dist/IIPopover/IIPopoverNestedMenuProof.svelte +32 -0
- package/dist/IIPopover/IIPopoverNestedMenuProof.svelte.d.ts +3 -0
- package/dist/IIPopover/IIPopoverNonDismissableProof.svelte +22 -0
- package/dist/IIPopover/IIPopoverNonDismissableProof.svelte.d.ts +3 -0
- package/dist/style/colors.css +3 -0
- package/dist/style/dark.css +2 -0
- package/dist/style/tailwind/colors.d.ts +1 -0
- package/dist/style/tailwind/colors.js +1 -0
- package/dist/style/tailwind/preset.d.ts +2 -0
- package/dist/style/tailwind/shadows.d.ts +1 -0
- package/dist/style/tailwind/shadows.js +5 -1
- package/package.json +1 -1
|
@@ -58,6 +58,10 @@
|
|
|
58
58
|
</script>
|
|
59
59
|
|
|
60
60
|
<div bind:this={containerEl} class={cn('min-w-0 relative', className)}>
|
|
61
|
+
<!-- Edges come from `shadow-pill` / `shadow-selected-pill` rather than borders: a shadow
|
|
62
|
+
takes no layout space, so the row doesn't reflow as the selection moves. Uniform font
|
|
63
|
+
weight for the same reason. Selected is a step DOWN from white under a darker
|
|
64
|
+
hairline, so it reads pressed in while its neighbours read raised. -->
|
|
61
65
|
{#snippet pill(tab: Tab)}
|
|
62
66
|
<button
|
|
63
67
|
class={cn(
|
|
@@ -66,8 +70,8 @@
|
|
|
66
70
|
tab.disabled
|
|
67
71
|
? 'bg-surface text-tertiary opacity-50'
|
|
68
72
|
: value === tab.value
|
|
69
|
-
? 'bg-
|
|
70
|
-
: 'bg-surface text-secondary shadow-pill hover:bg-
|
|
73
|
+
? 'bg-background-alt text-body shadow-selected-pill'
|
|
74
|
+
: 'bg-surface text-secondary shadow-pill hover:bg-background-alt hover:text-secondary-strong'
|
|
71
75
|
)}
|
|
72
76
|
style="transition: all var(--transition-fast)"
|
|
73
77
|
disabled={tab.disabled}
|
|
@@ -24,6 +24,27 @@
|
|
|
24
24
|
triggerClass?: string
|
|
25
25
|
/** Strip the default surface (background, border, radius, shadow) — for content that renders its own. */
|
|
26
26
|
unstyled?: boolean
|
|
27
|
+
/**
|
|
28
|
+
* Fired when a pointer interaction starts outside the popover. Call
|
|
29
|
+
* `event.preventDefault()` to keep the popover open. Interactions inside one of
|
|
30
|
+
* the styleguide's own portaled menus (IIDropdownInput, IIMenu…) are already
|
|
31
|
+
* kept — see `keepOpenForNestedMenus`.
|
|
32
|
+
*/
|
|
33
|
+
onInteractOutside?: (event: PointerEvent) => void
|
|
34
|
+
/**
|
|
35
|
+
* Position the content against this element (or selector) instead of the
|
|
36
|
+
* trigger — e.g. a settings panel that should sit beside the whole card its gear
|
|
37
|
+
* button lives in. Clicks on the anchor don't count as outside interactions.
|
|
38
|
+
*/
|
|
39
|
+
customAnchor?: HTMLElement | string | null
|
|
40
|
+
/**
|
|
41
|
+
* Whether the popover dismisses itself. Default `true`: a click outside or Escape
|
|
42
|
+
* closes it, as a menu should. Set `false` for a panel that owns the screen for a
|
|
43
|
+
* while and holds work in progress — a live call, a form mid-edit — where a stray
|
|
44
|
+
* click elsewhere in the app should not throw it away. It can then be closed only
|
|
45
|
+
* by its own trigger or by whoever owns `open`.
|
|
46
|
+
*/
|
|
47
|
+
dismissable?: boolean
|
|
27
48
|
}
|
|
28
49
|
|
|
29
50
|
let {
|
|
@@ -38,11 +59,36 @@
|
|
|
38
59
|
class: className,
|
|
39
60
|
triggerClass,
|
|
40
61
|
unstyled = false,
|
|
62
|
+
onInteractOutside,
|
|
63
|
+
customAnchor = null,
|
|
64
|
+
dismissable = true,
|
|
41
65
|
}: Props = $props()
|
|
42
66
|
|
|
43
67
|
const surfaceClasses = unstyled
|
|
44
68
|
? ''
|
|
45
69
|
: 'bg-dropdown-bg border border-dropdown-border rounded-10 shadow-dropdown'
|
|
70
|
+
|
|
71
|
+
// The menu components (IIDropdownInput, IIMenu, …) portal their list to <body>,
|
|
72
|
+
// so to bits-ui a click on one of their options is a click OUTSIDE this popover:
|
|
73
|
+
// it dismissed the popover on pointerdown, unmounting the content — and the
|
|
74
|
+
// option along with it — before the click could land. A dropdown inside a popover
|
|
75
|
+
// therefore never changed its value. Every portaled menu marks its list with
|
|
76
|
+
// `data-menu-content`; an interaction starting there is ours, so keep the popover
|
|
77
|
+
// open and let the option's own click do its job.
|
|
78
|
+
function keepOpenForNestedMenus(event: PointerEvent) {
|
|
79
|
+
const target = event.target
|
|
80
|
+
if (!dismissable || (target instanceof Element && target.closest('[data-menu-content]'))) {
|
|
81
|
+
event.preventDefault()
|
|
82
|
+
}
|
|
83
|
+
onInteractOutside?.(event)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// bits-ui closes on Escape unless the handler defaults it away. A non-dismissable
|
|
87
|
+
// panel has to opt out of that too, or Escape would still throw away the very work
|
|
88
|
+
// the outside-click guard above is protecting.
|
|
89
|
+
function keepOpenOnEscape(event: KeyboardEvent) {
|
|
90
|
+
if (!dismissable) event.preventDefault()
|
|
91
|
+
}
|
|
46
92
|
</script>
|
|
47
93
|
|
|
48
94
|
<Popover.Root bind:open {onOpenChange}>
|
|
@@ -62,6 +108,9 @@
|
|
|
62
108
|
{side}
|
|
63
109
|
{align}
|
|
64
110
|
{sideOffset}
|
|
111
|
+
{customAnchor}
|
|
112
|
+
onInteractOutside={keepOpenForNestedMenus}
|
|
113
|
+
onEscapeKeydown={keepOpenOnEscape}
|
|
65
114
|
class={cn(
|
|
66
115
|
surfaceClasses,
|
|
67
116
|
'z-16 animate-slide-in motion-reduce:animate-none',
|
|
@@ -21,6 +21,27 @@ type Props = {
|
|
|
21
21
|
triggerClass?: string;
|
|
22
22
|
/** Strip the default surface (background, border, radius, shadow) — for content that renders its own. */
|
|
23
23
|
unstyled?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Fired when a pointer interaction starts outside the popover. Call
|
|
26
|
+
* `event.preventDefault()` to keep the popover open. Interactions inside one of
|
|
27
|
+
* the styleguide's own portaled menus (IIDropdownInput, IIMenu…) are already
|
|
28
|
+
* kept — see `keepOpenForNestedMenus`.
|
|
29
|
+
*/
|
|
30
|
+
onInteractOutside?: (event: PointerEvent) => void;
|
|
31
|
+
/**
|
|
32
|
+
* Position the content against this element (or selector) instead of the
|
|
33
|
+
* trigger — e.g. a settings panel that should sit beside the whole card its gear
|
|
34
|
+
* button lives in. Clicks on the anchor don't count as outside interactions.
|
|
35
|
+
*/
|
|
36
|
+
customAnchor?: HTMLElement | string | null;
|
|
37
|
+
/**
|
|
38
|
+
* Whether the popover dismisses itself. Default `true`: a click outside or Escape
|
|
39
|
+
* closes it, as a menu should. Set `false` for a panel that owns the screen for a
|
|
40
|
+
* while and holds work in progress — a live call, a form mid-edit — where a stray
|
|
41
|
+
* click elsewhere in the app should not throw it away. It can then be closed only
|
|
42
|
+
* by its own trigger or by whoever owns `open`.
|
|
43
|
+
*/
|
|
44
|
+
dismissable?: boolean;
|
|
24
45
|
};
|
|
25
46
|
declare const IIPopover: import("svelte").Component<Props, {}, "open">;
|
|
26
47
|
type IIPopover = ReturnType<typeof IIPopover>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import IIPopover from './IIPopover.svelte'
|
|
3
|
+
import {IIButton} from '../IIButton'
|
|
4
|
+
import {IIDropdownInput} from '../IIDropdownInput'
|
|
5
|
+
|
|
6
|
+
// Fixture for the play test: a menu-style input inside a popover. Its option
|
|
7
|
+
// list portals to <body>, so choosing an option used to read as an outside
|
|
8
|
+
// click and dismiss the popover before the choice registered.
|
|
9
|
+
let open = $state(false)
|
|
10
|
+
let device = $state('')
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<IIPopover bind:open>
|
|
14
|
+
{#snippet trigger()}
|
|
15
|
+
<IIButton variant="secondary" size="sm">Audio settings</IIButton>
|
|
16
|
+
{/snippet}
|
|
17
|
+
{#snippet content()}
|
|
18
|
+
<div class="p-12 w-240 flex flex-col gap-8">
|
|
19
|
+
<p class="text-small text-secondary">Speaker</p>
|
|
20
|
+
<IIDropdownInput
|
|
21
|
+
items={[
|
|
22
|
+
{label: 'System Default', value: ''},
|
|
23
|
+
{label: 'Headset', value: 'headset'},
|
|
24
|
+
{label: 'Desk speakers', value: 'desk'},
|
|
25
|
+
]}
|
|
26
|
+
bind:value={device}
|
|
27
|
+
class="w-full"
|
|
28
|
+
/>
|
|
29
|
+
<p class="text-small text-body" data-testid="chosen">Chosen: {device || 'default'}</p>
|
|
30
|
+
</div>
|
|
31
|
+
{/snippet}
|
|
32
|
+
</IIPopover>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import IIPopover from './IIPopover.svelte'
|
|
3
|
+
import {IIButton} from '../IIButton'
|
|
4
|
+
|
|
5
|
+
// Fixture for the play test: a panel that must survive a click elsewhere in the app
|
|
6
|
+
// and an Escape press, and close only from its own trigger.
|
|
7
|
+
let open = $state(false)
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<div class="flex flex-col gap-16">
|
|
11
|
+
<IIPopover bind:open dismissable={false}>
|
|
12
|
+
{#snippet trigger()}
|
|
13
|
+
<IIButton variant="secondary" size="sm">{open ? 'Collapse panel' : 'Open panel'}</IIButton>
|
|
14
|
+
{/snippet}
|
|
15
|
+
{#snippet content()}
|
|
16
|
+
<div class="p-12 w-200">
|
|
17
|
+
<p class="text-small text-body">Work in progress.</p>
|
|
18
|
+
</div>
|
|
19
|
+
{/snippet}
|
|
20
|
+
</IIPopover>
|
|
21
|
+
<button type="button" data-testid="elsewhere" class="text-small text-secondary">Somewhere else</button>
|
|
22
|
+
</div>
|
package/dist/style/colors.css
CHANGED
|
@@ -54,6 +54,9 @@
|
|
|
54
54
|
/* Text */
|
|
55
55
|
--ii-text-primary: #111827;
|
|
56
56
|
--ii-text-accent: #111827;
|
|
57
|
+
/* Between secondary and body. Off the ramp, not a literal, so it follows a
|
|
58
|
+
consuming app's own neutrals. */
|
|
59
|
+
--ii-text-secondary-strong: var(--ii-gray-700);
|
|
57
60
|
--ii-text-secondary: #6b7280;
|
|
58
61
|
--ii-text-tertiary: #9ca3af;
|
|
59
62
|
--ii-text-inverse: white;
|
package/dist/style/dark.css
CHANGED
|
@@ -48,6 +48,8 @@
|
|
|
48
48
|
/* Text — neutral gray, brightest step softened so it doesn't glare on charcoal */
|
|
49
49
|
--ii-text-primary: #dcdce0;
|
|
50
50
|
--ii-text-accent: #ececee;
|
|
51
|
+
/* Ramp inverts here, so gray-700 again lands between secondary and primary. */
|
|
52
|
+
--ii-text-secondary-strong: var(--ii-gray-700);
|
|
51
53
|
--ii-text-secondary: #9a9a9f;
|
|
52
54
|
--ii-text-tertiary: #737377;
|
|
53
55
|
--ii-text-inverse: #17171a;
|
|
@@ -158,6 +158,7 @@ export const textColor = {
|
|
|
158
158
|
// Text hierarchy
|
|
159
159
|
body: 'var(--ii-text-primary)',
|
|
160
160
|
secondary: 'var(--ii-text-secondary)',
|
|
161
|
+
'secondary-strong': 'var(--ii-text-secondary-strong)',
|
|
161
162
|
tertiary: 'var(--ii-text-tertiary)',
|
|
162
163
|
inverse: 'var(--ii-text-inverse)',
|
|
163
164
|
'on-primary': 'var(--ii-text-on-primary)',
|
|
@@ -128,6 +128,7 @@ declare const _default: {
|
|
|
128
128
|
'dropdown-item-selected': string;
|
|
129
129
|
body: string;
|
|
130
130
|
secondary: string;
|
|
131
|
+
'secondary-strong': string;
|
|
131
132
|
tertiary: string;
|
|
132
133
|
inverse: string;
|
|
133
134
|
'on-primary': string;
|
|
@@ -405,6 +406,7 @@ declare const _default: {
|
|
|
405
406
|
boxShadow: {
|
|
406
407
|
none: string;
|
|
407
408
|
pill: string;
|
|
409
|
+
'selected-pill': string;
|
|
408
410
|
subtle: string;
|
|
409
411
|
card: string;
|
|
410
412
|
'comm-hover': string;
|
|
@@ -11,7 +11,11 @@ const T3 = 'var(--ii-shadow-3)';
|
|
|
11
11
|
export const boxShadow = {
|
|
12
12
|
none: 'none',
|
|
13
13
|
// Tier 1 — at rest
|
|
14
|
-
|
|
14
|
+
// Inset hairline + the lift. T1 alone has no spread, so it only darkens the bottom edge;
|
|
15
|
+
// an outset ring would sit in that same band and paint over the glow.
|
|
16
|
+
pill: `inset 0 0 0 1px var(--ii-border), ${T1}`,
|
|
17
|
+
// Selected: same hairline, stronger tone, no lift. Ring-for-ring keeps widths stable.
|
|
18
|
+
'selected-pill': 'inset 0 0 0 1px var(--ii-border-strong)',
|
|
15
19
|
subtle: T1,
|
|
16
20
|
card: T1,
|
|
17
21
|
'comm-hover': T1,
|