@nitra/cursor 12.8.5 → 12.8.7
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/CHANGELOG.md +12 -0
- package/bin/n-cursor.js +5 -5
- package/package.json +1 -1
- package/rules/abie/js/http_route_base.mdc +25 -0
- package/rules/abie/js/ua_http_route.mdc +1 -1
- package/rules/abie/main.mdc +12 -0
- package/rules/adr/js/hooks.mdc +32 -0
- package/rules/adr/js/madr_format.mdc +96 -0
- package/rules/adr/js/settings_policy.mdc +34 -0
- package/rules/adr/main.mdc +13 -95
- package/rules/bun/js/bunfig.mdc +12 -0
- package/rules/bun/js/layout.mdc +60 -0
- package/rules/bun/js/lint.mdc +9 -0
- package/rules/bun/js/package_json.mdc +19 -0
- package/rules/bun/main.mdc +9 -61
- package/rules/capacitor/js/ios_spm.mdc +69 -0
- package/rules/capacitor/js/version.mdc +29 -0
- package/rules/capacitor/main.mdc +8 -22
- package/rules/changelog/js/agent-workflow.mdc +15 -0
- package/rules/changelog/js/changelog-format.mdc +33 -0
- package/rules/changelog/js/comparison-models.mdc +40 -0
- package/rules/changelog/main.mdc +4 -98
- package/rules/ci4/js/marksman_config.mdc +31 -0
- package/rules/ci4/js/vscode_extensions.mdc +33 -0
- package/rules/ci4/main.mdc +14 -14
- package/rules/docker/js/compile.mdc +44 -0
- package/rules/docker/js/hadolint.mdc +50 -0
- package/rules/docker/js/mirror.mdc +13 -0
- package/rules/docker/js/multistage.mdc +13 -0
- package/rules/docker/js/native-addon.mdc +43 -0
- package/rules/docker/js/nginx-tag.mdc +7 -0
- package/rules/docker/js/nginx-user.mdc +37 -0
- package/rules/docker/js/non-root.mdc +39 -0
- package/rules/docker/main.mdc +15 -196
- package/rules/ga/js/lint_toolchain.mdc +15 -0
- package/rules/ga/js/required_workflows.mdc +35 -0
- package/rules/ga/js/vscode.mdc +17 -0
- package/rules/ga/js/workflow_common.mdc +108 -0
- package/rules/ga/js/workflows.mdc +32 -0
- package/rules/ga/js/zizmor.mdc +7 -0
- package/rules/ga/main.mdc +17 -125
- package/rules/graphql/js/tooling.mdc +13 -0
- package/rules/graphql/js/vscode_extensions.mdc +13 -0
- package/rules/graphql/main.mdc +3 -22
- package/rules/hasura/js/internal_urls.mdc +27 -0
- package/rules/hasura/js/migrations.mdc +13 -0
- package/rules/hasura/js/svc_hl.mdc +17 -0
- package/rules/hasura/main.mdc +8 -30
- package/rules/image-avif/js/avif_generation.mdc +26 -0
- package/rules/image-avif/js/package_json_optout.mdc +21 -0
- package/rules/image-avif/main.mdc +7 -34
- package/rules/image-compress/js/package_json.mdc +7 -0
- package/rules/image-compress/js/package_setup.mdc +13 -0
- package/rules/image-compress/main.mdc +4 -12
- package/rules/js/docs/index.md +3 -3
- package/rules/js/js/dep-policy.mdc +17 -0
- package/rules/js/js/eslint-config.mdc +28 -0
- package/rules/js/js/extensions.mdc +8 -0
- package/rules/js/js/file-extensions.mdc +12 -0
- package/rules/js/js/for-in.mdc +26 -0
- package/rules/js/js/jscpd.mdc +42 -0
- package/rules/js/js/knip.mdc +15 -0
- package/rules/js/js/lint-js-workflow.mdc +58 -0
- package/rules/js/js/oxlintrc.mdc +20 -0
- package/rules/js/js/package-json.mdc +31 -0
- package/rules/js/js/tests.mdc +9 -0
- package/rules/js/js/utils-lib-structure.mdc +15 -0
- package/rules/js/main.mdc +21 -214
- package/rules/js-bun-db/js/bun-sql-migration.mdc +15 -0
- package/rules/js-bun-db/js/connection.mdc +42 -0
- package/rules/js-bun-db/js/pg-format-identifiers.mdc +102 -0
- package/rules/js-bun-db/js/pg-format-shim.mdc +99 -0
- package/rules/js-bun-db/js/pg-leftover.mdc +27 -0
- package/rules/js-bun-db/js/pg-listen-notify.mdc +51 -0
- package/rules/js-bun-db/js/query-safety.mdc +117 -0
- package/rules/js-bun-db/js/sql-array.mdc +88 -0
- package/rules/js-bun-db/js/unsafe.mdc +65 -0
- package/rules/js-bun-db/main.mdc +15 -605
- package/rules/js-bun-redis/js/imports.mdc +47 -0
- package/rules/js-bun-redis/js/package_json.mdc +44 -0
- package/rules/js-bun-redis/main.mdc +3 -11
- package/rules/js-mssql/js/mssql-in-list.mdc +38 -0
- package/rules/js-mssql/js/mssql-pool.mdc +56 -0
- package/rules/js-mssql/js/mssql-query-template.mdc +33 -0
- package/rules/js-mssql/js/mssql-tvp.mdc +75 -0
- package/rules/js-mssql/js/mssql-version.mdc +7 -0
- package/rules/js-mssql/main.mdc +10 -198
- package/rules/js-run/js/check-env.mdc +35 -0
- package/rules/js-run/js/conn-aliases.mdc +109 -0
- package/rules/js-run/js/jsconfig.mdc +20 -0
- package/rules/js-run/js/otel-configmap.mdc +6 -0
- package/rules/js-run/js/pino.mdc +6 -0
- package/rules/js-run/js/project-structure.mdc +11 -0
- package/rules/js-run/js/runtime.mdc +14 -0
- package/rules/js-run/js/scope.mdc +11 -0
- package/rules/js-run/js/settimeout.mdc +11 -0
- package/rules/js-run/js/temporal.mdc +5 -0
- package/rules/js-run/main.mdc +16 -218
- package/rules/k8s/js/configmap.mdc +41 -0
- package/rules/k8s/js/deployment_resources.mdc +49 -0
- package/rules/k8s/js/hasura_httproute.mdc +91 -0
- package/rules/k8s/js/hpa_apiversion.mdc +27 -0
- package/rules/k8s/js/ingress_gateway.mdc +16 -0
- package/rules/k8s/js/kustomize_structure.mdc +144 -0
- package/rules/k8s/js/lint_k8s.mdc +72 -0
- package/rules/k8s/js/multidoc_yaml.mdc +5 -0
- package/rules/k8s/js/network_policy.mdc +136 -0
- package/rules/k8s/js/schema_modeline.mdc +57 -0
- package/rules/k8s/js/service.mdc +44 -0
- package/rules/k8s/js/topology_hpa_pdb.mdc +181 -0
- package/rules/k8s/main.mdc +30 -843
- package/rules/nginx-default-tpl/js/dockerfile.mdc +36 -0
- package/rules/nginx-default-tpl/js/http-route.mdc +41 -0
- package/rules/nginx-default-tpl/js/ini-keys.mdc +21 -0
- package/rules/nginx-default-tpl/js/template-structure.mdc +86 -0
- package/rules/nginx-default-tpl/js/vscode.mdc +37 -0
- package/rules/nginx-default-tpl/main.mdc +6 -112
- package/rules/npm-module/js/docs/index.md +5 -5
- package/rules/npm-module/js/docs/rule_meta.md +6 -6
- package/rules/npm-module/js/docs/skill_meta.md +8 -8
- package/rules/npm-module/js/header_doc_pointer.mdc +18 -0
- package/rules/npm-module/js/package_structure.mdc +62 -0
- package/rules/npm-module/js/rule_meta.mdc +11 -0
- package/rules/npm-module/js/skill_meta.mdc +11 -0
- package/rules/npm-module/main.mdc +10 -55
- package/rules/php/js/lint_php_yml.mdc +12 -0
- package/rules/php/js/tooling.mdc +66 -0
- package/rules/php/main.mdc +7 -66
- package/rules/python/js/lint_python_yml.mdc +23 -0
- package/rules/python/js/pyproject_toml.mdc +32 -0
- package/rules/python/js/tooling.mdc +23 -0
- package/rules/python/main.mdc +9 -33
- package/rules/rego/js/rego-lint.mdc +31 -0
- package/rules/rego/js/vscode_extensions.mdc +11 -0
- package/rules/rego/js/vscode_settings.mdc +13 -0
- package/rules/rego/main.mdc +8 -24
- package/rules/rust/js/coverage.mdc +28 -0
- package/rules/rust/js/lint.mdc +22 -0
- package/rules/rust/js/tauri_composition.mdc +8 -0
- package/rules/rust/js/vscode_extensions.mdc +12 -0
- package/rules/rust/main.mdc +8 -38
- package/rules/security/js/rego_policies.mdc +15 -0
- package/rules/security/js/sample_secret.mdc +19 -0
- package/rules/security/js/trufflehog.mdc +21 -0
- package/rules/security/main.mdc +7 -35
- package/rules/style/js/admin-table.mdc +88 -0
- package/rules/style/js/colors.mdc +21 -0
- package/rules/style/js/gap.mdc +22 -0
- package/rules/style/js/quasar-fixes.mdc +32 -0
- package/rules/style/js/quasar.mdc +7 -0
- package/rules/style/js/tooling.mdc +85 -0
- package/rules/style/main.mdc +13 -253
- package/rules/tauri/js/cargo_mutants_config.mdc +39 -0
- package/rules/tauri/js/tool_surface.mdc +21 -0
- package/rules/tauri/js/tooling.mdc +25 -0
- package/rules/tauri/main.mdc +8 -78
- package/rules/test/js/cargo_mutants_config.mdc +18 -0
- package/rules/test/js/docs/index.md +7 -7
- package/rules/test/js/location.mdc +52 -0
- package/rules/test/js/no-console-store-restore.mdc +11 -0
- package/rules/test/js/no-process-chdir.mdc +15 -0
- package/rules/test/js/no-relative-fs-path.mdc +22 -0
- package/rules/test/js/sandbox-aware-test.mdc +28 -0
- package/rules/test/js/stryker_config.mdc +26 -0
- package/rules/test/js/vitest-config-pool-forks.mdc +33 -0
- package/rules/test/main.mdc +18 -184
- package/rules/text/js/ci-lint-text.mdc +15 -0
- package/rules/text/js/cspell.mdc +81 -0
- package/rules/text/js/dotenv-linter.mdc +16 -0
- package/rules/text/js/forbidden-prettier.mdc +13 -0
- package/rules/text/js/markdownlint.mdc +25 -0
- package/rules/text/js/oxfmt.mdc +35 -0
- package/rules/text/js/package-json.mdc +26 -0
- package/rules/text/js/shellcheck.mdc +18 -0
- package/rules/text/js/v8r.mdc +23 -0
- package/rules/text/js/vscode.mdc +86 -0
- package/rules/text/main.mdc +20 -237
- package/rules/vue/js/composition-api.mdc +82 -0
- package/rules/vue/js/nheader-layout.mdc +171 -0
- package/rules/vue/js/node-imports.mdc +25 -0
- package/rules/vue/js/quasar-ui.mdc +32 -0
- package/rules/vue/js/structure.mdc +101 -0
- package/rules/vue/js/testing.mdc +32 -0
- package/rules/vue/js/tfm-translations.mdc +26 -0
- package/rules/vue/js/vite-config.mdc +126 -0
- package/rules/vue/js/vite-env.mdc +55 -0
- package/rules/vue/js/vue-imports.mdc +25 -0
- package/rules/vue/main.mdc +16 -640
- package/scripts/auto-rules.mjs +6 -6
- package/scripts/auto-skills.mjs +3 -3
- package/scripts/docs/auto-rules.md +17 -31
- package/scripts/docs/auto-skills.md +18 -163
- package/scripts/docs/index.md +16 -16
- package/scripts/lib/docs/index.md +36 -36
- package/scripts/lib/docs/mirror-parity.md +7 -7
- package/scripts/lib/docs/rule-meta.md +12 -12
- package/scripts/lib/docs/skill-meta.md +9 -9
- package/scripts/lib/docs/worktree-notice.md +10 -8
- package/scripts/lib/rule-meta.mjs +6 -6
- package/scripts/lib/skill-meta.mjs +6 -6
- package/scripts/lib/worktree-notice.mjs +2 -2
- package/scripts/utils/docs/index.md +14 -14
package/rules/text/main.mdc
CHANGED
|
@@ -4,253 +4,36 @@ alwaysApply: true
|
|
|
4
4
|
version: '1.30'
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Правило охоплює весь текстовий стек проєкту: форматування (oxfmt), перевірку правопису (cspell), shell-скрипти (shellcheck), `.env`-файли (dotenv-linter), Markdown (markdownlint-cli2), JSON/YAML/TOML-схеми (v8r) та CI-workflow.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
{
|
|
11
|
-
"recommendations": [
|
|
12
|
-
"dbaeumer.vscode-eslint",
|
|
13
|
-
"github.vscode-github-actions",
|
|
14
|
-
"oxc.oxc-vscode",
|
|
15
|
-
"DavidAnson.vscode-markdownlint",
|
|
16
|
-
"timonwong.shellcheck",
|
|
17
|
-
"redhat.vscode-yaml",
|
|
18
|
-
"irongeek.vscode-env"
|
|
19
|
-
]
|
|
20
|
-
}
|
|
21
|
-
```
|
|
9
|
+
[text-vscode](./js/vscode.mdc)
|
|
22
10
|
|
|
23
|
-
|
|
11
|
+
[text-oxfmt](./js/oxfmt.mdc)
|
|
24
12
|
|
|
25
|
-
|
|
26
|
-
{
|
|
27
|
-
"files.associations": {
|
|
28
|
-
"*.env.*": "env",
|
|
29
|
-
"*.env": "env"
|
|
30
|
-
},
|
|
31
|
-
"editor.formatOnSave": true,
|
|
32
|
-
"[css]": {
|
|
33
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
34
|
-
},
|
|
35
|
-
"[graphql]": {
|
|
36
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
37
|
-
},
|
|
38
|
-
"[handlebars]": {
|
|
39
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
40
|
-
},
|
|
41
|
-
"[html]": {
|
|
42
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
43
|
-
},
|
|
44
|
-
"[javascript]": {
|
|
45
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
46
|
-
},
|
|
47
|
-
"[json]": {
|
|
48
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
49
|
-
},
|
|
50
|
-
"[json5]": {
|
|
51
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
52
|
-
},
|
|
53
|
-
"[jsonc]": {
|
|
54
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
55
|
-
},
|
|
56
|
-
"[less]": {
|
|
57
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
58
|
-
},
|
|
59
|
-
"[markdown]": {
|
|
60
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
61
|
-
},
|
|
62
|
-
"[mdx]": {
|
|
63
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
64
|
-
},
|
|
65
|
-
"[scss]": {
|
|
66
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
67
|
-
},
|
|
68
|
-
"[toml]": {
|
|
69
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
70
|
-
},
|
|
71
|
-
"[typescript]": {
|
|
72
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
73
|
-
},
|
|
74
|
-
"[vue]": {
|
|
75
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
76
|
-
},
|
|
77
|
-
"[yaml]": {
|
|
78
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
79
|
-
},
|
|
80
|
-
"oxc.path.oxfmt": "/opt/homebrew/bin/oxfmt"
|
|
81
|
-
}
|
|
82
|
-
```
|
|
13
|
+
[text-forbidden-prettier](./js/forbidden-prettier.mdc)
|
|
83
14
|
|
|
84
|
-
|
|
15
|
+
[text-cspell](./js/cspell.mdc)
|
|
85
16
|
|
|
86
|
-
|
|
17
|
+
[text-markdownlint](./js/markdownlint.mdc)
|
|
87
18
|
|
|
88
|
-
|
|
89
|
-
{
|
|
90
|
-
"ignorePatterns": ["**/hasura/metadata/**", "**/schema.graphql", "**/auto-imports.d.ts"],
|
|
91
|
-
"arrowParens": "avoid",
|
|
92
|
-
"printWidth": 120,
|
|
93
|
-
"bracketSpacing": true,
|
|
94
|
-
"bracketSameLine": true,
|
|
95
|
-
"embeddedLanguageFormatting": "auto",
|
|
96
|
-
"endOfLine": "lf",
|
|
97
|
-
"htmlWhitespaceSensitivity": "css",
|
|
98
|
-
"insertPragma": false,
|
|
99
|
-
"jsxSingleQuote": true,
|
|
100
|
-
"proseWrap": "preserve",
|
|
101
|
-
"quoteProps": "as-needed",
|
|
102
|
-
"requirePragma": false,
|
|
103
|
-
"semi": false,
|
|
104
|
-
"singleQuote": true,
|
|
105
|
-
"tabWidth": 2,
|
|
106
|
-
"trailingComma": "none",
|
|
107
|
-
"useTabs": false,
|
|
108
|
-
"vueIndentScriptAndStyle": false
|
|
109
|
-
}
|
|
110
|
-
```
|
|
19
|
+
[text-shellcheck](./js/shellcheck.mdc)
|
|
111
20
|
|
|
112
|
-
|
|
21
|
+
[text-dotenv-linter](./js/dotenv-linter.mdc)
|
|
113
22
|
|
|
114
|
-
|
|
23
|
+
[text-v8r](./js/v8r.mdc)
|
|
115
24
|
|
|
116
|
-
|
|
25
|
+
[text-package-json](./js/package-json.mdc)
|
|
117
26
|
|
|
118
|
-
|
|
27
|
+
[text-ci-lint-text](./js/ci-lint-text.mdc)
|
|
119
28
|
|
|
120
|
-
|
|
29
|
+
## Швидкий gate через conftest
|
|
121
30
|
|
|
122
|
-
|
|
31
|
+
Rego-пакети, що перевіряються через conftest (auto-discovered за `target.json` поряд із `.rego`):
|
|
123
32
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
"@nitra/cspell-dict": "^2.1.0"
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
**v8r:** без обгортки — чотири виклики `(bunx v8r "<glob>" || [ $? -eq 98 ])` для **`**/*.json`**, **`**/*.yml`**, **`**/*.yaml`**, **`**/*.toml`** (за потреби окремо **json5**). Враховує `.gitignore`. Для **`**/*.json`** опційно додай **власний каталог схем** [`--catalogs`](https://chris48s.github.io/v8r/usage-examples/#using-a-custom-catlog) (наприклад `-c npm/schemas/v8r-catalog.json` у репозиторії пакета `@nitra/cursor` або `-c https://unpkg.com/@nitra/cursor/schemas/v8r-catalog.json`), щоб перевіряти **`.n-cursor.json`** за схемою з [unpkg](https://unpkg.com/@nitra/cursor/schemas/n-cursor.json).
|
|
137
|
-
|
|
138
|
-
У корені проєкту має бути **`.v8rignore`**: **v8r** шукає схему в [Schema Store](https://www.schemastore.org/); для JSON без запису там перевірка завершується помилкою. Мінімум виключи **`.vscode/extensions.json`** і **`.vscode/settings.json`** (немає стабільної схеми в каталозі). Інші файли без схеми — за тією ж логікою; не розширюй ignore, щоб приховати проблеми там, де схема є. За потреби додай **`.git/**`** (службові JSON під `.git`) та **`npm/schemas/n-cursor.json`** у репозиторії `@nitra/cursor`, якщо для цього файлу немає стабільної схеми в ланцюжку v8r.
|
|
139
|
-
|
|
140
|
-
```text title=".v8rignore"
|
|
141
|
-
.vscode/extensions.json
|
|
142
|
-
.vscode/settings.json
|
|
143
|
-
.git/**
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
```json title=".markdownlint-cli2.jsonc"
|
|
147
|
-
{
|
|
148
|
-
"gitignore": true,
|
|
149
|
-
"config": {
|
|
150
|
-
"default": true,
|
|
151
|
-
"MD013": false,
|
|
152
|
-
"MD024": {
|
|
153
|
-
"siblings_only": true
|
|
154
|
-
},
|
|
155
|
-
"MD029": false,
|
|
156
|
-
"MD040": false,
|
|
157
|
-
"MD041": false
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
Канон: [.markdownlint-cli2.jsonc.snippet.jsonc](./policy/markdownlint/template/.markdownlint-cli2.jsonc.snippet.jsonc)
|
|
163
|
-
|
|
164
|
-
**MD041** off навмисно (`.mdc` з frontmatter). Деталі — [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2).
|
|
165
|
-
|
|
166
|
-
## Cspell
|
|
167
|
-
|
|
168
|
-
У корені проєкту має бути `.cspell.json` і залежності для cspell у кореневому `package.json` (зазвичай `devDependencies`).
|
|
169
|
-
|
|
170
|
-
Додай workflow `.github/workflows/lint-text.yml`:
|
|
171
|
-
|
|
172
|
-
- Канон: [lint-text.yml.snippet.yml](./policy/lint_text/template/lint-text.yml.snippet.yml)
|
|
173
|
-
|
|
174
|
-
Перед **`./.github/actions/setup-bun-deps`** — **`actions/checkout@v6`** (див. **ga.mdc**). Після composite — кроки **`Install shellcheck`** (apt) і **`Install dotenv-linter`** (curl), бо `n-cursor lint text` вимагає обидва бінарники в PATH; на ubuntu-latest shellcheck часто вже є, dotenv-linter — ні. Composite: Node 24, Bun, кеш, `bun install --frozen-lockfile`.
|
|
175
|
-
|
|
176
|
-
Не дублюй окремий workflow з тими самими кроками cspell/markdownlint.
|
|
177
|
-
|
|
178
|
-
**`.cspell.json`**, `version: "0.2"`, **`language`**, **`import`** з `@nitra/cspell-dict`, **`ignorePaths`**, **`words`** лише для назв/термінів, коли не виправити текстом.
|
|
179
|
-
|
|
180
|
-
Базово (англійська + українська + корпоративний словник):
|
|
181
|
-
|
|
182
|
-
```json title=".cspell.json"
|
|
183
|
-
{
|
|
184
|
-
"version": "0.2",
|
|
185
|
-
"language": "nitra",
|
|
186
|
-
"ignorePaths": ["**/node_modules/**", "**/vscode-extension/**", "**/.git/**", ".vscode", "report", "*.svg", "**/k8s/**/*.yaml", "docs/adr/**"],
|
|
187
|
-
"import": ["@nitra/cspell-dict/cspell-ext.json"],
|
|
188
|
-
"words": []
|
|
189
|
-
}
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
Канон базових ключів `.cspell.json` (`version`, `ignorePaths`): [.cspell.json.snippet.json](./policy/cspell/template/.cspell.json.snippet.json). Обовʼязковий запис у `import`: [.cspell.json.contains.json](./policy/cspell/template/.cspell.json.contains.json). Заборонено імпортувати окремі `@cspell/dict-*` у `.cspell.json`: [.cspell.json.deny.json](./policy/cspell/template/.cspell.json.deny.json).
|
|
193
|
-
|
|
194
|
-
`docs/adr/**` у канонічному `ignorePaths` — машинно-генеровані MADR-документи (драфти `capture-decisions.sh` + clean-ADR-и після `normalize-decisions.sh`). cspell-перевірка там безглузда: чернетка стирається наступним прогоном хук-ланцюжка, а будь-яка ручна правка правопису перезаписується. Локальні розширення `ignorePaths` дозволені — це лише мінімум.
|
|
195
|
-
|
|
196
|
-
```json title="package.json"
|
|
197
|
-
{
|
|
198
|
-
"devDependencies": {
|
|
199
|
-
"@nitra/cspell-dict": "^2.1.0"
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
## Проєкт з українською та російською (і суміжні мови)
|
|
205
|
-
|
|
206
|
-
У **`@nitra/cspell-dict`** від **2.0.0** уже зібрані залежності на **`@cspell/dict-uk-ua`**, **`@cspell/dict-ru_ru`** та інші типові словники — **не** дублюй їх у кореневому `package.json` і **не** імпортуй **`@cspell/dict-*/cspell-ext.json`** у `.cspell.json`.
|
|
207
|
-
|
|
208
|
-
**1. Залежності** — лише корпоративний пакет:
|
|
209
|
-
|
|
210
|
-
```json title="package.json"
|
|
211
|
-
{
|
|
212
|
-
"devDependencies": {
|
|
213
|
-
"@nitra/cspell-dict": "^2.1.0"
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
```
|
|
217
|
-
|
|
218
|
-
Встановлення: `bun add -d @nitra/cspell-dict@^2.0.0`.
|
|
219
|
-
|
|
220
|
-
**2. `.cspell.json`** — у полі **`language`** додай потрібні коди (наприклад **`uk`**, **`ru-ru`** разом з **`en`** та **`nitra`**). У **`import`** залиш лише **`@nitra/cspell-dict/cspell-ext.json`**:
|
|
221
|
-
|
|
222
|
-
```json title=".cspell.json"
|
|
223
|
-
{
|
|
224
|
-
"version": "0.2",
|
|
225
|
-
"language": "en,uk,ru-ru,nitra",
|
|
226
|
-
"ignorePaths": ["**/node_modules/**", "**/vscode-extension/**", "**/.git/**", ".vscode", "report", "*.svg", "**/k8s/**/*.yaml", "docs/adr/**"],
|
|
227
|
-
"import": ["@nitra/cspell-dict/cspell-ext.json"],
|
|
228
|
-
"words": []
|
|
229
|
-
}
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
Підлаштуй **`language`** під проєкт. Порядок у **`import`** може впливати на пріоритет словників — тримай корпоративний **`@nitra/cspell-dict`** першим, якщо додаєш інші розширення (рідко).
|
|
233
|
-
|
|
234
|
-
**Український апостроф:** у словах не використовуй прямий символ `'` (U+0027); потрібен типографський апостроф `’` (U+2019). Якщо після цього cspell досі підсвічує слово як невідоме — додай його до масиву `words` у `.cspell.json`.
|
|
235
|
-
|
|
236
|
-
## Локальні виключення (cspell `words`)
|
|
237
|
-
|
|
238
|
-
Коли **cspell** підсвічує слово, спочатку **виправ текст**, а не розширюй словник:
|
|
239
|
-
|
|
240
|
-
- виправ **друкарські помилки** та неправильні форми;
|
|
241
|
-
- **перефразуй коректною українською** (або англійською, залежно від контексту файлу): заміни кальки й випадкові склади на звичні формулювання зі словників;
|
|
242
|
-
- заміни **жаргон**, якщо є природний еквівалент у тому ж стилі документації (наприклад, у коментарях пиши «функція зворотного виклику» замість розмовного запозичення з англійського `callback`).
|
|
243
|
-
|
|
244
|
-
У секцію `words` у `.cspell.json` додавай записи **лише якщо переписати коректно неможливо** або **недоречно**: власні назви, стабільні технічні терміни без усталеного перекладу в проєкті, ідентифікатори зовнішніх API тощо.
|
|
245
|
-
|
|
246
|
-
## Інші мови
|
|
247
|
-
|
|
248
|
-
Якщо потрібна мова вже є в залежностях **`@nitra/cspell-dict`** — додай лише код у **`language`**, без окремих **`@cspell/dict-*`** у споживачі. Якщо мови немає в корпоративному пакеті — розширюй **`@nitra/cspell-dict`**, а не підключай **`@cspell/dict-*`** у корені репозиторію-споживача. Огляд upstream-словників: [streetsidesoftware/cspell-dicts](https://github.com/streetsidesoftware/cspell-dicts).
|
|
249
|
-
|
|
250
|
-
## Найменування каталогів
|
|
251
|
-
|
|
252
|
-
kebab-case
|
|
253
|
-
|
|
254
|
-
## Перевірка
|
|
255
|
-
|
|
256
|
-
`npx @nitra/cursor fix text` (охоплює oxfmt, cspell, shellcheck, markdownlint, v8r і CI для `n-cursor lint text`). Зокрема падає, якщо у корені є `.prettierignore`, `.prettierrc*`, `prettier.config.*` або у `package.json#scripts` зустрічається команда з `prettier` — Prettier повністю заборонено, форматування лише через **oxfmt**.
|
|
33
|
+
- `text.cspell` — `.cspell.json`: version, ignorePaths, import (@nitra/cspell-dict), language, заборонені @cspell/dict-* у import
|
|
34
|
+
- `text.lint_text` — `.github/workflows/lint-text.yml`: name, on.push/pull_request branches+paths, runs-on, permissions, кроки uses+run
|
|
35
|
+
- `text.markdownlint` — `.markdownlint-cli2.jsonc`: gitignore, config leafs (MD013, MD024.siblings_only, MD029, MD040, MD041)
|
|
36
|
+
- `text.oxfmtrc` — `.oxfmtrc.json`: обовʼязкові ключі (presence), ignorePatterns subset, scalar leafs
|
|
37
|
+
- `text.package_json` — `package.json`: заборонені top-level/deps (prettier, @nitra/prettier-config, markdownlint-cli2), @nitra/cspell-dict ^2.0.0+ у devDependencies, scripts без prettier
|
|
38
|
+
- `text.vscode_extensions` — `.vscode/extensions.json`: recommendations містить канонічні розширення
|
|
39
|
+
- `text.vscode_settings` — `.vscode/settings.json`: editor.formatOnSave, editor.defaultFormatter для мов
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
## Найкращі практики Vue 3 Composition API
|
|
2
|
+
|
|
3
|
+
```javascript
|
|
4
|
+
const vue3CompositionApiBestPractices = [
|
|
5
|
+
'Використовуй функцію setup() для логіки компонента',
|
|
6
|
+
'Реалізуй computed змінні через $computed()',
|
|
7
|
+
'Реалізуй ref змінні через $ref',
|
|
8
|
+
'Використовуй watch і watchEffect для побічних ефектів',
|
|
9
|
+
'Підключай lifecycle hooks: onMounted, onUpdated тощо',
|
|
10
|
+
'Для глибоко вкладених залежностей використовуй composables, props/emits або store'
|
|
11
|
+
'не використовуй provide/inject для залежностей'
|
|
12
|
+
]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Патерни та антипатерни
|
|
16
|
+
|
|
17
|
+
- Для глибоко вкладених залежностей використовуй **composables**, **props/emits** або **store**; **renderless**-компоненти / **slots** — коли логіку відділяєш від розмітки.
|
|
18
|
+
- **HTTP:** окремі модулі **services** або **composables** для API; **async/await**.
|
|
19
|
+
- **Події:** батько–дитина через **emits**; для не пов'язаних гілок — **store**.
|
|
20
|
+
- Не мутуй **props** напряму — оновлення через подію вгору або v-model.
|
|
21
|
+
- Обмежуй зайве в глобальному стані; локальний стан у компоненті — за замовчуванням.
|
|
22
|
+
- Уникай прямої роботи з **DOM**, якщо достатньо реактивного шаблону та ref.
|
|
23
|
+
|
|
24
|
+
### State management
|
|
25
|
+
|
|
26
|
+
- **Single source of truth** для спільних даних: у нових проєктах на Vue 3 **Pinia** (модульні stores, actions).
|
|
27
|
+
- Похідний стан — через обчислення в store або **computed** у компонентах, без «тихих» побічних ефектів у getters.
|
|
28
|
+
|
|
29
|
+
### Обробка помилок
|
|
30
|
+
|
|
31
|
+
- **try/catch** навколо async-операцій; зрозумілі повідомлення для користувача через notifySuccess, notifyError; логування на сервіс моніторингу за потреби.
|
|
32
|
+
|
|
33
|
+
### Продуктивність
|
|
34
|
+
|
|
35
|
+
- **v-for** — стабільні унікальні **`:key`**; не плутай **v-if** (умовний mount) і **v-show** (перемикання visibility).
|
|
36
|
+
- **debounce/throttle** для частих подій.
|
|
37
|
+
- Після ручних **addEventListener** / підписок — прибирай у **onUnmounted**.
|
|
38
|
+
|
|
39
|
+
### Функції в шаблоні
|
|
40
|
+
|
|
41
|
+
Виклики функцій у шаблоні дозволені **лише** в обробниках подій (`@click`, `@change` тощо). У всіх інших місцях — `v-if`, `v-show`, атрибутах (`:prop`), інтерполяціях (`{{ }}`) — замінюй функції на `computed`-властивості: функція виконується при **кожному** render-і, тоді як `computed` кешується і перераховується лише при зміні залежностей.
|
|
42
|
+
|
|
43
|
+
```vue
|
|
44
|
+
<!-- ❌ функція в умові, атрибуті та інтерполяції -->
|
|
45
|
+
<q-item v-if="getItems(order).length" :label="getLabel(item)">
|
|
46
|
+
{{ formatName(user) }}
|
|
47
|
+
</q-item>
|
|
48
|
+
|
|
49
|
+
<!-- ✅ реактивні змінні / computed / props -->
|
|
50
|
+
<q-item v-if="itemsMap[order.id].length" :label="item.label">
|
|
51
|
+
{{ user.displayName }}
|
|
52
|
+
</q-item>
|
|
53
|
+
<!-- обробник події — виклик функції дозволений -->
|
|
54
|
+
<q-btn @click="doSomething(item)" />
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Безпека
|
|
58
|
+
|
|
59
|
+
- Не довіряй **v-html** без санітизації; для форм/API — **CSRF**-захист за потреби; валідація **на сервері** обов'язкова.
|
|
60
|
+
|
|
61
|
+
### Приклад компонента
|
|
62
|
+
|
|
63
|
+
```javascript
|
|
64
|
+
// Приклад Vue 3 компонента з Composition API
|
|
65
|
+
import { computed, onMounted } from 'vue'
|
|
66
|
+
|
|
67
|
+
export default {
|
|
68
|
+
setup() {
|
|
69
|
+
const count = $ref(0)
|
|
70
|
+
const doubleCount = $computed(() => count * 2)
|
|
71
|
+
|
|
72
|
+
onMounted(() => {
|
|
73
|
+
console.log('Компонент змонтовано')
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
count,
|
|
78
|
+
doubleCount
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
## NHeader — телепорт-слоти на сторінках
|
|
2
|
+
|
|
3
|
+
У проектах з `NHeader` використовуй `<teleport>` для вбудовування контенту сторінки в шапку:
|
|
4
|
+
|
|
5
|
+
| Слот | Призначення |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| `#header-subtitle` | Заголовок сторінки (якщо потрібно перевизначити subtitle) |
|
|
8
|
+
| `#header-center` | Важливі повідомлення та елементи управління |
|
|
9
|
+
| `#header-filters` | Фільтри, кнопки та інші елементи управління сторінки |
|
|
10
|
+
|
|
11
|
+
Оскільки `NHeader` за замовчуванням темний, додавай до полів і селектів у телепортах: `dark`, `standout="bg-white text-primary"`, `:options-dark="false"`.
|
|
12
|
+
|
|
13
|
+
Завжди обгортай `<teleport>` в `v-if="mounted"` (де `mounted` — `$ref(false)`, що встановлюється в `onMounted`), щоб уникнути помилки відсутності target-елемента при SSR / першому рендері.
|
|
14
|
+
|
|
15
|
+
```vue
|
|
16
|
+
<template>
|
|
17
|
+
<q-page>
|
|
18
|
+
<!-- ФІЛЬТРИ В ШАПЦІ -->
|
|
19
|
+
<teleport v-if="mounted" to="#header-filters">
|
|
20
|
+
<div class="col row items-center n-gap-sm q-pa-sm">
|
|
21
|
+
<q-input
|
|
22
|
+
v-model="pageStore.filterName"
|
|
23
|
+
:label="t`Поиск по названию`"
|
|
24
|
+
debounce="200"
|
|
25
|
+
standout="bg-white text-primary"
|
|
26
|
+
clearable
|
|
27
|
+
dense
|
|
28
|
+
dark
|
|
29
|
+
class="col"
|
|
30
|
+
style="min-width: 120px">
|
|
31
|
+
<template #prepend>
|
|
32
|
+
<q-icon name="search" />
|
|
33
|
+
</template>
|
|
34
|
+
</q-input>
|
|
35
|
+
|
|
36
|
+
<n-select-multi
|
|
37
|
+
v-model="pageStore.filterRequestTypes"
|
|
38
|
+
:options="requestTypeOptions"
|
|
39
|
+
:label="t`Тип запроса`"
|
|
40
|
+
dark
|
|
41
|
+
standout="bg-white text-primary"
|
|
42
|
+
:options-dark="false"
|
|
43
|
+
style="min-width: 180px; max-width: 400px"
|
|
44
|
+
dense
|
|
45
|
+
emit-value
|
|
46
|
+
map-options
|
|
47
|
+
clearable
|
|
48
|
+
searchable
|
|
49
|
+
:stack-label="false" />
|
|
50
|
+
|
|
51
|
+
<q-btn
|
|
52
|
+
@click="addItem"
|
|
53
|
+
icon="add"
|
|
54
|
+
:label="t`Добавить`"
|
|
55
|
+
color="primary"
|
|
56
|
+
no-caps
|
|
57
|
+
padding="8px 12px"
|
|
58
|
+
unelevated />
|
|
59
|
+
</div>
|
|
60
|
+
</teleport>
|
|
61
|
+
|
|
62
|
+
<!-- ОСНОВНИЙ КОНТЕНТ -->
|
|
63
|
+
...
|
|
64
|
+
</q-page>
|
|
65
|
+
</template>
|
|
66
|
+
<script setup>
|
|
67
|
+
const mounted = $ref(false)
|
|
68
|
+
onMounted(() => { mounted = true })
|
|
69
|
+
</script>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Layout з NHeader
|
|
73
|
+
|
|
74
|
+
Для нових layout-ів використовуй `NHeader` з вбудованими `NLang` і `NMenu`.
|
|
75
|
+
|
|
76
|
+
```vue
|
|
77
|
+
<template>
|
|
78
|
+
<q-layout view="hHh Lpr lFf">
|
|
79
|
+
<n-header
|
|
80
|
+
v-model="leftSideOpened"
|
|
81
|
+
:logo="baseUrl + 'logo.png'"
|
|
82
|
+
:logo-url="homeUrl"
|
|
83
|
+
title="My App"
|
|
84
|
+
:subtitle="subtitle"
|
|
85
|
+
:username="userName"
|
|
86
|
+
toolbar-dark>
|
|
87
|
+
<template #top-toolbar>
|
|
88
|
+
<div class="platform-ios-only q-py-lg" />
|
|
89
|
+
</template>
|
|
90
|
+
<div>default slot content</div>
|
|
91
|
+
</n-header>
|
|
92
|
+
|
|
93
|
+
<!-- ЛЕВАЯ КОЛОНКА -->
|
|
94
|
+
<q-drawer v-model="leftSideOpened" :breakpoint="700" :width="300" overlay class="col column shadow-5 bg-grey-1">
|
|
95
|
+
<div class="platform-ios-only q-py-lg" />
|
|
96
|
+
<div v-if="!$q.screen.gt.xs" class="q-pa-sm row items-center">
|
|
97
|
+
<q-icon name="account_circle" color="primary" size="32px" class="q-mr-sm" />
|
|
98
|
+
<div class="text-subtitle1">{{ user.name }}</div>
|
|
99
|
+
</div>
|
|
100
|
+
<n-menu v-model="activeMenu" :menu="menu" />
|
|
101
|
+
<q-space />
|
|
102
|
+
<n-menu :menu="homeMenu" />
|
|
103
|
+
<div class="platform-ios-only q-py-md" />
|
|
104
|
+
</q-drawer>
|
|
105
|
+
|
|
106
|
+
<q-page-container>
|
|
107
|
+
<router-view />
|
|
108
|
+
</q-page-container>
|
|
109
|
+
</q-layout>
|
|
110
|
+
</template>
|
|
111
|
+
<script setup>
|
|
112
|
+
import { lang, tf as tfm } from '@nitra/tfm'
|
|
113
|
+
const t = tfm.bind({ tr: getTr() })
|
|
114
|
+
|
|
115
|
+
const baseUrl = import.meta.env.BASE_URL
|
|
116
|
+
const homeUrl = String.raw`https:\\` + import.meta.env.VITE_DOMAIN
|
|
117
|
+
|
|
118
|
+
// Ліва колонка
|
|
119
|
+
const leftSideOpened = $ref(false)
|
|
120
|
+
const activeMenu = $ref(null)
|
|
121
|
+
|
|
122
|
+
// Заголовок у шапці з поточного пункту меню
|
|
123
|
+
const subtitle = computed(() => (activeMenu ? getTr()[activeMenu.labelKey]?.[lang.value] || activeMenu?.labelKey : ''))
|
|
124
|
+
|
|
125
|
+
// Меню
|
|
126
|
+
const menu = computed(() =>
|
|
127
|
+
[
|
|
128
|
+
{
|
|
129
|
+
icon: 'sym_o_store',
|
|
130
|
+
label: t`Клиенты`,
|
|
131
|
+
labelKey: t`Клиенты`,
|
|
132
|
+
routeName: 'customer'
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
icon: 'sym_o_route',
|
|
136
|
+
label: t`Маршруты и визиты`,
|
|
137
|
+
items: [
|
|
138
|
+
{
|
|
139
|
+
icon: 'sym_o_route',
|
|
140
|
+
label: t`Маршруты`,
|
|
141
|
+
labelKey: t`Маршруты`,
|
|
142
|
+
routeName: 'route'
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
icon: 'sym_o_event_upcoming',
|
|
146
|
+
label: t`Переносы маршрутов`,
|
|
147
|
+
labelKey: t`Переносы маршрутов`,
|
|
148
|
+
routeName: 'route_postpone'
|
|
149
|
+
}
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
].filter(item => {
|
|
153
|
+
if (item.items?.length) {
|
|
154
|
+
item.items = item.items.filter(i => can[i.permissionRoute || i.routeName])
|
|
155
|
+
return item.items.length > 0
|
|
156
|
+
}
|
|
157
|
+
return can[item.routeName]
|
|
158
|
+
})
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* LOCALIZATION
|
|
163
|
+
* @returns {object} translations
|
|
164
|
+
*/
|
|
165
|
+
function getTr() {
|
|
166
|
+
return {
|
|
167
|
+
Клиенты: { en: 'Customers', ro: 'Clienți', tr: 'Müşteriler' }
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
</script>
|
|
171
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
## Заборонено імпортувати Node-нативні модулі у `.vue` SFC
|
|
2
|
+
|
|
3
|
+
Vue SFC виконується у браузері, тож API Node.js там недоступне. У `<script>` (включно з `<script setup>`)
|
|
4
|
+
заборонено будь-які імпорти вбудованих модулів Node — як з префіксом `node:`, так і bare-ім'ям модуля
|
|
5
|
+
(включно з підшляхами):
|
|
6
|
+
|
|
7
|
+
```vue title="погано — ламає білд"
|
|
8
|
+
<script setup lang="ts">
|
|
9
|
+
import { setTimeout as sleep } from 'node:timers/promises'
|
|
10
|
+
import fs from 'fs'
|
|
11
|
+
import { readFile } from 'fs/promises'
|
|
12
|
+
import path from 'node:path'
|
|
13
|
+
</script>
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Якщо потрібна логіка з Node API — винеси її у server-side утіліту (наприклад, у backend-пакет монорепо)
|
|
17
|
+
та звертайся до неї через HTTP/GraphQL. Браузерні замінники (`window.crypto`, `URL`, `setTimeout` глобальний,
|
|
18
|
+
`AbortController` тощо) використовуй напряму, без import.
|
|
19
|
+
|
|
20
|
+
Правило стосується саме `.vue` файлів. Допоміжні `.ts`/`.js` модулі, які споживаються лише server-side
|
|
21
|
+
(наприклад, окремий пакет утіліт), можуть імпортувати Node-built-ins без обмежень.
|
|
22
|
+
|
|
23
|
+
Перевірка реалізована у `npm/rules/vue/lib/vue-forbidden-imports.mjs` через функцію
|
|
24
|
+
`findForbiddenNodeImportsInVueFile` — аналізує лише `<script>` блоки SFC через **oxc-parser**,
|
|
25
|
+
ігноруючи `<template>`.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
## Quasar як UI-основа
|
|
2
|
+
|
|
3
|
+
У Vue-проектах використовуй **Quasar** як базовий UI-фреймворк:
|
|
4
|
+
|
|
5
|
+
- **Компоненти:** `q-btn`, `q-input`, `q-select`, `q-table`, `q-dialog`, `q-card`, `q-layout`, `q-page`, `q-drawer` тощо — основа UI.
|
|
6
|
+
- **Плагіни:** `Notify`, `Dialog`, `Loading` та інші Quasar-плагіни.
|
|
7
|
+
- **Кольори:** використовуй Quasar CSS-змінні (`primary`, `secondary`, `accent`, `positive`, `negative`, `warning`, `info`, `dark`) і утиліти (`text-primary`, `bg-accent` тощо).
|
|
8
|
+
- **Утиліти:** flex-layout (`row`, `col`, `items-center`), spacing (`q-pa-md`, `q-mt-sm`), shadow (`shadow-2`) — зі стандартної бібліотеки Quasar.
|
|
9
|
+
- **Кастомні компоненти** `@nitra/components` — **надбудова** над Quasar, а не заміна; їх слід надавати перевагу лише там, де вони є.
|
|
10
|
+
|
|
11
|
+
## @nitra/components — надавай перевагу перед Quasar-компонентами
|
|
12
|
+
|
|
13
|
+
При створенні нової функціональності використовуй компоненти `@nitra/components`, якщо логіка компонента дозволяє отримати потрібний функціонал. Заміни:
|
|
14
|
+
|
|
15
|
+
| Завдання | `@nitra/components` | Замість Quasar |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| Діалоги | `NDialog` | `q-dialog` |
|
|
18
|
+
| Multi-вибір | `NSelectMulti` | `q-select` (multiple) |
|
|
19
|
+
| Текстовий редактор | `NEditor` | `q-editor` |
|
|
20
|
+
| Вибір дати | `NDate` | — |
|
|
21
|
+
| Вибір місяця/року | `NDateMonthYear` | — |
|
|
22
|
+
| Діапазон дат | `NDateRange` | — |
|
|
23
|
+
| Дата і час | `NDateTime` | — |
|
|
24
|
+
| Drag&drop список | `NDraggableList` | — |
|
|
25
|
+
| Редаговане значення | `NEditableString` | — |
|
|
26
|
+
| Повідомлення | `NCallout` | — |
|
|
27
|
+
| Хедер проекту | `NHeader` | — |
|
|
28
|
+
| Перемикання мов | `NLang` | — (якщо `NHeader` не використовується) |
|
|
29
|
+
| Меню проекту | `NMenu` | — |
|
|
30
|
+
| Зображення (масив / одиночне) | `NImages` | — |
|
|
31
|
+
| Завантаження файлів | `NUploader` | — |
|
|
32
|
+
| Вибір колонок `q-table` | `NTableColumns` | — |
|