@streamscloud/kit 0.40.2 → 0.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/theme/app-theme.svelte.d.ts +1 -0
- package/dist/core/theme/app-theme.svelte.js +11 -1
- package/dist/styles/_index.scss +1 -0
- package/dist/styles/_semantic.scss +2 -1
- package/dist/styles/_theme.scss +8 -0
- package/dist/ui/cropper/img-cropper/cmp.img-cropper-controls.svelte +1 -1
- package/dist/ui/rich-text-input/cmp.rich-text-input.svelte +7 -4
- package/dist/ui/rich-text-input/hugerte.declarations.d.ts +1 -0
- package/dist/ui/textarea/cmp.textarea.svelte +39 -5
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ declare class AppThemeContainer {
|
|
|
3
3
|
private _active;
|
|
4
4
|
private _mediaQuery;
|
|
5
5
|
private _isDarkMode;
|
|
6
|
+
private _transitionSuppressionId;
|
|
6
7
|
get active(): AppThemeValue;
|
|
7
8
|
/** Whether dark mode is currently active (resolves 'auto' based on system preference) */
|
|
8
9
|
get isDarkMode(): boolean;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { isBrowser } from '../utils';
|
|
2
2
|
import { ThemeCookie } from './theme-cookie';
|
|
3
3
|
import { getColorScheme } from './types';
|
|
4
|
+
const NO_TRANSITION_CLASS = 'sc-kit-no-theme-transition';
|
|
4
5
|
class AppThemeContainer {
|
|
5
6
|
_active = $state('auto');
|
|
6
7
|
_mediaQuery = null;
|
|
7
8
|
_isDarkMode = $state(false);
|
|
9
|
+
_transitionSuppressionId = 0;
|
|
8
10
|
get active() {
|
|
9
11
|
return this._active;
|
|
10
12
|
}
|
|
@@ -42,7 +44,15 @@ class AppThemeContainer {
|
|
|
42
44
|
else {
|
|
43
45
|
this._isDarkMode = this._active === 'dark';
|
|
44
46
|
}
|
|
45
|
-
|
|
47
|
+
const html = document.documentElement;
|
|
48
|
+
html.classList.add(NO_TRANSITION_CLASS);
|
|
49
|
+
html.style.colorScheme = getColorScheme(this._active);
|
|
50
|
+
const suppressionId = ++this._transitionSuppressionId;
|
|
51
|
+
requestAnimationFrame(() => requestAnimationFrame(() => {
|
|
52
|
+
if (suppressionId === this._transitionSuppressionId) {
|
|
53
|
+
html.classList.remove(NO_TRANSITION_CLASS);
|
|
54
|
+
}
|
|
55
|
+
}));
|
|
46
56
|
};
|
|
47
57
|
}
|
|
48
58
|
export const AppTheme = new AppThemeContainer();
|
package/dist/styles/_index.scss
CHANGED
|
@@ -194,7 +194,8 @@
|
|
|
194
194
|
--sc-kit--shadow--md: 0 4px 6px -1px rgba(0, 0, 0, 0.08), 0 2px 4px -2px rgba(0, 0, 0, 0.04);
|
|
195
195
|
--sc-kit--shadow--lg: 0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.04);
|
|
196
196
|
--sc-kit--shadow--xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.04);
|
|
197
|
-
--sc-kit--shadow--card: 0
|
|
197
|
+
--sc-kit--shadow--card: 0 2px 16px rgba(0, 0, 0, 0.035);
|
|
198
|
+
--sc-kit--shadow--hairline: 0 1px 1px rgba(0, 0, 0, 0.1);
|
|
198
199
|
--sc-kit--shadow--focus: var(--sc-kit--focus-ring);
|
|
199
200
|
|
|
200
201
|
// ============================================================
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// !important: must override component-scoped transition declarations, including
|
|
2
|
+
// transitions.transition() mixin output.
|
|
3
|
+
.sc-kit-no-theme-transition,
|
|
4
|
+
.sc-kit-no-theme-transition *,
|
|
5
|
+
.sc-kit-no-theme-transition *::before,
|
|
6
|
+
.sc-kit-no-theme-transition *::after {
|
|
7
|
+
transition: none !important;
|
|
8
|
+
}
|
|
@@ -61,7 +61,7 @@ Can be placed anywhere in the layout.
|
|
|
61
61
|
color: var(--sc-kit--color--text--primary);
|
|
62
62
|
background: var(--sc-kit--color--bg--panel);
|
|
63
63
|
border: 1px solid var(--sc-kit--color--border);
|
|
64
|
-
box-shadow: var(--sc-kit--shadow--
|
|
64
|
+
box-shadow: var(--sc-kit--shadow--hairline);
|
|
65
65
|
}
|
|
66
66
|
.img-cropper-controls__button--cancel:hover {
|
|
67
67
|
background: var(--sc-kit--color--bg--hover);
|
|
@@ -12,6 +12,7 @@ let toolbarRef = $state.raw(undefined);
|
|
|
12
12
|
let editorRef = $state.raw(null);
|
|
13
13
|
let lastVal;
|
|
14
14
|
let everFocused = false;
|
|
15
|
+
const loc = new RichTextInputLocalization();
|
|
15
16
|
/** Insert an emoji at the current selection (or at the end if the editor was never focused). */
|
|
16
17
|
const insertEmoji = (emojiChar) => {
|
|
17
18
|
if (!editorRef) {
|
|
@@ -48,13 +49,15 @@ const applyChange = (editor) => {
|
|
|
48
49
|
on?.change?.(lastVal);
|
|
49
50
|
};
|
|
50
51
|
onMount(async () => {
|
|
51
|
-
const loc = new RichTextInputLocalization();
|
|
52
52
|
const { default: hugerte } = await import('hugerte');
|
|
53
|
+
// Snapshotted once — the editor does not re-init on a later theme change.
|
|
54
|
+
const isDarkMode = AppTheme.isDarkMode;
|
|
55
|
+
const skinUrl = isDarkMode ? 'hugerte-5-dark' : 'hugerte-5';
|
|
53
56
|
await Promise.all([
|
|
54
57
|
import('hugerte/models/dom'),
|
|
55
58
|
import('hugerte/themes/silver'),
|
|
56
|
-
|
|
57
|
-
import('hugerte/skins/ui/hugerte-5/content.inline.js'),
|
|
59
|
+
isDarkMode ? import('hugerte/skins/ui/hugerte-5-dark/skin.js') : import('hugerte/skins/ui/hugerte-5/skin.js'),
|
|
60
|
+
isDarkMode ? import('hugerte/skins/ui/hugerte-5-dark/content.inline.js') : import('hugerte/skins/ui/hugerte-5/content.inline.js'),
|
|
58
61
|
import('hugerte/icons/default'),
|
|
59
62
|
import('hugerte/plugins/advlist'),
|
|
60
63
|
import('hugerte/plugins/link'),
|
|
@@ -65,7 +68,7 @@ onMount(async () => {
|
|
|
65
68
|
target: elementRef,
|
|
66
69
|
inline: true,
|
|
67
70
|
// Must match the injected skin's resource key (`ui/<skin_url>/skin.css`) or HugeRTE fetches it over the network and 404s.
|
|
68
|
-
skin_url:
|
|
71
|
+
skin_url: skinUrl,
|
|
69
72
|
content_css: false,
|
|
70
73
|
fixed_toolbar_container: options?.fixedToolbarId ? `#${options.fixedToolbarId}` : undefined,
|
|
71
74
|
fixed_toolbar_container_target: options?.fixedToolbarId ? undefined : toolbarRef,
|
|
@@ -4,6 +4,7 @@ declare module 'hugerte/icons/default';
|
|
|
4
4
|
declare module 'hugerte/skins/ui/hugerte-5/skin.js';
|
|
5
5
|
declare module 'hugerte/skins/ui/hugerte-5-dark/skin.js';
|
|
6
6
|
declare module 'hugerte/skins/ui/hugerte-5/content.inline.js';
|
|
7
|
+
declare module 'hugerte/skins/ui/hugerte-5-dark/content.inline.js';
|
|
7
8
|
declare module 'hugerte/plugins/advlist';
|
|
8
9
|
declare module 'hugerte/plugins/link';
|
|
9
10
|
declare module 'hugerte/plugins/lists';
|
|
@@ -13,14 +13,14 @@ const resize = () => {
|
|
|
13
13
|
if (!textareaEl || !autoresize) {
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
16
|
-
textareaEl.style.
|
|
16
|
+
textareaEl.style.overflowY = 'hidden';
|
|
17
17
|
textareaEl.style.height = 'auto';
|
|
18
18
|
const styles = getComputedStyle(textareaEl);
|
|
19
19
|
const lineHeight = parseFloat(styles.lineHeight) || parseFloat(styles.fontSize) * 1.4;
|
|
20
20
|
const paddingY = parseFloat(styles.paddingTop) + parseFloat(styles.paddingBottom);
|
|
21
21
|
const max = lineHeight * maxRows + paddingY;
|
|
22
22
|
textareaEl.style.height = Math.min(textareaEl.scrollHeight, max) + 'px';
|
|
23
|
-
textareaEl.style.
|
|
23
|
+
textareaEl.style.overflowY = '';
|
|
24
24
|
};
|
|
25
25
|
const initTextarea = (node) => {
|
|
26
26
|
textareaEl = node;
|
|
@@ -139,7 +139,9 @@ const focusTextarea = () => textareaEl?.focus();
|
|
|
139
139
|
onfocus={() => on?.focus?.()}></textarea>
|
|
140
140
|
|
|
141
141
|
{#if emoji}
|
|
142
|
-
<
|
|
142
|
+
<span class="textarea__emoji">
|
|
143
|
+
<InputEmojiPicker size={size} on={{ select: handleEmojiSelect }} />
|
|
144
|
+
</span>
|
|
143
145
|
{/if}
|
|
144
146
|
</div>
|
|
145
147
|
|
|
@@ -202,7 +204,8 @@ what the field shows. Blank lines inside the text are left alone. Typing is unto
|
|
|
202
204
|
align-items: flex-end;
|
|
203
205
|
width: var(--_ta--width);
|
|
204
206
|
max-width: 100%;
|
|
205
|
-
padding: var(--_ta--padding-block)
|
|
207
|
+
padding-block: var(--_ta--padding-block);
|
|
208
|
+
padding-inline-start: var(--_ta--padding-inline);
|
|
206
209
|
background: var(--_ta--background);
|
|
207
210
|
border: 1px solid var(--_ta--border-color);
|
|
208
211
|
border-radius: var(--_ta--border-radius);
|
|
@@ -262,7 +265,9 @@ what the field shows. Blank lines inside the text are left alone. Typing is unto
|
|
|
262
265
|
flex: 1;
|
|
263
266
|
width: 100%;
|
|
264
267
|
min-width: 0;
|
|
265
|
-
padding: 0;
|
|
268
|
+
padding-block: 0;
|
|
269
|
+
padding-inline-start: 0;
|
|
270
|
+
padding-inline-end: var(--_ta--padding-inline);
|
|
266
271
|
margin: 0;
|
|
267
272
|
border: none;
|
|
268
273
|
outline: none;
|
|
@@ -272,10 +277,39 @@ what the field shows. Blank lines inside the text are left alone. Typing is unto
|
|
|
272
277
|
font-size: inherit;
|
|
273
278
|
line-height: inherit;
|
|
274
279
|
resize: none;
|
|
280
|
+
overflow-y: auto;
|
|
281
|
+
--_cross-browser-scrollbar--thumb-color: transparent;
|
|
282
|
+
--_cross-browser-scrollbar--track-color: transparent;
|
|
283
|
+
}
|
|
284
|
+
.textarea__el:hover {
|
|
285
|
+
--_cross-browser-scrollbar--thumb-color: var(--sc-kit--color--border--strong);
|
|
286
|
+
--_cross-browser-scrollbar--track-color: var(--scrollbar--track-color, transparent);
|
|
287
|
+
}
|
|
288
|
+
.textarea__el::-webkit-scrollbar {
|
|
289
|
+
width: 6px;
|
|
290
|
+
height: 6px;
|
|
291
|
+
}
|
|
292
|
+
.textarea__el::-webkit-scrollbar-track {
|
|
293
|
+
background: var(--_cross-browser-scrollbar--track-color);
|
|
294
|
+
border-radius: 100vw;
|
|
295
|
+
}
|
|
296
|
+
.textarea__el::-webkit-scrollbar-thumb {
|
|
297
|
+
background: var(--_cross-browser-scrollbar--thumb-color);
|
|
298
|
+
border-radius: 100vw;
|
|
299
|
+
}
|
|
300
|
+
@supports (scrollbar-color: transparent transparent) {
|
|
301
|
+
.textarea__el {
|
|
302
|
+
scrollbar-color: var(--_cross-browser-scrollbar--thumb-color) var(--_cross-browser-scrollbar--track-color);
|
|
303
|
+
scrollbar-width: thin;
|
|
304
|
+
}
|
|
275
305
|
}
|
|
276
306
|
.textarea__el::placeholder {
|
|
277
307
|
color: var(--_ta--placeholder-color);
|
|
278
308
|
}
|
|
279
309
|
.textarea__el:disabled {
|
|
280
310
|
cursor: default;
|
|
311
|
+
}
|
|
312
|
+
.textarea__emoji {
|
|
313
|
+
flex-shrink: 0;
|
|
314
|
+
margin-inline-end: var(--_ta--padding-inline);
|
|
281
315
|
}</style>
|