@streamscloud/kit 0.9.2 → 0.9.3
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/core/utils/array-helper.d.ts +5 -0
- package/dist/core/utils/array-helper.js +14 -0
- package/dist/ui/announcement-banner/announcement-banner-localization.d.ts +3 -0
- package/dist/ui/announcement-banner/announcement-banner-localization.js +12 -0
- package/dist/ui/announcement-banner/cmp.announcement-banner.svelte +153 -0
- package/dist/ui/announcement-banner/cmp.announcement-banner.svelte.d.ts +39 -0
- package/dist/ui/announcement-banner/index.d.ts +2 -0
- package/dist/ui/announcement-banner/index.js +1 -0
- package/dist/ui/announcement-banner/types.d.ts +1 -0
- package/dist/ui/announcement-banner/types.js +1 -0
- package/dist/ui/popover/cmp.popover-item.svelte +10 -1
- package/dist/ui/popover/cmp.popover-item.svelte.d.ts +4 -0
- package/package.json +1 -1
|
@@ -2,6 +2,11 @@ export declare class ArrayHelper {
|
|
|
2
2
|
static distinct<T>(items: T[]): T[];
|
|
3
3
|
static distinctBy<T>(items: T[], keyFn: (elem: T) => unknown): T[];
|
|
4
4
|
static intersect<T>(arrays: T[][]): T[];
|
|
5
|
+
/**
|
|
6
|
+
* Splits `items` into sequential chunks of at most `size` elements.
|
|
7
|
+
* If `size < 1`, returns a single chunk containing all items.
|
|
8
|
+
*/
|
|
9
|
+
static chunk<T>(items: T[], size: number): T[][];
|
|
5
10
|
static assertHasValue<T>(value: T | null | undefined): value is T;
|
|
6
11
|
/**
|
|
7
12
|
* Find position ("from" and "to" indexes) of the element that was moved inside array (only one element should be moved)
|
|
@@ -11,6 +11,20 @@ export class ArrayHelper {
|
|
|
11
11
|
}
|
|
12
12
|
return arrays.reduce((result, current) => result.filter((item) => current.includes(item)));
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Splits `items` into sequential chunks of at most `size` elements.
|
|
16
|
+
* If `size < 1`, returns a single chunk containing all items.
|
|
17
|
+
*/
|
|
18
|
+
static chunk(items, size) {
|
|
19
|
+
if (size < 1) {
|
|
20
|
+
return [[...items]];
|
|
21
|
+
}
|
|
22
|
+
const result = [];
|
|
23
|
+
for (let i = 0; i < items.length; i += size) {
|
|
24
|
+
result.push(items.slice(i, i + size));
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
14
28
|
static assertHasValue(value) {
|
|
15
29
|
return value !== null && value !== undefined;
|
|
16
30
|
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
<script lang="ts">import { Icon, IconSlot } from '../icon';
|
|
2
|
+
import { AnnouncementBannerLocalization } from './announcement-banner-localization';
|
|
3
|
+
import IconDismiss from '@fluentui/svg-icons/icons/dismiss_12_regular.svg?raw';
|
|
4
|
+
let { variant = 'info', title, dismissible = false, icon, action, children, on } = $props();
|
|
5
|
+
const localization = new AnnouncementBannerLocalization();
|
|
6
|
+
let visible = $state(true);
|
|
7
|
+
const role = $derived(variant === 'maintenance' ? 'alert' : 'status');
|
|
8
|
+
const dismiss = () => {
|
|
9
|
+
visible = false;
|
|
10
|
+
on?.dismiss?.();
|
|
11
|
+
};
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
{#if visible}
|
|
15
|
+
<div class="announcement-banner announcement-banner--{variant}" class:announcement-banner--dismissible={dismissible} role={role}>
|
|
16
|
+
<div class="announcement-banner__content">
|
|
17
|
+
{#if icon}
|
|
18
|
+
<span class="announcement-banner__icon" aria-hidden="true"><IconSlot icon={icon} /></span>
|
|
19
|
+
{/if}
|
|
20
|
+
<div class="announcement-banner__body">
|
|
21
|
+
{#if title}<strong class="announcement-banner__title">{title}</strong>{/if}
|
|
22
|
+
{#if children}<span class="announcement-banner__description">{@render children()}</span>{/if}
|
|
23
|
+
</div>
|
|
24
|
+
{#if action}<div class="announcement-banner__action">{@render action()}</div>{/if}
|
|
25
|
+
</div>
|
|
26
|
+
{#if dismissible}
|
|
27
|
+
<button class="announcement-banner__close" type="button" aria-label={localization.dismiss} onclick={dismiss}>
|
|
28
|
+
<Icon src={IconDismiss} />
|
|
29
|
+
</button>
|
|
30
|
+
{/if}
|
|
31
|
+
</div>
|
|
32
|
+
{/if}
|
|
33
|
+
|
|
34
|
+
<!--
|
|
35
|
+
@component
|
|
36
|
+
Full-width ribbon notification for site-wide announcements placed at the top of a page or layout.
|
|
37
|
+
Supports four visual variants; `variant='maintenance'` uses `role="alert"` (assertive); all others use `role="status"` (polite).
|
|
38
|
+
|
|
39
|
+
### CSS Custom Properties
|
|
40
|
+
| Property | Description | Default |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| `--sc-kit--announcement-banner--padding-block` | Vertical padding | `--sc-kit--space--3` |
|
|
43
|
+
| `--sc-kit--announcement-banner--padding-inline` | Horizontal padding | `--sc-kit--space--5` |
|
|
44
|
+
| `--sc-kit--announcement-banner--gap` | Gap between icon / body / action | `--sc-kit--space--3` |
|
|
45
|
+
| `--sc-kit--announcement-banner--background` | Background color | per `variant` |
|
|
46
|
+
| `--sc-kit--announcement-banner--border-color` | Bottom border color | per `variant` |
|
|
47
|
+
| `--sc-kit--announcement-banner--accent-color` | Icon + dismiss glyph color | per `variant` |
|
|
48
|
+
| `--sc-kit--announcement-banner--title--color` | Title text color | `--sc-kit--color--text--primary` |
|
|
49
|
+
| `--sc-kit--announcement-banner--description--color` | Body text color | `--sc-kit--color--text--secondary` |
|
|
50
|
+
-->
|
|
51
|
+
|
|
52
|
+
<style>.announcement-banner {
|
|
53
|
+
--_ab--padding-block: var(--sc-kit--announcement-banner--padding-block, var(--sc-kit--space--3));
|
|
54
|
+
--_ab--padding-inline: var(--sc-kit--announcement-banner--padding-inline, var(--sc-kit--space--5));
|
|
55
|
+
--_ab--gap: var(--sc-kit--announcement-banner--gap, var(--sc-kit--space--3));
|
|
56
|
+
--_ab--title-color: var(--sc-kit--announcement-banner--title--color, var(--sc-kit--color--text--primary));
|
|
57
|
+
--_ab--description-color: var(--sc-kit--announcement-banner--description--color, var(--sc-kit--color--text--secondary));
|
|
58
|
+
--_ab--background-default: var(--sc-kit--color--accent--softer);
|
|
59
|
+
--_ab--border-default: var(--sc-kit--color--accent--soft);
|
|
60
|
+
--_ab--accent-default: var(--sc-kit--color--accent);
|
|
61
|
+
--_ab--background: var(--sc-kit--announcement-banner--background, var(--_ab--background-default));
|
|
62
|
+
--_ab--border-color: var(--sc-kit--announcement-banner--border-color, var(--_ab--border-default));
|
|
63
|
+
--_ab--accent-color: var(--sc-kit--announcement-banner--accent-color, var(--_ab--accent-default));
|
|
64
|
+
display: flex;
|
|
65
|
+
width: 100%;
|
|
66
|
+
align-items: center;
|
|
67
|
+
justify-content: center;
|
|
68
|
+
padding: var(--_ab--padding-block) var(--_ab--padding-inline);
|
|
69
|
+
background: var(--_ab--background);
|
|
70
|
+
border-bottom: 1px solid var(--_ab--border-color);
|
|
71
|
+
color: var(--_ab--accent-color);
|
|
72
|
+
position: relative;
|
|
73
|
+
}
|
|
74
|
+
.announcement-banner--dismissible {
|
|
75
|
+
padding-inline-end: calc(var(--_ab--padding-inline) + 2rem);
|
|
76
|
+
}
|
|
77
|
+
.announcement-banner--info {
|
|
78
|
+
--_ab--background-default: var(--sc-kit--color--accent--softer);
|
|
79
|
+
--_ab--border-default: var(--sc-kit--color--accent--soft);
|
|
80
|
+
--_ab--accent-default: var(--sc-kit--color--accent);
|
|
81
|
+
}
|
|
82
|
+
.announcement-banner--announcement {
|
|
83
|
+
--_ab--background-default: var(--sc-kit--color--accent--soft);
|
|
84
|
+
--_ab--border-default: var(--sc-kit--color--accent);
|
|
85
|
+
--_ab--accent-default: var(--sc-kit--color--accent);
|
|
86
|
+
}
|
|
87
|
+
.announcement-banner--warning {
|
|
88
|
+
--_ab--background-default: var(--sc-kit--color--warning--soft);
|
|
89
|
+
--_ab--border-default: var(--sc-kit--color--warning);
|
|
90
|
+
--_ab--accent-default: var(--sc-kit--color--warning);
|
|
91
|
+
}
|
|
92
|
+
.announcement-banner--maintenance {
|
|
93
|
+
--_ab--background-default: var(--sc-kit--color--danger--soft);
|
|
94
|
+
--_ab--border-default: var(--sc-kit--color--danger);
|
|
95
|
+
--_ab--accent-default: var(--sc-kit--color--danger);
|
|
96
|
+
}
|
|
97
|
+
.announcement-banner__content {
|
|
98
|
+
display: flex;
|
|
99
|
+
align-items: center;
|
|
100
|
+
gap: var(--_ab--gap);
|
|
101
|
+
}
|
|
102
|
+
.announcement-banner__icon {
|
|
103
|
+
flex-shrink: 0;
|
|
104
|
+
display: inline-flex;
|
|
105
|
+
align-items: center;
|
|
106
|
+
line-height: 0;
|
|
107
|
+
}
|
|
108
|
+
.announcement-banner__body {
|
|
109
|
+
display: flex;
|
|
110
|
+
align-items: baseline;
|
|
111
|
+
flex-wrap: wrap;
|
|
112
|
+
gap: var(--sc-kit--space--2);
|
|
113
|
+
}
|
|
114
|
+
.announcement-banner__title {
|
|
115
|
+
font-size: var(--sc-kit--font-size--sm);
|
|
116
|
+
font-weight: var(--sc-kit--font-weight--semibold);
|
|
117
|
+
line-height: var(--sc-kit--leading--tight);
|
|
118
|
+
color: var(--_ab--title-color);
|
|
119
|
+
}
|
|
120
|
+
.announcement-banner__description {
|
|
121
|
+
font-size: var(--sc-kit--font-size--sm);
|
|
122
|
+
line-height: var(--sc-kit--leading--normal);
|
|
123
|
+
color: var(--_ab--description-color);
|
|
124
|
+
}
|
|
125
|
+
.announcement-banner__action {
|
|
126
|
+
flex-shrink: 0;
|
|
127
|
+
}
|
|
128
|
+
.announcement-banner__close {
|
|
129
|
+
position: absolute;
|
|
130
|
+
inset-inline-end: var(--_ab--padding-inline);
|
|
131
|
+
top: 50%;
|
|
132
|
+
transform: translateY(-50%);
|
|
133
|
+
appearance: none;
|
|
134
|
+
width: 1.25rem;
|
|
135
|
+
height: 1.25rem;
|
|
136
|
+
border: 0;
|
|
137
|
+
border-radius: var(--sc-kit--radius--sm);
|
|
138
|
+
background: transparent;
|
|
139
|
+
color: currentColor;
|
|
140
|
+
display: inline-flex;
|
|
141
|
+
align-items: center;
|
|
142
|
+
justify-content: center;
|
|
143
|
+
opacity: 0.7;
|
|
144
|
+
cursor: pointer;
|
|
145
|
+
--sc-kit--icon--size: 0.75rem;
|
|
146
|
+
}
|
|
147
|
+
.announcement-banner__close:hover {
|
|
148
|
+
opacity: 1;
|
|
149
|
+
}
|
|
150
|
+
.announcement-banner__close:focus-visible {
|
|
151
|
+
outline: 2px solid var(--sc-kit--color--border--focus);
|
|
152
|
+
outline-offset: 2px;
|
|
153
|
+
}</style>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type IconProp } from '../icon';
|
|
2
|
+
import type { AnnouncementBannerVariant } from './types';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
type Props = {
|
|
5
|
+
/** @default 'info' */
|
|
6
|
+
variant?: AnnouncementBannerVariant;
|
|
7
|
+
/** Short headline rendered in bold. */
|
|
8
|
+
title?: string;
|
|
9
|
+
/** Show a dismiss button. Hides the banner locally when clicked and fires `on.dismiss`. @default false */
|
|
10
|
+
dismissible?: boolean;
|
|
11
|
+
/** Leading icon — string SVG source, `{ src, color?, size? }` object, or custom snippet. */
|
|
12
|
+
icon?: IconProp;
|
|
13
|
+
/** Optional inline call-to-action area (e.g. "Learn more →", "See status page"). */
|
|
14
|
+
action?: Snippet;
|
|
15
|
+
/** Announcement body text. */
|
|
16
|
+
children?: Snippet;
|
|
17
|
+
on?: {
|
|
18
|
+
dismiss?: () => void;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Full-width ribbon notification for site-wide announcements placed at the top of a page or layout.
|
|
23
|
+
* Supports four visual variants; `variant='maintenance'` uses `role="alert"` (assertive); all others use `role="status"` (polite).
|
|
24
|
+
*
|
|
25
|
+
* ### CSS Custom Properties
|
|
26
|
+
* | Property | Description | Default |
|
|
27
|
+
* |---|---|---|
|
|
28
|
+
* | `--sc-kit--announcement-banner--padding-block` | Vertical padding | `--sc-kit--space--3` |
|
|
29
|
+
* | `--sc-kit--announcement-banner--padding-inline` | Horizontal padding | `--sc-kit--space--5` |
|
|
30
|
+
* | `--sc-kit--announcement-banner--gap` | Gap between icon / body / action | `--sc-kit--space--3` |
|
|
31
|
+
* | `--sc-kit--announcement-banner--background` | Background color | per `variant` |
|
|
32
|
+
* | `--sc-kit--announcement-banner--border-color` | Bottom border color | per `variant` |
|
|
33
|
+
* | `--sc-kit--announcement-banner--accent-color` | Icon + dismiss glyph color | per `variant` |
|
|
34
|
+
* | `--sc-kit--announcement-banner--title--color` | Title text color | `--sc-kit--color--text--primary` |
|
|
35
|
+
* | `--sc-kit--announcement-banner--description--color` | Body text color | `--sc-kit--color--text--secondary` |
|
|
36
|
+
*/
|
|
37
|
+
declare const Cmp: import("svelte").Component<Props, {}, "">;
|
|
38
|
+
type Cmp = ReturnType<typeof Cmp>;
|
|
39
|
+
export default Cmp;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as AnnouncementBanner } from './cmp.announcement-banner.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type AnnouncementBannerVariant = 'info' | 'announcement' | 'warning' | 'maintenance';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">import { popoverIgnore } from './popover-ignore';
|
|
2
|
-
const { disabled = false, keepOpen = false, divider = false, on, children } = $props();
|
|
2
|
+
const { disabled = false, keepOpen = false, divider = false, inset = false, on, children } = $props();
|
|
3
3
|
const handleClick = () => {
|
|
4
4
|
if (disabled) {
|
|
5
5
|
return;
|
|
@@ -12,6 +12,7 @@ const handleClick = () => {
|
|
|
12
12
|
class="popover-item"
|
|
13
13
|
class:popover-item--disabled={disabled}
|
|
14
14
|
class:popover-item--divider={divider}
|
|
15
|
+
class:popover-item--inset={inset}
|
|
15
16
|
use:popoverIgnore={keepOpen}
|
|
16
17
|
role="menuitem"
|
|
17
18
|
tabindex={disabled ? -1 : 0}
|
|
@@ -42,6 +43,8 @@ for toggle items inside menus).
|
|
|
42
43
|
| `--sc-kit--popover-item--divider-color` | Divider line color | `var(--sc-kit--color--border)` |
|
|
43
44
|
| `--sc-kit--popover-item--divider-spacing` | Vertical gap added by divider | `var(--sc-kit--space--1)` |
|
|
44
45
|
| `--sc-kit--popover-item--text-align` | Text alignment | `left` |
|
|
46
|
+
| `--sc-kit--popover-item--margin-inline` | Inline margin when `inset` | `var(--sc-kit--space--2)` |
|
|
47
|
+
| `--sc-kit--popover-item--border-radius` | Corner radius when `inset` | `var(--sc-kit--radius--sm)` |
|
|
45
48
|
-->
|
|
46
49
|
|
|
47
50
|
<style>.popover-item {
|
|
@@ -56,6 +59,8 @@ for toggle items inside menus).
|
|
|
56
59
|
--_di--divider-color: var(--sc-kit--popover-item--divider-color, var(--sc-kit--color--border));
|
|
57
60
|
--_di--divider-spacing: var(--sc-kit--popover-item--divider-spacing, var(--sc-kit--space--1));
|
|
58
61
|
--_di--text-align: var(--sc-kit--popover-item--text-align, left);
|
|
62
|
+
--_di--margin-inline: var(--sc-kit--popover-item--margin-inline, var(--sc-kit--space--2));
|
|
63
|
+
--_di--border-radius: var(--sc-kit--popover-item--border-radius, var(--sc-kit--radius--sm));
|
|
59
64
|
display: flex;
|
|
60
65
|
align-items: center;
|
|
61
66
|
gap: var(--_di--gap);
|
|
@@ -81,6 +86,10 @@ for toggle items inside menus).
|
|
|
81
86
|
margin-bottom: var(--_di--divider-spacing);
|
|
82
87
|
padding-bottom: calc(var(--_di--padding-block) + 1px);
|
|
83
88
|
}
|
|
89
|
+
.popover-item--inset {
|
|
90
|
+
margin-inline: var(--_di--margin-inline);
|
|
91
|
+
border-radius: var(--_di--border-radius);
|
|
92
|
+
}
|
|
84
93
|
.popover-item__content {
|
|
85
94
|
flex: 1;
|
|
86
95
|
min-width: 0;
|
|
@@ -5,6 +5,8 @@ type Props = {
|
|
|
5
5
|
keepOpen?: boolean;
|
|
6
6
|
/** Render a separator line below this item — useful for grouping menu sections. */
|
|
7
7
|
divider?: boolean;
|
|
8
|
+
/** Inset the item from the popover edges: adds an inline margin and rounds the hover background. */
|
|
9
|
+
inset?: boolean;
|
|
8
10
|
on?: {
|
|
9
11
|
click?: () => void;
|
|
10
12
|
};
|
|
@@ -29,6 +31,8 @@ type Props = {
|
|
|
29
31
|
* | `--sc-kit--popover-item--divider-color` | Divider line color | `var(--sc-kit--color--border)` |
|
|
30
32
|
* | `--sc-kit--popover-item--divider-spacing` | Vertical gap added by divider | `var(--sc-kit--space--1)` |
|
|
31
33
|
* | `--sc-kit--popover-item--text-align` | Text alignment | `left` |
|
|
34
|
+
* | `--sc-kit--popover-item--margin-inline` | Inline margin when `inset` | `var(--sc-kit--space--2)` |
|
|
35
|
+
* | `--sc-kit--popover-item--border-radius` | Corner radius when `inset` | `var(--sc-kit--radius--sm)` |
|
|
32
36
|
*/
|
|
33
37
|
declare const Cmp: import("svelte").Component<Props, {}, "">;
|
|
34
38
|
type Cmp = ReturnType<typeof Cmp>;
|