@retailcrm/embed-ui-v1-components 0.9.14 → 0.9.15

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 (74) hide show
  1. package/AGENTS.md +126 -0
  2. package/README.md +24 -0
  3. package/assets/stylesheets/palette.less +11 -6
  4. package/bin/embed-ui-v1-components.mjs +209 -0
  5. package/bin/postinstall.mjs +37 -0
  6. package/dist/host.cjs +1899 -590
  7. package/dist/host.css +659 -6
  8. package/dist/host.d.ts +2374 -50
  9. package/dist/host.js +1900 -591
  10. package/dist/remote.cjs +610 -33
  11. package/dist/remote.d.ts +729 -48
  12. package/dist/remote.js +612 -35
  13. package/docs/AI.md +106 -0
  14. package/docs/COMPONENTS.md +96 -0
  15. package/docs/FORMAT.md +248 -0
  16. package/docs/PROFILES.md +64 -0
  17. package/docs/README.md +65 -0
  18. package/docs/STYLING.md +156 -0
  19. package/docs/profiles/UiAddButton.yml +45 -0
  20. package/docs/profiles/UiAlert.yml +36 -0
  21. package/docs/profiles/UiAvatar.yml +36 -0
  22. package/docs/profiles/UiAvatarList.yml +30 -0
  23. package/docs/profiles/UiButton.yml +221 -0
  24. package/docs/profiles/UiCalendar.yml +36 -0
  25. package/docs/profiles/UiCheckbox.yml +41 -0
  26. package/docs/profiles/UiCollapse.yml +28 -0
  27. package/docs/profiles/UiCollapseBox.yml +39 -0
  28. package/docs/profiles/UiCollapseGroup.yml +27 -0
  29. package/docs/profiles/UiCopyButton.yml +40 -0
  30. package/docs/profiles/UiDate.yml +26 -0
  31. package/docs/profiles/UiDatePicker.yml +47 -0
  32. package/docs/profiles/UiError.yml +20 -0
  33. package/docs/profiles/UiField.yml +229 -0
  34. package/docs/profiles/UiImage.yml +27 -0
  35. package/docs/profiles/UiInfobox.yml +33 -0
  36. package/docs/profiles/UiLink.yml +39 -0
  37. package/docs/profiles/UiLoader.yml +26 -0
  38. package/docs/profiles/UiMenuItem.yml +45 -0
  39. package/docs/profiles/UiMenuItemGroup.yml +38 -0
  40. package/docs/profiles/UiModalSidebar.yml +34 -0
  41. package/docs/profiles/UiModalWindow.yml +32 -0
  42. package/docs/profiles/UiModalWindowSurface.yml +29 -0
  43. package/docs/profiles/UiNumberStepper.yml +40 -0
  44. package/docs/profiles/UiPageHeader.yml +240 -0
  45. package/docs/profiles/UiPopper.yml +197 -0
  46. package/docs/profiles/UiPopperConnector.yml +109 -0
  47. package/docs/profiles/UiPopperTarget.yml +112 -0
  48. package/docs/profiles/UiRadio.yml +26 -0
  49. package/docs/profiles/UiRadioSwitch.yml +224 -0
  50. package/docs/profiles/UiRadioSwitchOption.yml +113 -0
  51. package/docs/profiles/UiScrollBox.yml +19 -0
  52. package/docs/profiles/UiSelect.yml +318 -0
  53. package/docs/profiles/UiSelectOption.yml +32 -0
  54. package/docs/profiles/UiSelectOptionGroup.yml +26 -0
  55. package/docs/profiles/UiSlider.yml +26 -0
  56. package/docs/profiles/UiSwitch.yml +25 -0
  57. package/docs/profiles/UiTab.yml +114 -0
  58. package/docs/profiles/UiTabGroup.yml +233 -0
  59. package/docs/profiles/UiTable.yml +148 -0
  60. package/docs/profiles/UiTableBodyCell.yml +35 -0
  61. package/docs/profiles/UiTableColumn.yml +38 -0
  62. package/docs/profiles/UiTableFooterButton.yml +32 -0
  63. package/docs/profiles/UiTableFooterSection.yml +26 -0
  64. package/docs/profiles/UiTableHeadCell.yml +32 -0
  65. package/docs/profiles/UiTableSorter.yml +33 -0
  66. package/docs/profiles/UiTag.yml +29 -0
  67. package/docs/profiles/UiTextbox.yml +388 -0
  68. package/docs/profiles/UiTimePicker.yml +34 -0
  69. package/docs/profiles/UiToolbarButton.yml +25 -0
  70. package/docs/profiles/UiToolbarLink.yml +20 -0
  71. package/docs/profiles/UiTooltip.yml +31 -0
  72. package/docs/profiles/UiTransition.yml +15 -0
  73. package/docs/profiles/UiYandexMap.yml +17 -0
  74. package/package.json +7 -2
package/AGENTS.md ADDED
@@ -0,0 +1,126 @@
1
+ # AGENTS.md
2
+
3
+ ## Purpose
4
+
5
+ This file is for AI assistants and automation that use the built package
6
+ `@retailcrm/embed-ui-v1-components` in application code.
7
+
8
+ It is not a contributor guide for editing the internal source of this workspace.
9
+ Treat this file as usage guidance for the published API.
10
+
11
+ ## What This Package Is
12
+
13
+ - Package: `@retailcrm/embed-ui-v1-components`
14
+ - Role: UI component library for RetailCRM JS extensions
15
+ - Framework: Vue 3
16
+ - Main consumer entrypoint: `@retailcrm/embed-ui-v1-components/remote`
17
+
18
+ This package exposes declarative UI primitives that are rendered by RetailCRM host runtime.
19
+
20
+ ## How To Import
21
+
22
+ - For extension UI code, import from `@retailcrm/embed-ui-v1-components/remote`.
23
+ - For icons and static assets, import from `@retailcrm/embed-ui-v1-components/assets/...`.
24
+ - Do not import from package-internal files such as `dist/*` or internal workspace files when writing extension code.
25
+ - Do not recommend `@retailcrm/embed-ui-v1-components/host` unless the task is explicitly about CRM host internals.
26
+
27
+ ## Mental Model
28
+
29
+ - `remote` is the public API for extension authors.
30
+ - Components from `remote` do not represent a standalone design system outside RetailCRM.
31
+ - Extension code describes UI declaratively, and the CRM host side interprets and renders it.
32
+ - Because of this architecture, prefer documented public props and slots over assumptions based on internal implementation.
33
+
34
+ ## Safe Default Recommendation
35
+
36
+ When building UI in an extension, start with imports like:
37
+
38
+ ```ts
39
+ import {
40
+ UiButton,
41
+ UiField,
42
+ UiPageHeader,
43
+ UiSelect,
44
+ UiTextbox,
45
+ } from '@retailcrm/embed-ui-v1-components/remote'
46
+ ```
47
+
48
+ ## Public API Areas
49
+
50
+ Commonly used exports from `remote` include:
51
+
52
+ - form controls:
53
+ `UiTextbox`, `UiCheckbox`, `UiRadio`, `UiSwitch`, `UiSlider`, `UiNumberStepper`
54
+ - selection and date controls:
55
+ `UiSelect`, `UiSelectOption`, `UiSelectOptionGroup`, `UiDatePicker`, `UiTimePicker`, `UiCalendar`
56
+ - layout and structure:
57
+ `UiField`, `UiPageHeader`, `UiCollapse`, `UiCollapseBox`, `UiScrollBox`
58
+ - actions and links:
59
+ `UiButton`, `UiAddButton`, `UiCopyButton`, `UiToolbarButton`, `UiToolbarLink`, `UiLink`
60
+ - feedback and overlays:
61
+ `UiAlert`, `UiInfobox`, `UiError`, `UiLoader`, `UiTooltip`, `UiModalWindow`, `UiModalSidebar`
62
+ - content and data display:
63
+ `UiAvatar`, `UiAvatarList`, `UiDate`, `UiImage`, `UiTag`, `UiTable`, `UiTableColumn`, `UiYandexMap`
64
+ - helpers:
65
+ `usePreview`, `ImageWorkersKey`, `formatDate`, `formatDateTime`, `formatTime`
66
+
67
+ ## Usage Rules
68
+
69
+ - Prefer package public exports over reimplementing CRM-styled controls manually.
70
+ - Match component choice to semantics:
71
+ use `UiField` for labeled form controls, `UiAlert` for state messages, `UiPageHeader` for page-level headings.
72
+ - Keep imports on the public package boundary.
73
+ - If you are unsure whether something is public, assume only exports from `remote` and `assets/*` are safe for consumer code.
74
+ - If a needed capability is missing from the public API, say that clearly instead of suggesting internal imports.
75
+
76
+ ## What To Avoid
77
+
78
+ - Do not import from `@retailcrm/embed-ui-v1-components/host` in normal extension code.
79
+ - Do not rely on internal file paths from this repository.
80
+ - Do not treat Storybook examples or internal source layout as stable runtime API.
81
+ - Do not assume every host-side component is available to extension authors.
82
+
83
+ ## Example
84
+
85
+ ```vue
86
+ <template>
87
+ <UiPageHeader
88
+ title="История заказа"
89
+ description="Последние изменения и служебные действия"
90
+ />
91
+
92
+ <UiField id="comment" label="Комментарий">
93
+ <UiTextbox v-model="comment" placeholder="Введите текст" />
94
+ </UiField>
95
+
96
+ <UiButton @click="save">
97
+ Сохранить
98
+ </UiButton>
99
+ </template>
100
+
101
+ <script lang="ts" setup>
102
+ import { ref } from 'vue'
103
+
104
+ import {
105
+ UiButton,
106
+ UiField,
107
+ UiPageHeader,
108
+ UiTextbox,
109
+ } from '@retailcrm/embed-ui-v1-components/remote'
110
+
111
+ const comment = ref('')
112
+
113
+ const save = () => {}
114
+ </script>
115
+ ```
116
+
117
+ ## If You Need More Context
118
+
119
+ - Package README:
120
+ [`./README.md`](./README.md)
121
+ - Human-oriented package docs:
122
+ [`./docs/README.md`](./docs/README.md)
123
+ - Machine-oriented package summary:
124
+ [`./docs/AI.md`](./docs/AI.md)
125
+ - Component profiles:
126
+ [`./docs/PROFILES.md`](./docs/PROFILES.md)
package/README.md CHANGED
@@ -41,3 +41,27 @@ import { UiButton } from '@retailcrm/embed-ui-v1-components/remote'
41
41
  интерфейс. Библиотека также содержит `@retailcrm/embed-ui-v1-components/host` &ndash; набор компонентов,
42
42
  который будет использовать CRM при интерпретации инструкций от расширений. **_Не используйте_** host компоненты
43
43
  как часть кода расширения.
44
+
45
+ ## Документация пакета
46
+
47
+ Дополнительные материалы по пакету находятся в `docs/`:
48
+
49
+ - [`docs/README.md`](./docs/README.md) — обзор пакета и правил использования.
50
+ - [`docs/COMPONENTS.md`](./docs/COMPONENTS.md) — карта публичных компонентов.
51
+ - [`docs/AI.md`](./docs/AI.md) — контекст для ИИ и автоматизаций.
52
+ - [`docs/PROFILES.md`](./docs/PROFILES.md) — AI-friendly YAML-профили компонентов.
53
+ - [`docs/FORMAT.md`](./docs/FORMAT.md) — формат описания компонента для AI-агентов.
54
+
55
+ ## AI и инициализация `AGENTS.md`
56
+
57
+ После установки пакет показывает подсказку, что внутри есть AI-заметки и YAML-профили компонентов.
58
+
59
+ Если в целевом проекте еще нет `AGENTS.md`, можно сгенерировать стартовый файл командой:
60
+
61
+ ```bash
62
+ npx @retailcrm/embed-ui-v1-components init-agents
63
+ ```
64
+
65
+ Если `AGENTS.md` уже существует, команда допишет в конец инструкции для
66
+ `@retailcrm/embed-ui-v1-components`, если такого блока там еще нет. С `--force`
67
+ можно обновить уже существующий блок пакета.
@@ -11,7 +11,8 @@
11
11
  @red-800: #932121;
12
12
  @red-900: #932121;
13
13
 
14
- @red-transparent: rgba(255, 83, 83, 0.1);
14
+ @red-translucent: rgba(255, 83, 83, 0.1);
15
+ @red-transparent: @red-translucent;
15
16
 
16
17
  /* Blue */
17
18
  @blue-100: #EDF4FF;
@@ -24,7 +25,8 @@
24
25
  @blue-800: #0033A2;
25
26
  @blue-900: #00228C;
26
27
 
27
- @blue-transparent: rgba(0, 94, 235, 0.12);
28
+ @blue-translucent: rgba(0, 94, 235, 0.12);
29
+ @blue-transparent: @blue-translucent;
28
30
 
29
31
  /* Yellow */
30
32
  @yellow-100: #FFF9F0;
@@ -37,7 +39,8 @@
37
39
  @yellow-800: #BC6B01;
38
40
  @yellow-900: #965601;
39
41
 
40
- @yellow-transparent: rgba(254, 165, 48, 0.12);
42
+ @yellow-translucent: rgba(254, 165, 48, 0.12);
43
+ @yellow-transparent: @yellow-translucent;
41
44
 
42
45
  /* Green */
43
46
  @green-100: #D8F8EE;
@@ -50,7 +53,8 @@
50
53
  @green-800: #168561;
51
54
  @green-900: #106349;
52
55
 
53
- @green-transparent: rgba(34, 201, 147, 0.16);
56
+ @green-translucent: rgba(34, 201, 147, 0.16);
57
+ @green-transparent: @green-translucent;
54
58
 
55
59
  /* Purple */
56
60
  @purple-100: #E5DBF8;
@@ -63,7 +67,8 @@
63
67
  @purple-800: #371F7C;
64
68
  @purple-900: #2D1A68;
65
69
 
66
- @purple-transparent: rgba(101, 40, 215, 0.12);
70
+ @purple-translucent: rgba(101, 40, 215, 0.12);
71
+ @purple-transparent: @purple-translucent;
67
72
 
68
73
  /* Black */
69
74
  @black-100: #323976;
@@ -85,4 +90,4 @@
85
90
  @grey-600: #C7CDD4;
86
91
  @grey-700: #AFB9C3;
87
92
  @grey-800: #8A96A6;
88
- @grey-900: #636F7F;
93
+ @grey-900: #636F7F;
@@ -0,0 +1,209 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from 'node:fs'
4
+ import path from 'node:path'
5
+ import process from 'node:process'
6
+
7
+ const PACKAGE_NAME = '@retailcrm/embed-ui-v1-components'
8
+ const DEFAULT_NEWLINE = '\n'
9
+ const AGENTS_SECTION_HEADER = '## @retailcrm/embed-ui-v1-components'
10
+
11
+ const HELP_TEXT = `Usage:
12
+ npx ${PACKAGE_NAME} init-agents [target] [options]
13
+
14
+ Options:
15
+ -f, --force Replace existing package section in AGENTS.md
16
+ -h, --help Show this help
17
+
18
+ Examples:
19
+ npx ${PACKAGE_NAME} init-agents
20
+ npx ${PACKAGE_NAME} init-agents ./my-project
21
+ npx ${PACKAGE_NAME} init-agents --force
22
+ `
23
+
24
+ const parseArgs = (argv) => {
25
+ const options = {
26
+ command: null,
27
+ target: process.cwd(),
28
+ force: false,
29
+ }
30
+
31
+ const positionals = []
32
+
33
+ for (let index = 0; index < argv.length; index++) {
34
+ const argument = argv[index]
35
+
36
+ if (argument === '-h' || argument === '--help') {
37
+ console.log(HELP_TEXT)
38
+ process.exit(0)
39
+ }
40
+
41
+ if (argument === '-f' || argument === '--force') {
42
+ options.force = true
43
+ continue
44
+ }
45
+
46
+ if (argument.startsWith('-')) {
47
+ throw new Error(`Unknown option: ${argument}`)
48
+ }
49
+
50
+ positionals.push(argument)
51
+ }
52
+
53
+ if (!positionals.length) {
54
+ throw new Error('Command is required')
55
+ }
56
+
57
+ options.command = positionals[0]
58
+
59
+ if (positionals.length >= 2) {
60
+ options.target = path.resolve(process.cwd(), positionals[1])
61
+ }
62
+
63
+ if (positionals.length > 2) {
64
+ throw new Error('Too many positional arguments')
65
+ }
66
+
67
+ return options
68
+ }
69
+
70
+ const createAgentsTemplate = () => {
71
+ return `# AGENTS.md
72
+
73
+ ${AGENTS_SECTION_HEADER}
74
+
75
+ When working with \`${PACKAGE_NAME}\` in this project:
76
+
77
+ 1. Read \`./node_modules/${PACKAGE_NAME}/docs/AI.md\`.
78
+ 2. Then read \`./node_modules/${PACKAGE_NAME}/docs/COMPONENTS.md\`.
79
+ 3. Then open the relevant profile from \`./node_modules/${PACKAGE_NAME}/docs/profiles/<Component>.yml\`.
80
+ 4. Prefer those docs and profiles over guessing from internal implementation files.
81
+ 5. Import only from documented public entrypoints:
82
+ - \`${PACKAGE_NAME}/remote\`
83
+ - \`${PACKAGE_NAME}/host\`
84
+ - \`${PACKAGE_NAME}/assets/...\`
85
+ 6. Prefer \`${PACKAGE_NAME}/remote\` for extension UI code.
86
+ 7. Do not import from package-internal files such as \`dist/*\`, repository-only paths, or source internals.
87
+
88
+ ## Suggested Reading Order
89
+
90
+ 1. \`docs/AI.md\`
91
+ 2. \`docs/COMPONENTS.md\`
92
+ 3. The relevant profile from \`docs/profiles/*.yml\`
93
+ 4. \`docs/FORMAT.md\` if you need to understand profile structure
94
+ 5. Storybook and public types only when no profile exists yet
95
+ ` + DEFAULT_NEWLINE
96
+ }
97
+
98
+ const createAgentsSection = () => {
99
+ return `${AGENTS_SECTION_HEADER}
100
+
101
+ When working with \`${PACKAGE_NAME}\` in this project:
102
+
103
+ 1. Read \`./node_modules/${PACKAGE_NAME}/docs/AI.md\`.
104
+ 2. Then read \`./node_modules/${PACKAGE_NAME}/docs/COMPONENTS.md\`.
105
+ 3. Then open the relevant profile from \`./node_modules/${PACKAGE_NAME}/docs/profiles/<Component>.yml\`.
106
+ 4. Prefer those docs and profiles over guessing from internal implementation files.
107
+ 5. Import only from documented public entrypoints:
108
+ - \`${PACKAGE_NAME}/remote\`
109
+ - \`${PACKAGE_NAME}/host\`
110
+ - \`${PACKAGE_NAME}/assets/...\`
111
+ 6. Prefer \`${PACKAGE_NAME}/remote\` for extension UI code.
112
+ 7. Do not import from package-internal files such as \`dist/*\`, repository-only paths, or source internals.
113
+
114
+ ## Suggested Reading Order
115
+
116
+ 1. \`docs/AI.md\`
117
+ 2. \`docs/COMPONENTS.md\`
118
+ 3. The relevant profile from \`docs/profiles/*.yml\`
119
+ 4. \`docs/FORMAT.md\` if you need to understand profile structure
120
+ 5. Storybook and public types only when no profile exists yet
121
+ `
122
+ }
123
+
124
+ const hasPackageSection = (content) => content.includes(AGENTS_SECTION_HEADER)
125
+
126
+ const appendSection = (content, section) => {
127
+ const trimmed = content.replace(/\s+$/u, '')
128
+
129
+ if (!trimmed.length) {
130
+ return `${section}${DEFAULT_NEWLINE}`
131
+ }
132
+
133
+ return `${trimmed}${DEFAULT_NEWLINE}${DEFAULT_NEWLINE}${section}${DEFAULT_NEWLINE}`
134
+ }
135
+
136
+ const replaceSection = (content, section) => {
137
+ const escapedHeader = AGENTS_SECTION_HEADER.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
138
+ const sectionPattern = new RegExp(`${escapedHeader}[\\s\\S]*?(?=\\n##\\s|$)`, 'u')
139
+
140
+ if (!sectionPattern.test(content)) {
141
+ return appendSection(content, section)
142
+ }
143
+
144
+ return content
145
+ .replace(sectionPattern, section.trimEnd())
146
+ .replace(/\s+$/u, '') + DEFAULT_NEWLINE
147
+ }
148
+
149
+ const initAgents = (target, force) => {
150
+ if (!fs.existsSync(target)) {
151
+ throw new Error(`Target path does not exist: ${target}`)
152
+ }
153
+
154
+ const stat = fs.statSync(target)
155
+
156
+ if (!stat.isDirectory()) {
157
+ throw new Error(`Target path is not a directory: ${target}`)
158
+ }
159
+
160
+ const agentsPath = path.join(target, 'AGENTS.md')
161
+ const section = createAgentsSection()
162
+
163
+ if (!fs.existsSync(agentsPath)) {
164
+ fs.writeFileSync(agentsPath, createAgentsTemplate(), 'utf8')
165
+
166
+ console.log(`AGENTS.md was created at ${agentsPath}`)
167
+ console.log('Next step: review it and adjust project-specific rules if needed.')
168
+ return
169
+ }
170
+
171
+ const currentContent = fs.readFileSync(agentsPath, 'utf8')
172
+
173
+ if (force) {
174
+ fs.writeFileSync(agentsPath, replaceSection(currentContent, section), 'utf8')
175
+ console.log(`AGENTS.md was updated at ${agentsPath}`)
176
+ console.log(`The ${PACKAGE_NAME} section was refreshed.`)
177
+ return
178
+ }
179
+
180
+ if (hasPackageSection(currentContent)) {
181
+ console.log(`AGENTS.md already contains a ${PACKAGE_NAME} section at ${agentsPath}`)
182
+ console.log('Nothing was changed. Re-run with --force to refresh that section.')
183
+ return
184
+ }
185
+
186
+ fs.writeFileSync(agentsPath, appendSection(currentContent, section), 'utf8')
187
+
188
+ console.log(`AGENTS.md was updated at ${agentsPath}`)
189
+ console.log(`The ${PACKAGE_NAME} instructions were appended to the end of the file.`)
190
+ }
191
+
192
+ const main = () => {
193
+ try {
194
+ const options = parseArgs(process.argv.slice(2))
195
+
196
+ if (options.command !== 'init-agents') {
197
+ throw new Error(`Unknown command: ${options.command}`)
198
+ }
199
+
200
+ initAgents(options.target, options.force)
201
+ } catch (error) {
202
+ console.error(error instanceof Error ? error.message : String(error))
203
+ console.error('')
204
+ console.error(HELP_TEXT)
205
+ process.exit(1)
206
+ }
207
+ }
208
+
209
+ main()
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { fileURLToPath } from 'node:url'
4
+ import fs from 'node:fs'
5
+ import path from 'node:path'
6
+ import process from 'node:process'
7
+
8
+ const PACKAGE_NAME = '@retailcrm/embed-ui-v1-components'
9
+
10
+ const currentFile = fileURLToPath(import.meta.url)
11
+ const packageRoot = path.resolve(path.dirname(currentFile), '..')
12
+
13
+ const isInstalledFromNodeModules = packageRoot.includes(`${path.sep}node_modules${path.sep}`)
14
+
15
+ if (!isInstalledFromNodeModules) {
16
+ process.exit(0)
17
+ }
18
+
19
+ const targetRoot = process.env.INIT_CWD
20
+
21
+ if (!targetRoot) {
22
+ process.exit(0)
23
+ }
24
+
25
+ const agentsPath = path.join(targetRoot, 'AGENTS.md')
26
+ const hasAgentsFile = fs.existsSync(agentsPath)
27
+
28
+ console.log('')
29
+ console.log(`[${PACKAGE_NAME}] AI docs are available in node_modules/${PACKAGE_NAME}/docs`)
30
+ console.log(`[${PACKAGE_NAME}] Start with docs/AI.md, docs/COMPONENTS.md, and docs/profiles/*.yml`)
31
+
32
+ if (!hasAgentsFile) {
33
+ console.log(`[${PACKAGE_NAME}] To scaffold AGENTS.md for this project, run:`)
34
+ console.log(` npx ${PACKAGE_NAME} init-agents`)
35
+ } else {
36
+ console.log(`[${PACKAGE_NAME}] AGENTS.md already exists in this project, so no scaffold was created automatically`)
37
+ }