@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.
Files changed (4) hide show
  1. package/README.md +47 -0
  2. package/index.d.ts +211 -0
  3. package/index.js +13 -0
  4. 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
+ }