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` и смотрите результат там.
|
package/dist/WidgetHeader.svelte
CHANGED
|
@@ -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
|
-
<!--
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
|
60
|
-
|
|
61
|
-
|
|
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"
|