@streamscloud/kit 0.9.11 → 0.9.13
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/ui/duration/cmp.duration.svelte +49 -0
- package/dist/ui/duration/cmp.duration.svelte.d.ts +27 -0
- package/dist/ui/duration/index.d.ts +1 -0
- package/dist/ui/duration/index.js +1 -0
- package/dist/ui/feature-intro/cmp.feature-intro.svelte +273 -0
- package/dist/ui/feature-intro/cmp.feature-intro.svelte.d.ts +48 -0
- package/dist/ui/feature-intro/index.d.ts +2 -0
- package/dist/ui/feature-intro/index.js +1 -0
- package/dist/ui/feature-intro/types.d.ts +18 -0
- package/dist/ui/feature-intro/types.js +1 -0
- package/dist/ui/navigation/cmp.nav-menu-header.svelte +21 -7
- package/dist/ui/navigation/cmp.nav-menu-header.svelte.d.ts +7 -3
- package/dist/ui/stepper-dialog-layout/cmp.stepper-dialog-layout.svelte +1 -1
- package/package.json +9 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<script lang="ts">const { seconds, variant = 'raw', showZero = false } = $props();
|
|
2
|
+
const format = (secs) => {
|
|
3
|
+
const total = Math.max(0, Math.round(secs));
|
|
4
|
+
const hours = Math.floor(total / 3600);
|
|
5
|
+
const minutes = Math.floor((total % 3600) / 60);
|
|
6
|
+
const ss = (total % 60).toString().padStart(2, '0');
|
|
7
|
+
return hours > 0 ? `${hours}:${minutes.toString().padStart(2, '0')}:${ss}` : `${minutes}:${ss}`;
|
|
8
|
+
};
|
|
9
|
+
const value = $derived(seconds !== null && seconds > 0 ? format(seconds) : showZero ? format(0) : null);
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
{#if value !== null}
|
|
13
|
+
<span class="duration" class:duration--badge={variant === 'badge'}>{value}</span>
|
|
14
|
+
{/if}
|
|
15
|
+
|
|
16
|
+
<!--
|
|
17
|
+
@component
|
|
18
|
+
Renders a media/time duration given in seconds as a human-readable clock string — `m:ss` under an
|
|
19
|
+
hour, `h:mm:ss` at or above (seconds are rounded, so a 60-second carry rolls up). `null` or ≤ 0
|
|
20
|
+
renders nothing; pass `showZero` to force `0:00`. `variant='raw'` (default) is bare text that
|
|
21
|
+
inherits the parent's typography; `variant='badge'` is a dark overlay pill for the bottom corner of
|
|
22
|
+
a video thumbnail. Placement (e.g. absolute over media) is the consumer's job via the cascade.
|
|
23
|
+
|
|
24
|
+
### CSS Custom Properties
|
|
25
|
+
| Property | Description | Default |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| `--sc-kit--duration--badge--background` | Badge background (badge variant) | `rgb(0 0 0 / 55%)` (dark translucent) |
|
|
28
|
+
| `--sc-kit--duration--badge--color` | Badge text color (badge variant) | `var(--sc-kit--color--text--on-accent)` |
|
|
29
|
+
| `--sc-kit--duration--badge--padding` | Badge padding (badge variant) | `var(--sc-kit--space--1) var(--sc-kit--space--2)` |
|
|
30
|
+
| `--sc-kit--duration--badge--border-radius` | Badge corner radius (badge variant) | `var(--sc-kit--radius--sm)` |
|
|
31
|
+
| `--sc-kit--duration--badge--font-size` | Badge font size (badge variant) | `var(--sc-kit--font-size--xs)` |
|
|
32
|
+
-->
|
|
33
|
+
<style>.duration {
|
|
34
|
+
font-variant-numeric: tabular-nums;
|
|
35
|
+
}
|
|
36
|
+
.duration--badge {
|
|
37
|
+
--_duration--badge-background: var(--sc-kit--duration--badge--background, rgb(0 0 0 / 55%));
|
|
38
|
+
--_duration--badge-color: var(--sc-kit--duration--badge--color, var(--sc-kit--color--text--on-accent));
|
|
39
|
+
--_duration--badge-padding: var(--sc-kit--duration--badge--padding, var(--sc-kit--space--1) var(--sc-kit--space--2));
|
|
40
|
+
--_duration--badge-border-radius: var(--sc-kit--duration--badge--border-radius, var(--sc-kit--radius--sm));
|
|
41
|
+
--_duration--badge-font-size: var(--sc-kit--duration--badge--font-size, var(--sc-kit--font-size--xs));
|
|
42
|
+
display: inline-block;
|
|
43
|
+
padding: var(--_duration--badge-padding);
|
|
44
|
+
background: var(--_duration--badge-background);
|
|
45
|
+
border-radius: var(--_duration--badge-border-radius);
|
|
46
|
+
color: var(--_duration--badge-color);
|
|
47
|
+
font-size: var(--_duration--badge-font-size);
|
|
48
|
+
line-height: var(--sc-kit--leading--normal);
|
|
49
|
+
}</style>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
type Props = {
|
|
2
|
+
/** Duration in seconds. Zero, negative, or `null` renders nothing unless `showZero`. */
|
|
3
|
+
seconds: number | null;
|
|
4
|
+
/** Visual style — `raw` is bare text; `badge` is a dark overlay pill for media thumbnails. @default 'raw' */
|
|
5
|
+
variant?: 'raw' | 'badge';
|
|
6
|
+
/** Render `0:00` for a null / zero / negative duration instead of nothing. @default false */
|
|
7
|
+
showZero?: boolean;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Renders a media/time duration given in seconds as a human-readable clock string — `m:ss` under an
|
|
11
|
+
* hour, `h:mm:ss` at or above (seconds are rounded, so a 60-second carry rolls up). `null` or ≤ 0
|
|
12
|
+
* renders nothing; pass `showZero` to force `0:00`. `variant='raw'` (default) is bare text that
|
|
13
|
+
* inherits the parent's typography; `variant='badge'` is a dark overlay pill for the bottom corner of
|
|
14
|
+
* a video thumbnail. Placement (e.g. absolute over media) is the consumer's job via the cascade.
|
|
15
|
+
*
|
|
16
|
+
* ### CSS Custom Properties
|
|
17
|
+
* | Property | Description | Default |
|
|
18
|
+
* |---|---|---|
|
|
19
|
+
* | `--sc-kit--duration--badge--background` | Badge background (badge variant) | `rgb(0 0 0 / 55%)` (dark translucent) |
|
|
20
|
+
* | `--sc-kit--duration--badge--color` | Badge text color (badge variant) | `var(--sc-kit--color--text--on-accent)` |
|
|
21
|
+
* | `--sc-kit--duration--badge--padding` | Badge padding (badge variant) | `var(--sc-kit--space--1) var(--sc-kit--space--2)` |
|
|
22
|
+
* | `--sc-kit--duration--badge--border-radius` | Badge corner radius (badge variant) | `var(--sc-kit--radius--sm)` |
|
|
23
|
+
* | `--sc-kit--duration--badge--font-size` | Badge font size (badge variant) | `var(--sc-kit--font-size--xs)` |
|
|
24
|
+
*/
|
|
25
|
+
declare const Cmp: import("svelte").Component<Props, {}, "">;
|
|
26
|
+
type Cmp = ReturnType<typeof Cmp>;
|
|
27
|
+
export default Cmp;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Duration } from './cmp.duration.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Duration } from './cmp.duration.svelte';
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
<script lang="ts">import { Badge } from '../badge';
|
|
2
|
+
import { Icon, IconSlot } from '../icon';
|
|
3
|
+
import IconCheck from '@fluentui/svg-icons/icons/checkmark_12_regular.svg?raw';
|
|
4
|
+
let { eyebrow, title, description, highlights, featuresTitle, features, headingLevel = 2, media, actions } = $props();
|
|
5
|
+
const clampLevel = (level) => Math.min(Math.max(level, 1), 6);
|
|
6
|
+
const titleLevel = $derived(clampLevel(headingLevel));
|
|
7
|
+
const titleTag = $derived(`h${titleLevel}`);
|
|
8
|
+
const featuresTitleTag = $derived(`h${Math.min(titleLevel + 1, 6)}`);
|
|
9
|
+
const featureItemTag = $derived(`h${Math.min(titleLevel + 2, 6)}`);
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<section class="feature-intro">
|
|
13
|
+
<div class="feature-intro__hero">
|
|
14
|
+
<div class="feature-intro__hero-grid" class:feature-intro__hero-grid--with-media={!!media}>
|
|
15
|
+
{#if media}
|
|
16
|
+
<div class="feature-intro__media" aria-hidden="true">{@render media()}</div>
|
|
17
|
+
{/if}
|
|
18
|
+
<div class="feature-intro__body">
|
|
19
|
+
{#if eyebrow}
|
|
20
|
+
<Badge variant="accent">
|
|
21
|
+
{#if eyebrow.icon}<IconSlot icon={eyebrow.icon} size="sm" />{/if}
|
|
22
|
+
{eyebrow.label}
|
|
23
|
+
</Badge>
|
|
24
|
+
{/if}
|
|
25
|
+
<svelte:element this={titleTag} class="feature-intro__title">{title}</svelte:element>
|
|
26
|
+
{#if description}
|
|
27
|
+
<p class="feature-intro__lede">{description}</p>
|
|
28
|
+
{/if}
|
|
29
|
+
{#if actions}
|
|
30
|
+
<div class="feature-intro__actions">{@render actions()}</div>
|
|
31
|
+
{/if}
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
{#if highlights && highlights.length > 0}
|
|
36
|
+
<ul class="feature-intro__highlights">
|
|
37
|
+
{#each highlights as item, i (i)}
|
|
38
|
+
<li class="feature-intro__highlight">
|
|
39
|
+
<span class="feature-intro__highlight-check" aria-hidden="true"><Icon src={IconCheck} /></span>
|
|
40
|
+
{item}
|
|
41
|
+
</li>
|
|
42
|
+
{/each}
|
|
43
|
+
</ul>
|
|
44
|
+
{/if}
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
{#if features && features.length > 0}
|
|
48
|
+
<div class="feature-intro__features">
|
|
49
|
+
{#if featuresTitle}
|
|
50
|
+
<svelte:element this={featuresTitleTag} class="feature-intro__features-title">{featuresTitle}</svelte:element>
|
|
51
|
+
{/if}
|
|
52
|
+
<ul class="feature-intro__feature-list">
|
|
53
|
+
{#each features as feature, i (i)}
|
|
54
|
+
<li class="feature-intro__feature">
|
|
55
|
+
{#if feature.icon}
|
|
56
|
+
<div class="feature-intro__feature-icon" aria-hidden="true"><IconSlot icon={feature.icon} size="md" /></div>
|
|
57
|
+
{/if}
|
|
58
|
+
<div class="feature-intro__feature-body">
|
|
59
|
+
<svelte:element this={featureItemTag} class="feature-intro__feature-title">
|
|
60
|
+
{feature.title}
|
|
61
|
+
{#if feature.badge}<Badge variant="neutral" size="sm">{feature.badge}</Badge>{/if}
|
|
62
|
+
</svelte:element>
|
|
63
|
+
<p class="feature-intro__feature-description">{feature.description}</p>
|
|
64
|
+
</div>
|
|
65
|
+
</li>
|
|
66
|
+
{/each}
|
|
67
|
+
</ul>
|
|
68
|
+
</div>
|
|
69
|
+
{/if}
|
|
70
|
+
</section>
|
|
71
|
+
|
|
72
|
+
<!--
|
|
73
|
+
@component
|
|
74
|
+
Onboarding / feature-introduction surface for any app area — a paneled hero (eyebrow, title, lede, media + CTA snippets, optional highlights checklist) followed by an optional list of capabilities with per-row badges. All copy comes from props, so it carries no built-in strings. Renders at `100%` width; wrap in the consumer's page for background, padding and max-width.
|
|
75
|
+
|
|
76
|
+
### CSS Custom Properties
|
|
77
|
+
| Property | Description | Default |
|
|
78
|
+
|---|---|---|
|
|
79
|
+
| `--sc-kit--feature-intro--gap` | Gap between the hero and the feature list | `--sc-kit--space--12` |
|
|
80
|
+
| `--sc-kit--feature-intro--background` | Hero panel background | `--sc-kit--color--bg--panel` |
|
|
81
|
+
| `--sc-kit--feature-intro--border-color` | Hero / feature card border color | `--sc-kit--color--border` |
|
|
82
|
+
| `--sc-kit--feature-intro--radius` | Hero / feature card corner radius | `--sc-kit--radius--lg` |
|
|
83
|
+
| `--sc-kit--feature-intro--padding` | Hero panel padding | `--sc-kit--space--10` |
|
|
84
|
+
| `--sc-kit--feature-intro--hero--gap` | Gap between media and body columns | `--sc-kit--space--12` |
|
|
85
|
+
| `--sc-kit--feature-intro--media--width` | Media column width | `18.75rem` (300px) |
|
|
86
|
+
| `--sc-kit--feature-intro--media--aspect-ratio` | Media frame aspect ratio | `2 / 3` |
|
|
87
|
+
| `--sc-kit--feature-intro--media--radius` | Media frame corner radius | `--sc-kit--radius--md` |
|
|
88
|
+
| `--sc-kit--feature-intro--title--font-size` | Title font size | `--sc-kit--font-size--3xl` |
|
|
89
|
+
| `--sc-kit--feature-intro--title--color` | Title color | `--sc-kit--color--text--primary` |
|
|
90
|
+
| `--sc-kit--feature-intro--description--color` | Lede color | `--sc-kit--color--text--secondary` |
|
|
91
|
+
-->
|
|
92
|
+
|
|
93
|
+
<style>.feature-intro {
|
|
94
|
+
--_fi--gap: var(--sc-kit--feature-intro--gap, var(--sc-kit--space--12));
|
|
95
|
+
--_fi--background: var(--sc-kit--feature-intro--background, var(--sc-kit--color--bg--panel));
|
|
96
|
+
--_fi--border-color: var(--sc-kit--feature-intro--border-color, var(--sc-kit--color--border));
|
|
97
|
+
--_fi--radius: var(--sc-kit--feature-intro--radius, var(--sc-kit--radius--lg));
|
|
98
|
+
--_fi--padding: var(--sc-kit--feature-intro--padding, var(--sc-kit--space--10));
|
|
99
|
+
--_fi--hero-gap: var(--sc-kit--feature-intro--hero--gap, var(--sc-kit--space--12));
|
|
100
|
+
--_fi--media-width: var(--sc-kit--feature-intro--media--width, 18.75rem);
|
|
101
|
+
--_fi--media-aspect: var(--sc-kit--feature-intro--media--aspect-ratio, 2 / 3);
|
|
102
|
+
--_fi--media-radius: var(--sc-kit--feature-intro--media--radius, var(--sc-kit--radius--md));
|
|
103
|
+
--_fi--title-font-size: var(--sc-kit--feature-intro--title--font-size, var(--sc-kit--font-size--3xl));
|
|
104
|
+
--_fi--title-color: var(--sc-kit--feature-intro--title--color, var(--sc-kit--color--text--primary));
|
|
105
|
+
--_fi--description-color: var(--sc-kit--feature-intro--description--color, var(--sc-kit--color--text--secondary));
|
|
106
|
+
container-type: inline-size;
|
|
107
|
+
display: flex;
|
|
108
|
+
flex-direction: column;
|
|
109
|
+
gap: var(--_fi--gap);
|
|
110
|
+
width: 100%;
|
|
111
|
+
}
|
|
112
|
+
.feature-intro__hero {
|
|
113
|
+
padding: var(--_fi--padding);
|
|
114
|
+
background: var(--_fi--background);
|
|
115
|
+
border: 1px solid var(--_fi--border-color);
|
|
116
|
+
border-radius: var(--_fi--radius);
|
|
117
|
+
}
|
|
118
|
+
.feature-intro__hero-grid {
|
|
119
|
+
display: grid;
|
|
120
|
+
grid-template-columns: 1fr;
|
|
121
|
+
align-items: center;
|
|
122
|
+
gap: var(--_fi--hero-gap);
|
|
123
|
+
}
|
|
124
|
+
.feature-intro__hero-grid--with-media {
|
|
125
|
+
grid-template-columns: var(--_fi--media-width) 1fr;
|
|
126
|
+
}
|
|
127
|
+
.feature-intro__hero-grid {
|
|
128
|
+
/* Set 'container-type: inline-size;' to reference container*/
|
|
129
|
+
}
|
|
130
|
+
@container (width < 45rem) {
|
|
131
|
+
.feature-intro__hero-grid {
|
|
132
|
+
grid-template-columns: 1fr;
|
|
133
|
+
justify-items: center;
|
|
134
|
+
gap: var(--sc-kit--space--8);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
.feature-intro__media {
|
|
138
|
+
width: var(--_fi--media-width);
|
|
139
|
+
max-width: 100%;
|
|
140
|
+
aspect-ratio: var(--_fi--media-aspect);
|
|
141
|
+
overflow: hidden;
|
|
142
|
+
border-radius: var(--_fi--media-radius);
|
|
143
|
+
background: var(--sc-kit--color--bg--field-alt);
|
|
144
|
+
border: 1px solid var(--_fi--border-color);
|
|
145
|
+
}
|
|
146
|
+
.feature-intro__media :global(img),
|
|
147
|
+
.feature-intro__media :global(video) {
|
|
148
|
+
display: block;
|
|
149
|
+
width: 100%;
|
|
150
|
+
height: 100%;
|
|
151
|
+
object-fit: cover;
|
|
152
|
+
}
|
|
153
|
+
.feature-intro__body {
|
|
154
|
+
display: flex;
|
|
155
|
+
flex-direction: column;
|
|
156
|
+
align-items: flex-start;
|
|
157
|
+
gap: var(--sc-kit--space--4);
|
|
158
|
+
text-align: left;
|
|
159
|
+
min-width: 0;
|
|
160
|
+
/* Set 'container-type: inline-size;' to reference container*/
|
|
161
|
+
}
|
|
162
|
+
@container (width < 45rem) {
|
|
163
|
+
.feature-intro__body {
|
|
164
|
+
align-items: center;
|
|
165
|
+
text-align: center;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
.feature-intro__title {
|
|
169
|
+
margin: 0;
|
|
170
|
+
font-size: var(--_fi--title-font-size);
|
|
171
|
+
font-weight: var(--sc-kit--font-weight--semibold);
|
|
172
|
+
line-height: var(--sc-kit--leading--tight);
|
|
173
|
+
letter-spacing: var(--sc-kit--letter-spacing--tight);
|
|
174
|
+
color: var(--_fi--title-color);
|
|
175
|
+
}
|
|
176
|
+
.feature-intro__lede {
|
|
177
|
+
margin: 0;
|
|
178
|
+
font-size: var(--sc-kit--font-size--md);
|
|
179
|
+
line-height: var(--sc-kit--leading--relaxed);
|
|
180
|
+
color: var(--_fi--description-color);
|
|
181
|
+
}
|
|
182
|
+
.feature-intro__actions {
|
|
183
|
+
display: flex;
|
|
184
|
+
flex-wrap: wrap;
|
|
185
|
+
align-items: center;
|
|
186
|
+
gap: var(--sc-kit--space--4);
|
|
187
|
+
margin-top: var(--sc-kit--space--2);
|
|
188
|
+
}
|
|
189
|
+
.feature-intro__highlights {
|
|
190
|
+
list-style: none;
|
|
191
|
+
margin: var(--sc-kit--space--8) 0 0;
|
|
192
|
+
padding: var(--sc-kit--space--5) 0 0;
|
|
193
|
+
border-top: 1px solid var(--_fi--border-color);
|
|
194
|
+
display: flex;
|
|
195
|
+
flex-wrap: wrap;
|
|
196
|
+
justify-content: center;
|
|
197
|
+
gap: var(--sc-kit--space--2) var(--sc-kit--space--6);
|
|
198
|
+
}
|
|
199
|
+
.feature-intro__highlight {
|
|
200
|
+
display: inline-flex;
|
|
201
|
+
align-items: center;
|
|
202
|
+
gap: var(--sc-kit--space--2);
|
|
203
|
+
font-size: var(--sc-kit--font-size--sm);
|
|
204
|
+
color: var(--sc-kit--color--text--secondary);
|
|
205
|
+
}
|
|
206
|
+
.feature-intro__highlight-check {
|
|
207
|
+
flex-shrink: 0;
|
|
208
|
+
display: inline-flex;
|
|
209
|
+
align-items: center;
|
|
210
|
+
justify-content: center;
|
|
211
|
+
width: 1rem;
|
|
212
|
+
height: 1rem;
|
|
213
|
+
border-radius: var(--sc-kit--radius--circle);
|
|
214
|
+
background: var(--sc-kit--color--success--soft);
|
|
215
|
+
color: var(--sc-kit--color--success);
|
|
216
|
+
--sc-kit--icon--size: 0.75rem;
|
|
217
|
+
}
|
|
218
|
+
.feature-intro__features-title {
|
|
219
|
+
margin: 0 0 var(--sc-kit--space--4);
|
|
220
|
+
font-size: var(--sc-kit--font-size--sm);
|
|
221
|
+
font-weight: var(--sc-kit--font-weight--semibold);
|
|
222
|
+
letter-spacing: var(--sc-kit--letter-spacing--wide);
|
|
223
|
+
text-transform: uppercase;
|
|
224
|
+
color: var(--sc-kit--color--text--secondary);
|
|
225
|
+
}
|
|
226
|
+
.feature-intro__feature-list {
|
|
227
|
+
list-style: none;
|
|
228
|
+
margin: 0;
|
|
229
|
+
padding: 0;
|
|
230
|
+
display: flex;
|
|
231
|
+
flex-direction: column;
|
|
232
|
+
gap: var(--sc-kit--space--2);
|
|
233
|
+
}
|
|
234
|
+
.feature-intro__feature {
|
|
235
|
+
display: flex;
|
|
236
|
+
align-items: flex-start;
|
|
237
|
+
gap: var(--sc-kit--space--4);
|
|
238
|
+
padding: var(--sc-kit--space--5);
|
|
239
|
+
border: 1px solid var(--_fi--border-color);
|
|
240
|
+
border-radius: var(--_fi--radius);
|
|
241
|
+
background: var(--_fi--background);
|
|
242
|
+
}
|
|
243
|
+
.feature-intro__feature-icon {
|
|
244
|
+
flex-shrink: 0;
|
|
245
|
+
display: flex;
|
|
246
|
+
align-items: center;
|
|
247
|
+
justify-content: center;
|
|
248
|
+
width: 2.25rem;
|
|
249
|
+
height: 2.25rem;
|
|
250
|
+
border-radius: var(--sc-kit--radius--md);
|
|
251
|
+
background: var(--sc-kit--color--bg--field-alt);
|
|
252
|
+
color: var(--sc-kit--color--text--primary);
|
|
253
|
+
}
|
|
254
|
+
.feature-intro__feature-body {
|
|
255
|
+
flex: 1;
|
|
256
|
+
min-width: 0;
|
|
257
|
+
}
|
|
258
|
+
.feature-intro__feature-title {
|
|
259
|
+
display: flex;
|
|
260
|
+
align-items: center;
|
|
261
|
+
flex-wrap: wrap;
|
|
262
|
+
gap: var(--sc-kit--space--2);
|
|
263
|
+
margin: 0 0 var(--sc-kit--space--1);
|
|
264
|
+
font-size: var(--sc-kit--font-size--md);
|
|
265
|
+
font-weight: var(--sc-kit--font-weight--semibold);
|
|
266
|
+
color: var(--sc-kit--color--text--primary);
|
|
267
|
+
}
|
|
268
|
+
.feature-intro__feature-description {
|
|
269
|
+
margin: 0;
|
|
270
|
+
font-size: var(--sc-kit--font-size--sm);
|
|
271
|
+
line-height: var(--sc-kit--leading--normal);
|
|
272
|
+
color: var(--sc-kit--color--text--secondary);
|
|
273
|
+
}</style>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { FeatureIntroEyebrow, FeatureIntroItem } from './types';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
type Props = {
|
|
4
|
+
/** Accent chip above the title — names the area or product (e.g. "Content Lab"). */
|
|
5
|
+
eyebrow?: FeatureIntroEyebrow;
|
|
6
|
+
/** Main heading. */
|
|
7
|
+
title: string;
|
|
8
|
+
/** Supporting paragraph beneath the title. */
|
|
9
|
+
description?: string;
|
|
10
|
+
/** Short proof points rendered as a checklist below the hero. */
|
|
11
|
+
highlights?: string[];
|
|
12
|
+
/** Label above the feature list (e.g. a localized "What's included"). Omit to hide it. */
|
|
13
|
+
featuresTitle?: string;
|
|
14
|
+
/** Capabilities to list out. Omit (or pass `[]`) to render the hero alone. */
|
|
15
|
+
features?: FeatureIntroItem[];
|
|
16
|
+
/** Heading level of the title; the features-title and feature headings nest one and two levels below it (each capped at h6). Keep to 2–4 when features are present, or the sub-headings collapse onto the same level. @default 2 */
|
|
17
|
+
headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
18
|
+
/**
|
|
19
|
+
* Hero media — an `<img>`, kit `<Image>`, video, or illustration. Fills the media frame (`object-fit: cover`).
|
|
20
|
+
* Images must carry `alt=""` — the frame is `aria-hidden` and decorative; the meaning lives in the title.
|
|
21
|
+
* Omit for a single-column hero.
|
|
22
|
+
*/
|
|
23
|
+
media?: Snippet;
|
|
24
|
+
/** Call-to-action area, typically a kit `<Button type="anchor" href={...}>`. */
|
|
25
|
+
actions?: Snippet;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Onboarding / feature-introduction surface for any app area — a paneled hero (eyebrow, title, lede, media + CTA snippets, optional highlights checklist) followed by an optional list of capabilities with per-row badges. All copy comes from props, so it carries no built-in strings. Renders at `100%` width; wrap in the consumer's page for background, padding and max-width.
|
|
29
|
+
*
|
|
30
|
+
* ### CSS Custom Properties
|
|
31
|
+
* | Property | Description | Default |
|
|
32
|
+
* |---|---|---|
|
|
33
|
+
* | `--sc-kit--feature-intro--gap` | Gap between the hero and the feature list | `--sc-kit--space--12` |
|
|
34
|
+
* | `--sc-kit--feature-intro--background` | Hero panel background | `--sc-kit--color--bg--panel` |
|
|
35
|
+
* | `--sc-kit--feature-intro--border-color` | Hero / feature card border color | `--sc-kit--color--border` |
|
|
36
|
+
* | `--sc-kit--feature-intro--radius` | Hero / feature card corner radius | `--sc-kit--radius--lg` |
|
|
37
|
+
* | `--sc-kit--feature-intro--padding` | Hero panel padding | `--sc-kit--space--10` |
|
|
38
|
+
* | `--sc-kit--feature-intro--hero--gap` | Gap between media and body columns | `--sc-kit--space--12` |
|
|
39
|
+
* | `--sc-kit--feature-intro--media--width` | Media column width | `18.75rem` (300px) |
|
|
40
|
+
* | `--sc-kit--feature-intro--media--aspect-ratio` | Media frame aspect ratio | `2 / 3` |
|
|
41
|
+
* | `--sc-kit--feature-intro--media--radius` | Media frame corner radius | `--sc-kit--radius--md` |
|
|
42
|
+
* | `--sc-kit--feature-intro--title--font-size` | Title font size | `--sc-kit--font-size--3xl` |
|
|
43
|
+
* | `--sc-kit--feature-intro--title--color` | Title color | `--sc-kit--color--text--primary` |
|
|
44
|
+
* | `--sc-kit--feature-intro--description--color` | Lede color | `--sc-kit--color--text--secondary` |
|
|
45
|
+
*/
|
|
46
|
+
declare const Cmp: import("svelte").Component<Props, {}, "">;
|
|
47
|
+
type Cmp = ReturnType<typeof Cmp>;
|
|
48
|
+
export default Cmp;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as FeatureIntro } from './cmp.feature-intro.svelte';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IconProp } from '../icon';
|
|
2
|
+
/** Eyebrow chip shown above the FeatureIntro title — names the area or product. */
|
|
3
|
+
export type FeatureIntroEyebrow = {
|
|
4
|
+
label: string;
|
|
5
|
+
/** Leading icon — string SVG source, `{ src, color?, size? }` object, or custom snippet. */
|
|
6
|
+
icon?: IconProp;
|
|
7
|
+
};
|
|
8
|
+
/** A single capability row in the FeatureIntro feature list. */
|
|
9
|
+
export type FeatureIntroItem = {
|
|
10
|
+
/** Leading icon — string SVG source, `{ src, color?, size? }` object, or custom snippet. */
|
|
11
|
+
icon?: IconProp;
|
|
12
|
+
/** Feature name. */
|
|
13
|
+
title: string;
|
|
14
|
+
/** One- to two-sentence explanation of the feature. */
|
|
15
|
+
description: string;
|
|
16
|
+
/** Optional pill rendered after the title (e.g. a localized "Coming soon"). Supply the text yourself — the kit adds no copy of its own. */
|
|
17
|
+
badge?: string;
|
|
18
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script lang="ts">const { label, fontFamily = 'mono', divider = false } = $props();
|
|
1
|
+
<script lang="ts">const { label, fontFamily = 'mono', tone = 'primary', divider = false } = $props();
|
|
2
2
|
export {};
|
|
3
3
|
</script>
|
|
4
4
|
|
|
@@ -7,6 +7,8 @@ export {};
|
|
|
7
7
|
class:nav-menu-header--mono={fontFamily === 'mono'}
|
|
8
8
|
class:nav-menu-header--sans={fontFamily === 'sans'}
|
|
9
9
|
class:nav-menu-header--display={fontFamily === 'display'}
|
|
10
|
+
class:nav-menu-header--primary={tone === 'primary'}
|
|
11
|
+
class:nav-menu-header--secondary={tone === 'secondary'}
|
|
10
12
|
class:nav-menu-header--divided={divider}>
|
|
11
13
|
{label}
|
|
12
14
|
</div>
|
|
@@ -14,25 +16,31 @@ export {};
|
|
|
14
16
|
<!--
|
|
15
17
|
@component
|
|
16
18
|
NavMenuHeader — group label rendered above a stack of `NavMenuItem`s. Monospace 400 by default;
|
|
17
|
-
non-mono families default to weight 500.
|
|
18
|
-
|
|
19
|
-
standalone divider and
|
|
19
|
+
non-mono families default to weight 500. `tone` switches the text between primary and secondary.
|
|
20
|
+
Use one per `NavMenuGroup`. Pass `divider` to draw a bottom separator (same style as
|
|
21
|
+
`NavMenuDivider`), so the header itself groups the items below it without a standalone divider and
|
|
22
|
+
wider spacing.
|
|
20
23
|
|
|
21
24
|
### CSS Custom Properties
|
|
22
25
|
| Property | Description | Default |
|
|
23
26
|
|---|---|---|
|
|
24
27
|
| `--sc-kit--nav-menu-header--font-family` | Label font family | `var(--sc-kit--font--mono)` |
|
|
25
28
|
| `--sc-kit--nav-menu-header--font-weight` | Label font weight | `400` (mono) / `500` (other families) |
|
|
29
|
+
| `--sc-kit--nav-menu-header--color` | Label text color | `var(--sc-kit--color--text--primary)` (tone-dependent) |
|
|
26
30
|
-->
|
|
27
31
|
<style>.nav-menu-header {
|
|
28
|
-
--_nav-menu-header--font-family: var(--sc-kit--nav-menu-header--font-family, var(--_nav-menu-header--font-family-default));
|
|
29
|
-
--_nav-menu-header--font-weight: var(
|
|
32
|
+
--_nav-menu-header--font-family: var(--sc-kit--nav-menu-header--font-family, var(--_nav-menu-header--font-family-default, var(--sc-kit--font--mono)));
|
|
33
|
+
--_nav-menu-header--font-weight: var(
|
|
34
|
+
--sc-kit--nav-menu-header--font-weight,
|
|
35
|
+
var(--_nav-menu-header--font-weight-default, var(--sc-kit--font-weight--regular))
|
|
36
|
+
);
|
|
37
|
+
--_nav-menu-header--color: var(--sc-kit--nav-menu-header--color, var(--_nav-menu-header--color-default, var(--sc-kit--color--text--primary)));
|
|
30
38
|
padding: var(--sc-kit--space--2) var(--sc-kit--space--5);
|
|
31
39
|
font-family: var(--_nav-menu-header--font-family), sans-serif;
|
|
32
40
|
font-size: var(--sc-kit--font-size--md);
|
|
33
41
|
font-weight: var(--_nav-menu-header--font-weight);
|
|
34
42
|
line-height: var(--sc-kit--leading--tight);
|
|
35
|
-
color: var(--
|
|
43
|
+
color: var(--_nav-menu-header--color);
|
|
36
44
|
}
|
|
37
45
|
.nav-menu-header--mono {
|
|
38
46
|
--_nav-menu-header--font-family-default: var(--sc-kit--font--mono);
|
|
@@ -46,6 +54,12 @@ standalone divider and wider spacing.
|
|
|
46
54
|
--_nav-menu-header--font-family-default: var(--sc-kit--font--display);
|
|
47
55
|
--_nav-menu-header--font-weight-default: var(--sc-kit--font-weight--medium);
|
|
48
56
|
}
|
|
57
|
+
.nav-menu-header--primary {
|
|
58
|
+
--_nav-menu-header--color-default: var(--sc-kit--color--text--primary);
|
|
59
|
+
}
|
|
60
|
+
.nav-menu-header--secondary {
|
|
61
|
+
--_nav-menu-header--color-default: var(--sc-kit--color--text--secondary);
|
|
62
|
+
}
|
|
49
63
|
.nav-menu-header--divided::after {
|
|
50
64
|
content: "";
|
|
51
65
|
display: block;
|
|
@@ -3,20 +3,24 @@ type Props = {
|
|
|
3
3
|
label: string;
|
|
4
4
|
/** Label font family; each family carries its own default weight (mono → 400, others → 500). Overridable via `--sc-kit--nav-menu-header--font-family`. @default 'mono' */
|
|
5
5
|
fontFamily?: KitFontFamily;
|
|
6
|
+
/** Text tone. Overridable via `--sc-kit--nav-menu-header--color`. @default 'primary' */
|
|
7
|
+
tone?: 'primary' | 'secondary';
|
|
6
8
|
/** Draw a bottom separator (same style as `NavMenuDivider`) under the label. @default false */
|
|
7
9
|
divider?: boolean;
|
|
8
10
|
};
|
|
9
11
|
/**
|
|
10
12
|
* NavMenuHeader — group label rendered above a stack of `NavMenuItem`s. Monospace 400 by default;
|
|
11
|
-
* non-mono families default to weight 500.
|
|
12
|
-
*
|
|
13
|
-
* standalone divider and
|
|
13
|
+
* non-mono families default to weight 500. `tone` switches the text between primary and secondary.
|
|
14
|
+
* Use one per `NavMenuGroup`. Pass `divider` to draw a bottom separator (same style as
|
|
15
|
+
* `NavMenuDivider`), so the header itself groups the items below it without a standalone divider and
|
|
16
|
+
* wider spacing.
|
|
14
17
|
*
|
|
15
18
|
* ### CSS Custom Properties
|
|
16
19
|
* | Property | Description | Default |
|
|
17
20
|
* |---|---|---|
|
|
18
21
|
* | `--sc-kit--nav-menu-header--font-family` | Label font family | `var(--sc-kit--font--mono)` |
|
|
19
22
|
* | `--sc-kit--nav-menu-header--font-weight` | Label font weight | `400` (mono) / `500` (other families) |
|
|
23
|
+
* | `--sc-kit--nav-menu-header--color` | Label text color | `var(--sc-kit--color--text--primary)` (tone-dependent) |
|
|
20
24
|
*/
|
|
21
25
|
declare const Cmp: import("svelte").Component<Props, {}, "">;
|
|
22
26
|
type Cmp = ReturnType<typeof Cmp>;
|
|
@@ -113,7 +113,7 @@ Completed sidebar steps are clickable to go back; `canAdvance(step)` gates Next
|
|
|
113
113
|
-->
|
|
114
114
|
|
|
115
115
|
<style>.stepper-dialog-layout {
|
|
116
|
-
--_sdl--sidebar-width: var(--sc-kit--stepper-dialog-layout--sidebar--width,
|
|
116
|
+
--_sdl--sidebar-width: var(--sc-kit--stepper-dialog-layout--sidebar--width, 20rem);
|
|
117
117
|
--_sdl--sidebar-background: var(--sc-kit--stepper-dialog-layout--sidebar--background, var(--sc-kit--color--bg--field-alt));
|
|
118
118
|
--sc-kit--dialog--height: var(--sc-kit--stepper-dialog-layout--height, auto);
|
|
119
119
|
--sc-kit--dialog--body--overflow-y: auto;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@streamscloud/kit",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.13",
|
|
4
4
|
"author": "StreamsCloud",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -163,6 +163,10 @@
|
|
|
163
163
|
"types": "./dist/ui/drawer/index.d.ts",
|
|
164
164
|
"svelte": "./dist/ui/drawer/index.js"
|
|
165
165
|
},
|
|
166
|
+
"./ui/duration": {
|
|
167
|
+
"types": "./dist/ui/duration/index.d.ts",
|
|
168
|
+
"svelte": "./dist/ui/duration/index.js"
|
|
169
|
+
},
|
|
166
170
|
"./ui/dynamic-component": {
|
|
167
171
|
"types": "./dist/ui/dynamic-component/index.d.ts",
|
|
168
172
|
"svelte": "./dist/ui/dynamic-component/index.js"
|
|
@@ -175,6 +179,10 @@
|
|
|
175
179
|
"types": "./dist/ui/empty-state/index.d.ts",
|
|
176
180
|
"svelte": "./dist/ui/empty-state/index.js"
|
|
177
181
|
},
|
|
182
|
+
"./ui/feature-intro": {
|
|
183
|
+
"types": "./dist/ui/feature-intro/index.d.ts",
|
|
184
|
+
"svelte": "./dist/ui/feature-intro/index.js"
|
|
185
|
+
},
|
|
178
186
|
"./ui/file-uploader": {
|
|
179
187
|
"types": "./dist/ui/file-uploader/index.d.ts",
|
|
180
188
|
"svelte": "./dist/ui/file-uploader/index.js"
|