@sveltia/ui 0.69.0 → 0.69.1

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.
@@ -32,6 +32,7 @@
32
32
  pressed = undefined,
33
33
  keyShortcuts = undefined,
34
34
  label = '',
35
+ labelDir = undefined,
35
36
  lines = 1,
36
37
  variant = undefined,
37
38
  size = 'medium',
@@ -80,7 +81,7 @@
80
81
  {@render startIcon?.()}
81
82
  {#if variant === 'link'}
82
83
  {#if label}
83
- <span role="none" class="label">
84
+ <span role="none" class="label" dir={labelDir}>
84
85
  <TruncatedText {lines}>
85
86
  {label}
86
87
  </TruncatedText>
@@ -92,7 +93,7 @@
92
93
  {/if}
93
94
  {:else}
94
95
  {#if label}
95
- <span role="none" class="label">
96
+ <span role="none" class="label" dir={labelDir}>
96
97
  <TruncatedText {lines}>
97
98
  {label}
98
99
  </TruncatedText>
@@ -10,7 +10,7 @@
10
10
  @see https://developer.mozilla.org/en-US/docs/Web/API/Popover_API
11
11
  -->
12
12
  <script>
13
- import { _ } from '@sveltia/i18n';
13
+ import { _, isRTL } from '@sveltia/i18n';
14
14
  import { onMount, untrack } from 'svelte';
15
15
  import { searchEmojis } from './emoji.js';
16
16
 
@@ -126,7 +126,7 @@
126
126
  const spaceBelow = innerHeight - anchorRect.bottom;
127
127
  const spaceAbove = anchorRect.top;
128
128
  const flipped = spaceBelow < listMaxHeight + VIEWPORT_MARGIN && spaceAbove > spaceBelow;
129
- const rtl = document.dir === 'rtl';
129
+ const rtl = isRTL();
130
130
  const anchorLeft = rtl ? anchorRect.right - LIST_WIDTH : anchorRect.left;
131
131
 
132
132
  return {
@@ -35,6 +35,7 @@
35
35
  hidden = false,
36
36
  disabled = false,
37
37
  label = '',
38
+ labelDir = undefined,
38
39
  popupPosition = 'right-top', // @todo Make this auto detect
39
40
  children: _children,
40
41
  startIcon: _startIcon,
@@ -118,7 +119,7 @@
118
119
  {/snippet}
119
120
  <!-- eslint-disable-next-line svelte/no-useless-children-snippet -->
120
121
  {#snippet children()}
121
- <div role="none" class="content" class:label={!!label}>
122
+ <div role="none" class="content" class:label={!!label} dir={label ? labelDir : undefined}>
122
123
  {#if label}
123
124
  {label}
124
125
  {:else}
@@ -473,6 +473,7 @@
473
473
  }
474
474
  .combobox-inner :global(.sui.search-bar) {
475
475
  flex: none;
476
+ margin-bottom: calc(8px - var(--sui-focus-ring-width));
476
477
  }
477
478
  .combobox-inner :global(.sui.listbox) {
478
479
  flex: auto;
@@ -301,7 +301,7 @@
301
301
  position: absolute;
302
302
  top: 0;
303
303
  bottom: 0;
304
- margin-left: -1px;
304
+ margin-inline-start: -1px;
305
305
  border-radius: 1px;
306
306
  width: 4px;
307
307
  background-color: var(--sui-primary-accent-color);
@@ -4,10 +4,6 @@
4
4
  * guaranteed to be compatible with the matching engine.
5
5
  */
6
6
  export const SHIKI_VERSION: "4.4.3";
7
- /**
8
- * Version of this package, used to resolve the prebuilt Shiki engine chunk from a CDN.
9
- */
10
- export const UI_VERSION: "0.69.0";
11
7
  /**
12
8
  * Available syntax highlighting languages, sorted by display name.
13
9
  * @type {{ id: string, name: string, aliases?: string[] }[]}
@@ -7,11 +7,6 @@
7
7
  */
8
8
  export const SHIKI_VERSION = "4.4.3";
9
9
 
10
- /**
11
- * Version of this package, used to resolve the prebuilt Shiki engine chunk from a CDN.
12
- */
13
- export const UI_VERSION = "0.69.0";
14
-
15
10
  /**
16
11
  * Available syntax highlighting languages, sorted by display name.
17
12
  * @type {{ id: string, name: string, aliases?: string[] }[]}
@@ -1,4 +1,5 @@
1
- import { SHIKI_VERSION, UI_VERSION } from './generated.js';
1
+ import { SHIKI_VERSION } from './generated.js';
2
+ import { UI_VERSION } from './version.js';
2
3
 
3
4
  /**
4
5
  * @import { CodeHighlighterLoaders } from '../../../typedefs';
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Version of this package, used to resolve the prebuilt Shiki engine chunk from a CDN.
3
+ */
4
+ export const UI_VERSION: "0.69.1";
@@ -0,0 +1,6 @@
1
+ // Generated by `scripts/generate-shiki-metadata.js`. DO NOT EDIT.
2
+
3
+ /**
4
+ * Version of this package, used to resolve the prebuilt Shiki engine chunk from a CDN.
5
+ */
6
+ export const UI_VERSION = '0.69.1';
@@ -1,3 +1,4 @@
1
+ import { isRTL } from '@sveltia/i18n';
1
2
  import { generateElementId } from '@sveltia/utils/element';
2
3
  import { sleep } from '@sveltia/utils/misc';
3
4
  import { on } from 'svelte/events';
@@ -305,7 +306,23 @@ class Popup {
305
306
  intersectionRect.width = Math.max(0, intersectionRect.right - intersectionRect.left);
306
307
  intersectionRect.height = Math.max(0, intersectionRect.bottom - intersectionRect.top);
307
308
 
309
+ // Measure the content at its natural size, with any limit previously applied here taken off
310
+ // first. A popup that delegates its scrolling to a child — the combobox hands it to the option
311
+ // list, so the filter stays put — reports a `scrollHeight` no larger than the `max-height` it’s
312
+ // already capped at, and the same goes for `scrollWidth` against `max-width`. Measuring those
313
+ // clipped values would make the cap stick: once the popup had shrunk to fit a small viewport,
314
+ // it could never grow back when the viewport did. The properties are put back synchronously,
315
+ // before the browser can paint, so nothing flickers.
316
+ const { maxHeight: appliedMaxHeight, maxWidth: appliedMaxWidth } = content.style;
317
+
318
+ content.style.maxHeight = '';
319
+ content.style.maxWidth = '';
320
+
308
321
  const { scrollHeight: contentHeight, scrollWidth: contentWidth } = content;
322
+
323
+ content.style.maxHeight = appliedMaxHeight;
324
+ content.style.maxWidth = appliedMaxWidth;
325
+
309
326
  const topMargin = intersectionRect.top - 8;
310
327
  const bottomMargin = rootBounds.height - intersectionRect.bottom - 8;
311
328
  let { position } = this;
@@ -313,7 +330,7 @@ class Popup {
313
330
 
314
331
  // Normalize RTL-friendly positions to LTR for LTR documents
315
332
  // @todo Rename `PopupPosition` enums to be direction-agnostic
316
- if (document.dir === 'rtl') {
333
+ if (isRTL()) {
317
334
  if (position.endsWith('-left')) {
318
335
  position = /** @type {PopupPosition} */ (position.replace('-left', '-right'));
319
336
  } else if (position.endsWith('-right')) {
@@ -384,7 +401,10 @@ class Popup {
384
401
  maxWidth: position.endsWith('-left')
385
402
  ? `${Math.round(rootBounds.width - intersectionRect.left - 8)}px`
386
403
  : `${Math.round(intersectionRect.right - 8)}px`,
387
- height: height ? `${Math.round(height)}px` : 'auto',
404
+ // `undefined` removes the `max-height` the popup is given, letting it take its natural size
405
+ // again. `auto` would look equivalent but isn’t a valid `max-height`, so the browser would
406
+ // drop it and leave whatever limit was applied last in place.
407
+ height: height ? `${Math.round(height)}px` : undefined,
388
408
  };
389
409
 
390
410
  if (
@@ -58,6 +58,12 @@ export type ButtonProps = {
58
58
  * Text label displayed on the button.
59
59
  */
60
60
  label?: string | undefined;
61
+ /**
62
+ * The `dir` attribute on the label element.
63
+ * Use `auto` to isolate a user-authored label whose text direction is unknown, so it cannot
64
+ * be reordered by the surrounding UI direction.
65
+ */
66
+ labelDir?: "ltr" | "rtl" | "auto" | undefined;
61
67
  /**
62
68
  * Number of lines to show the label. Overflowing text will be truncated.
63
69
  */
@@ -331,6 +337,12 @@ export type MenuItemProps = {
331
337
  * Text label displayed on the item.
332
338
  */
333
339
  label?: string | undefined;
340
+ /**
341
+ * The `dir` attribute on the label element.
342
+ * Use `auto` to isolate a user-authored label whose text direction is unknown, so it cannot
343
+ * be reordered by the surrounding UI direction.
344
+ */
345
+ labelDir?: "ltr" | "rtl" | "auto" | undefined;
334
346
  /**
335
347
  * Primary slot content.
336
348
  */
package/dist/typedefs.js CHANGED
@@ -26,6 +26,9 @@
26
26
  * attribute. Accepts the special `Accel` key, which will be replaced with `Control` or `Meta`
27
27
  * depending on the user’s operating system.
28
28
  * @property {string} [label] Text label displayed on the button.
29
+ * @property {'ltr' | 'rtl' | 'auto'} [labelDir] The `dir` attribute on the label element.
30
+ * Use `auto` to isolate a user-authored label whose text direction is unknown, so it cannot
31
+ * be reordered by the surrounding UI direction.
29
32
  * @property {number} [lines] Number of lines to show the label. Overflowing text will be truncated.
30
33
  * @property {'primary' | 'secondary' | 'tertiary' | 'ghost' | 'link'} [variant] The style variant
31
34
  * of the button.
@@ -119,6 +122,9 @@
119
122
  * @property {boolean} [checked] Whether to check the widget. An alias of the `aria-checked`
120
123
  * attribute.
121
124
  * @property {string} [label] Text label displayed on the item.
125
+ * @property {'ltr' | 'rtl' | 'auto'} [labelDir] The `dir` attribute on the label element.
126
+ * Use `auto` to isolate a user-authored label whose text direction is unknown, so it cannot
127
+ * be reordered by the surrounding UI direction.
122
128
  * @property {Snippet} [children] Primary slot content.
123
129
  * @property {Snippet} [startIcon] Start icon slot content.
124
130
  * @property {Snippet} [endIcon] End icon slot content.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sveltia/ui",
3
- "version": "0.69.0",
3
+ "version": "0.69.1",
4
4
  "description": "A collection of Svelte components and utilities for building user interfaces.",
5
5
  "repository": {
6
6
  "type": "git",