poe-svelte-ui-lib 1.60.0 → 1.61.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/README.md CHANGED
@@ -59,6 +59,8 @@ npm install poe-svelte-ui-lib
59
59
 
60
60
  **Названия смарт-виджетов** — в словаре библиотеки на всех языках (WiFi, «Об устройстве», «Файловая система», «Стек и задачи», «RGB лента», «Пилотажный дисплей», «Карта»); пустой `label.name` показывает название на языке пользователя, `widgetTitle(type)` отдаёт его сразу на всех языках `{ ru, en, zh }` — так конструктор заполняет заголовок нового виджета.
61
61
 
62
+ **Шапка смарт-виджета** (`WidgetHeader`): значок, заголовок и сворачивание слева, «?» в правом краю; правая часть (режимы, «Обновить» и т. п.) стоит в той же строке, а если не помещается — уходит второй строкой под заголовок и там переносится.
63
+
62
64
  **Подсказки смарт-виджетов** — `hints.ts`: у каждого виджета своя кнопка «?» в правом краю шапки (`WidgetHeader` с пропом `hints`), по умолчанию подсказки выключены, выбор оператора запоминается в браузере для виджетов этого типа (`hintsSetting("WidgetPFD")`, ключ `localStorage` `WidgetHints.<тип>`, пишется только по нажатию «?»), глобального переключателя нет. Элемент получает подсказку действием `use:hint={{ text, enabled: $hints }}` — всплывающее окно в стиле темы над элементом; тексты — в словаре библиотеки (`widget.*.hint.*`), только там, где смысл поля не очевиден.
63
65
 
64
66
  **Предпросмотр темы** — вкладка «Тема» на главной витрины (`src/routes/ThemePreview.svelte`): палитра токенов и состояния, затем все компоненты и виджеты в порядке меню витрины — каждый тип в своём разделе с живыми демо-данными (графики, видео, полёт для PFD и карты), в конце типографика и Markdown; тема переключается кнопкой в шапке витрины. Правьте `theme.css` и смотрите результат там.
@@ -27,42 +27,57 @@
27
27
  } = $props()
28
28
 
29
29
  const Icon = $derived(icon)
30
+
31
+ /* Правая часть уходит второй строкой, если не помещается рядом с заголовком (место под значок, заголовок и «?») */
32
+ const TITLE_MIN_PX = 180
33
+ let headerWidth = $state(0)
34
+ let rightWidth = $state(0)
35
+ let wrapped = $derived(!!right && headerWidth > 0 && rightWidth + TITLE_MIN_PX + (hints ? 34 : 0) > headerWidth)
30
36
  </script>
31
37
 
32
- <!-- Фиксированная высота 32 px без переноса — свёрнутые виджеты одной высоты при любом содержимом справа; «?» — в правом краю, после содержимого шапки -->
33
- <div class="flex h-[32px] items-center justify-between gap-3">
34
- <button
35
- type="button"
36
- class="flex min-w-0 flex-1 cursor-pointer items-center gap-2 border-none bg-transparent p-0 text-left"
37
- onclick={() => (collapsed = !collapsed)}
38
- aria-expanded={!collapsed}
39
- >
40
- <span class="flex h-[18px] w-[18px] shrink-0 items-center justify-center text-(--accent-color) [&_svg]:h-full [&_svg]:w-full">
41
- <Icon />
42
- </span>
43
- <span class="min-w-0 truncate text-[14px] font-semibold">{label}</span>
44
- <span
45
- class="flex h-[14px] w-[14px] shrink-0 items-center justify-center text-(--faint-color) transition-transform duration-150 [&_svg]:h-full [&_svg]:w-full"
46
- style="transform: rotate({collapsed ? 0 : 90}deg)"
47
- >
48
- <ArrowIcon />
49
- </span>
50
- </button>
51
- {#if right}
52
- <div class="flex min-w-0 shrink-0 items-center justify-end">
53
- {@render right()}
54
- </div>
55
- {/if}
56
- {#if hints}
38
+ <!-- Первая строка фиксированной высоты 32 px — свёрнутые виджеты одной высоты; «?» — в правом краю.
39
+ Правая часть стоит в первой строке, а если не помещается — второй строкой под заголовком (выравнивание вправо) -->
40
+ <div class="flex flex-col gap-2" bind:clientWidth={headerWidth}>
41
+ <div class="flex h-[32px] items-center justify-between gap-3">
57
42
  <button
58
43
  type="button"
59
- class="flex size-[22px] shrink-0 cursor-pointer items-center justify-center rounded-full border text-[12px] font-bold transition-colors duration-150
60
- {$hints
61
- ? 'border-(--accent-color) bg-(--accent-soft) text-(--accent-color)'
62
- : 'border-(--hairline-color) bg-transparent text-(--faint-color) hover:text-(--muted-color)'}"
63
- title={$hints ? $T("widget.hints.on") : $T("widget.hints.off")}
64
- aria-pressed={$hints}
65
- onclick={() => hints.update((on) => !on)}>?</button
44
+ class="flex min-w-0 flex-1 cursor-pointer items-center gap-2 border-none bg-transparent p-0 text-left"
45
+ onclick={() => (collapsed = !collapsed)}
46
+ aria-expanded={!collapsed}
66
47
  >
48
+ <span class="flex h-[18px] w-[18px] shrink-0 items-center justify-center text-(--accent-color) [&_svg]:h-full [&_svg]:w-full">
49
+ <Icon />
50
+ </span>
51
+ <span class="min-w-0 truncate text-[14px] font-semibold">{label}</span>
52
+ <span
53
+ class="flex h-[14px] w-[14px] shrink-0 items-center justify-center text-(--faint-color) transition-transform duration-150 [&_svg]:h-full [&_svg]:w-full"
54
+ style="transform: rotate({collapsed ? 0 : 90}deg)"
55
+ >
56
+ <ArrowIcon />
57
+ </span>
58
+ </button>
59
+ {#if right && !wrapped}
60
+ <div class="flex w-max shrink-0 items-center justify-end" bind:clientWidth={rightWidth}>
61
+ {@render right()}
62
+ </div>
63
+ {/if}
64
+ {#if hints}
65
+ <button
66
+ type="button"
67
+ class="flex size-[22px] shrink-0 cursor-pointer items-center justify-center rounded-full border text-[12px] font-bold transition-colors duration-150
68
+ {$hints
69
+ ? 'border-(--accent-color) bg-(--accent-soft) text-(--accent-color)'
70
+ : 'border-(--hairline-color) bg-transparent text-(--faint-color) hover:text-(--muted-color)'}"
71
+ title={$hints ? $T("widget.hints.on") : $T("widget.hints.off")}
72
+ aria-pressed={$hints}
73
+ onclick={() => hints.update((on) => !on)}>?</button
74
+ >
75
+ {/if}
76
+ </div>
77
+ {#if right && wrapped}
78
+ <!-- Во второй строке элементы могут переноситься; естественная ширина правой части — из первой строки -->
79
+ <div class="flex max-w-full flex-wrap items-center justify-end gap-2">
80
+ {@render right()}
81
+ </div>
67
82
  {/if}
68
83
  </div>
@@ -129,7 +129,7 @@
129
129
  <!-- Заголовок -->
130
130
  <WidgetHeader icon={MemoryIcon} label={label?.name || $T("widget.stack.title")} bind:collapsed {hints}>
131
131
  {#snippet right()}
132
- <div class="flex items-center gap-2" use:hint={{ text: $T("widget.stack.hint.poll"), enabled: $hints }}>
132
+ <div class="flex flex-wrap items-center justify-end gap-2" use:hint={{ text: $T("widget.stack.hint.poll"), enabled: $hints }}>
133
133
  <UI.Select
134
134
  wrapperClass="w-64"
135
135
  type="buttons"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "poe-svelte-ui-lib",
3
- "version": "1.60.0",
3
+ "version": "1.61.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/Oleg-Perevyshin/ElementsUI.git"