@noroproject/module-ui 1.0.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 +47 -0
- package/index.d.ts +211 -0
- package/index.js +13 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# @noroproject/module-ui
|
|
2
|
+
|
|
3
|
+
Компоненты панели Noro для мини-аппов модулей — объявления типов.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
bun add -d @noroproject/module-ui
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
В рантайме пакета нет: он помечается external, и импорты становятся
|
|
10
|
+
обращениями к глобалям панели. Благодаря этому модуль получает **ту же** копию
|
|
11
|
+
Vue, что и панель, а его бандл весит килобайты.
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
// vite.config.mjs
|
|
15
|
+
export default defineConfig({
|
|
16
|
+
plugins: [vue()],
|
|
17
|
+
build: {
|
|
18
|
+
lib: { entry: 'ui/app.js', formats: ['iife'], name: '__noroModuleExport' },
|
|
19
|
+
rollupOptions: {
|
|
20
|
+
external: ['vue', '@noroproject/module-ui'],
|
|
21
|
+
output: { globals: { vue: '__noroVue', '@noroproject/module-ui': '__noroUi' } },
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
})
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```vue
|
|
28
|
+
<script setup lang="ts">
|
|
29
|
+
import { AtomBadge, NoroCard, useNoro } from '@noroproject/module-ui'
|
|
30
|
+
|
|
31
|
+
const noro = useNoro()
|
|
32
|
+
const points = await noro.api<number>('/points')
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<template>
|
|
36
|
+
<NoroCard icon="i-lucide-gift" :title="noro.t('mod-shop-title')">
|
|
37
|
+
<AtomBadge tone="success">{{ points }}</AtomBadge>
|
|
38
|
+
</NoroCard>
|
|
39
|
+
</template>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Перечисленные здесь компоненты и пропсы — публичный контракт панели: он может
|
|
43
|
+
пополняться, но то, что уже есть, не переименовывается. Панель сверяет их со
|
|
44
|
+
своими настоящими компонентами при проверке типов, так что обещание не может
|
|
45
|
+
разойтись с реальностью незаметно.
|
|
46
|
+
|
|
47
|
+
Как написать модуль целиком — в [README репозитория](https://github.com/NoroProject/noro-shared#writing-a-module).
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Компоненты панели Noro для мини-аппов модулей.
|
|
3
|
+
*
|
|
4
|
+
* Пакет состоит из одних объявлений: в рантайме его нет, а импорты при сборке
|
|
5
|
+
* превращаются в обращения к `window.__noroUi`, куда панель кладёт свои
|
|
6
|
+
* компоненты. Отсюда два следствия — автор получает автодополнение и типы, а
|
|
7
|
+
* бандл модуля не тащит ни Vue, ни вёрстку панели и весит килобайты.
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { NoroCard, AtomButton, useNoro } from '@noro/module-ui'
|
|
11
|
+
*
|
|
12
|
+
* const noro = useNoro()
|
|
13
|
+
* const me = await noro.api('/me')
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* Всё перечисленное здесь — публичный контракт панели. Он может пополняться, но
|
|
17
|
+
* то, что уже есть, не переименовывается: собранные модули этого не переживут.
|
|
18
|
+
*/
|
|
19
|
+
import type { DefineComponent } from 'vue'
|
|
20
|
+
|
|
21
|
+
/** Оттенок, общий для бейджей и кнопок. */
|
|
22
|
+
export type Tone = 'neutral' | 'blue' | 'cream' | 'amber' | 'danger' | 'success' | 'outline'
|
|
23
|
+
|
|
24
|
+
export type Size = 'sm' | 'md' | 'lg'
|
|
25
|
+
|
|
26
|
+
/** Некликабельная метка: состояние, число, версия. */
|
|
27
|
+
export interface AtomBadgeProps {
|
|
28
|
+
tone?: Tone
|
|
29
|
+
/** Моноширинный шрифт — для идентификаторов и версий. */
|
|
30
|
+
mono?: boolean
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export declare const AtomBadge: DefineComponent<AtomBadgeProps>
|
|
34
|
+
|
|
35
|
+
export interface AtomButtonProps {
|
|
36
|
+
variant?:
|
|
37
|
+
| 'primary'
|
|
38
|
+
| 'secondary'
|
|
39
|
+
| 'dark'
|
|
40
|
+
| 'warning'
|
|
41
|
+
| 'danger'
|
|
42
|
+
| 'danger-soft'
|
|
43
|
+
| 'outline'
|
|
44
|
+
| 'outline-blue'
|
|
45
|
+
| 'ghost'
|
|
46
|
+
size?: Size
|
|
47
|
+
/** Имя иконки `i-lucide-*`. */
|
|
48
|
+
icon?: string
|
|
49
|
+
iconRight?: string
|
|
50
|
+
loading?: boolean
|
|
51
|
+
disabled?: boolean
|
|
52
|
+
/** Растянуть на всю ширину. */
|
|
53
|
+
block?: boolean
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export declare const AtomButton: DefineComponent<AtomButtonProps>
|
|
57
|
+
|
|
58
|
+
export interface AtomCheckboxProps {
|
|
59
|
+
modelValue?: boolean | unknown[]
|
|
60
|
+
label?: string
|
|
61
|
+
hint?: string
|
|
62
|
+
value?: string | number
|
|
63
|
+
disabled?: boolean
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export declare const AtomCheckbox: DefineComponent<AtomCheckboxProps>
|
|
67
|
+
|
|
68
|
+
/** Переключатель в ряду: фильтр, набор значений. */
|
|
69
|
+
export interface AtomChipProps {
|
|
70
|
+
active?: boolean
|
|
71
|
+
disabled?: boolean
|
|
72
|
+
size?: 'sm' | 'md'
|
|
73
|
+
/** Заглавными буквами. */
|
|
74
|
+
caps?: boolean
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export declare const AtomChip: DefineComponent<AtomChipProps>
|
|
78
|
+
|
|
79
|
+
export interface AtomInputProps {
|
|
80
|
+
modelValue?: string | number
|
|
81
|
+
label?: string
|
|
82
|
+
placeholder?: string
|
|
83
|
+
type?: string
|
|
84
|
+
hint?: string
|
|
85
|
+
error?: string
|
|
86
|
+
disabled?: boolean
|
|
87
|
+
readonly?: boolean
|
|
88
|
+
/** Многострочное поле вместо однострочного. */
|
|
89
|
+
textarea?: boolean
|
|
90
|
+
rows?: number
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export declare const AtomInput: DefineComponent<AtomInputProps>
|
|
94
|
+
|
|
95
|
+
export interface AtomModalProps {
|
|
96
|
+
modelValue: boolean
|
|
97
|
+
title?: string
|
|
98
|
+
subtitle?: string
|
|
99
|
+
size?: 'md' | 'lg' | 'xl' | 'full'
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export declare const AtomModal: DefineComponent<AtomModalProps>
|
|
103
|
+
|
|
104
|
+
export interface AtomNumberInputProps {
|
|
105
|
+
modelValue?: number
|
|
106
|
+
label?: string
|
|
107
|
+
hint?: string
|
|
108
|
+
min?: number
|
|
109
|
+
max?: number
|
|
110
|
+
step?: number
|
|
111
|
+
disabled?: boolean
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export declare const AtomNumberInput: DefineComponent<AtomNumberInputProps>
|
|
115
|
+
|
|
116
|
+
/** Ряд взаимоисключающих значений — вместо выпадающего списка на два пункта. */
|
|
117
|
+
export interface AtomSegmentedProps {
|
|
118
|
+
modelValue?: string | number
|
|
119
|
+
options: { label: string; value: string | number; count?: number; icon?: string }[]
|
|
120
|
+
size?: Size
|
|
121
|
+
block?: boolean
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export declare const AtomSegmented: DefineComponent<AtomSegmentedProps>
|
|
125
|
+
|
|
126
|
+
export interface AtomSelectMenuProps {
|
|
127
|
+
modelValue?: string | number
|
|
128
|
+
options: { label: string; value: string | number; disabled?: boolean; group?: string }[]
|
|
129
|
+
placeholder?: string
|
|
130
|
+
disabled?: boolean
|
|
131
|
+
size?: 'sm' | 'md'
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export declare const AtomSelectMenu: DefineComponent<AtomSelectMenuProps>
|
|
135
|
+
|
|
136
|
+
export interface AtomToggleProps {
|
|
137
|
+
modelValue: boolean
|
|
138
|
+
label?: string
|
|
139
|
+
disabled?: boolean
|
|
140
|
+
loading?: boolean
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export declare const AtomToggle: DefineComponent<AtomToggleProps>
|
|
144
|
+
|
|
145
|
+
/** Заглушка для пустого списка. `bare` — без своей рамки, внутри карточки. */
|
|
146
|
+
export interface EmptyStateProps {
|
|
147
|
+
icon?: string
|
|
148
|
+
title: string
|
|
149
|
+
text?: string
|
|
150
|
+
bare?: boolean
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export declare const EmptyState: DefineComponent<EmptyStateProps>
|
|
154
|
+
|
|
155
|
+
/** Карточка-раздел. Иконка обязательна, справа — слот `actions`. */
|
|
156
|
+
export interface NoroCardProps {
|
|
157
|
+
title: string
|
|
158
|
+
/** Имя иконки `i-lucide-*`. */
|
|
159
|
+
icon: string
|
|
160
|
+
subtitle?: string
|
|
161
|
+
/** Без внутренних отступов — для таблиц во всю ширину. */
|
|
162
|
+
flush?: boolean
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export declare const NoroCard: DefineComponent<NoroCardProps>
|
|
166
|
+
|
|
167
|
+
/** Кто открыл мини-апп. */
|
|
168
|
+
export interface NoroUser {
|
|
169
|
+
id: string
|
|
170
|
+
username?: string | null
|
|
171
|
+
mc_username?: string | null
|
|
172
|
+
[key: string]: unknown
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** То, что панель даёт мини-аппу. */
|
|
176
|
+
export interface NoroContext {
|
|
177
|
+
/**
|
|
178
|
+
* Вызов ручки своего модуля.
|
|
179
|
+
*
|
|
180
|
+
* Путь — тот, что объявлен в `#[route]`. Чужие модули недоступны: адрес
|
|
181
|
+
* собирает панель.
|
|
182
|
+
*
|
|
183
|
+
* ```ts
|
|
184
|
+
* const me = await noro.api<Points>('/me')
|
|
185
|
+
* await noro.api('/buy', { method: 'POST', body: { id } })
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
api<T = unknown>(path: string, options?: { method?: string; body?: unknown }): Promise<T>
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Перевод по ключу каталога.
|
|
192
|
+
*
|
|
193
|
+
* Ключи модуля начинаются с `mod-<id>-` и живут в `locales/*.ftl` пакета.
|
|
194
|
+
* Второй аргумент — что показать, пока строки нет.
|
|
195
|
+
*/
|
|
196
|
+
t(key: string, fallback?: string): string
|
|
197
|
+
|
|
198
|
+
/** Кто открыл страницу. `null` у неавторизованного. */
|
|
199
|
+
user: NoroUser | null
|
|
200
|
+
|
|
201
|
+
/** Уведомления панели. */
|
|
202
|
+
notify: { ok(text?: string): void; fail(error: unknown): void }
|
|
203
|
+
|
|
204
|
+
/** Переход по панели: `noro.navigate('/cabinet')`. */
|
|
205
|
+
navigate(path: string): void
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Контекст мини-аппа. Зовётся в `setup`, как обычный composable Vue.
|
|
210
|
+
*/
|
|
211
|
+
export declare function useNoro(): NoroContext
|
package/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Пустышка нужна только сборщику.
|
|
3
|
+
*
|
|
4
|
+
* В рантайме этот пакет не существует: он помечен external, и его импорты
|
|
5
|
+
* превращаются в обращения к `window.__noroUi`, куда панель складывает свои
|
|
6
|
+
* компоненты. Настоящее содержимое пакета — index.d.ts с типами.
|
|
7
|
+
*
|
|
8
|
+
* Если файл всё же попал в бандл, значит external не настроен, и лучше узнать
|
|
9
|
+
* об этом сразу, а не по пустому экрану.
|
|
10
|
+
*/
|
|
11
|
+
throw new Error(
|
|
12
|
+
'@noro/module-ui должен быть external в сборке мини-аппа: проверьте vite.config',
|
|
13
|
+
)
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@noroproject/module-ui",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Типы и компоненты панели Noro для мини-аппов модулей",
|
|
5
|
+
"license": "AGPL-3.0-only",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"types": "index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"index.d.ts",
|
|
10
|
+
"index.js",
|
|
11
|
+
"README.md"
|
|
12
|
+
],
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./index.d.ts",
|
|
16
|
+
"default": "./index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"vue": "^3.5.0"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/NoroProject/noro-shared.git",
|
|
25
|
+
"directory": "packages/module-ui"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/NoroProject/noro-shared#writing-a-module",
|
|
28
|
+
"keywords": [
|
|
29
|
+
"noro",
|
|
30
|
+
"minecraft",
|
|
31
|
+
"launcher",
|
|
32
|
+
"plugin",
|
|
33
|
+
"module"
|
|
34
|
+
],
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
}
|
|
38
|
+
}
|