@brandup/ui-kit 1.0.26 → 1.0.28

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
@@ -1,200 +1,179 @@
1
- # brandup-ui-kit
1
+ # @brandup/ui-kit
2
2
 
3
- ## Installation and use
3
+ [![Build Status](https://dev.azure.com/brandup/BrandUp%20Core/_apis/build/status%2FBrandUp%2Fbrandup-ui-kit?branchName=main)](https://dev.azure.com/brandup/BrandUp%20Core/_build/latest?definitionId=81&branchName=main)
4
4
 
5
- Install NPM package [@brandup/ui-kit](https://www.npmjs.com/package/@brandup/ui-kit).
5
+ Базовый пакет UI-кита: сброс стилей, типографика, стили полей ввода, PopupManager и middleware для `@brandup/ui-app`.
6
+
7
+ ## Установка
6
8
 
7
9
  ```
8
- npm i @brandup/ui-kit@latest
10
+ npm i @brandup/ui-kit
9
11
  ```
10
12
 
11
- Add `@brandup/ui-kit` middleware to your application.
13
+ ## Подключение middleware
14
+
15
+ Зарегистрируйте `uiKitMiddlewareFactory` в сборщике приложения. Middleware автоматически регистрирует команду `ui-popup-toggle` для управления попапами.
12
16
 
13
- ```TypeScript
17
+ ```typescript
14
18
  import { ApplicationBuilder } from "@brandup/ui-app";
15
19
  import { uiKitMiddlewareFactory } from "@brandup/ui-kit";
16
20
 
17
21
  const builder = new ApplicationBuilder({});
18
- builder
19
- .useMiddleware(uiKitMiddlewareFactory)
20
- .useMiddleware(... other middleware);
22
+ builder.useMiddleware(uiKitMiddlewareFactory);
21
23
 
22
24
  const app = builder.build({ basePath: "/" });
23
-
24
25
  app.run();
25
26
  ```
26
27
 
27
- ## Styles
28
-
29
- ### Reset styles
30
-
31
- Reset styles for `<ul>`, `<ol>`, `<menu>`, `<img>` and others.
32
-
33
- See [reset.less](source/reset.less) file.
34
-
35
- ### Body styles
36
-
37
- Default root styles for `<body>` tag.
28
+ ## PopupManager
38
29
 
39
- ```
40
- --main-background
41
- --font-size
42
- --font-family
43
- --font-weight
44
- --line-height
45
- --text-color
46
- ```
30
+ Статический менеджер для управления всплывающими панелями. В каждый момент времени открыт не более одного попапа.
47
31
 
48
- See [common.less](source/common.less) file.
32
+ ### Разметка
49
33
 
50
- ### Header styles
51
-
52
- Default root styles for `<h1>`, `<h2>`, `<h3>`, `<h4>`, `<h5>`.
34
+ Добавьте CSS-класс `ui-popup` на элемент попапа.
53
35
 
36
+ ```html
37
+ <!-- Кнопка-инициатор рядом с попапом — команда ui-popup-toggle регистрируется middleware -->
38
+ <button data-command="ui-popup-toggle">Меню</button>
39
+ <div class="ui-popup">...</div>
54
40
  ```
55
- --h-line-height
56
-
57
- --h1-font-size
58
- --h1-font-weidth
59
41
 
60
- --h2-font-size
61
- --h2-font-weidth
62
-
63
- --h3-font-size
64
- --h3-font-weidth
65
-
66
- --h4-font-size
67
- --h4-font-weidth
68
-
69
- --h5-font-size
70
- --h5-font-weidth
71
- ```
42
+ ### API
72
43
 
73
- See [common.less](source/common.less) file.
44
+ ```typescript
45
+ import { PopupManager } from "@brandup/ui-kit";
74
46
 
75
- ### SVG styles
47
+ // Открыть попап (закрывает предыдущий, если был открыт другой)
48
+ PopupManager.open(popupElem, {
49
+ initiator: buttonElem, // необязательно: повторный клик по initiator закроет попап
50
+ onClose: () => { }, // необязательно: callback при закрытии
51
+ });
76
52
 
77
- Default root styles for `<svg>` tag.
53
+ // Закрыть текущий попап
54
+ PopupManager.close();
78
55
 
56
+ // Проверить, открыт ли какой-либо попап
57
+ PopupManager.isOpened(); // boolean
79
58
  ```
80
- --svg-size: 20px;
81
- --svg-fill: var(--text-color);
82
- --svg-stroke: none;
83
- ```
84
-
85
- See [common.less](source/common.less) file.
86
59
 
87
- ### Content width
60
+ ## Утилиты
88
61
 
89
- Add `content-width` class.
62
+ ```typescript
63
+ import { IS_TOUCH_DEVICE } from "@brandup/ui-kit";
90
64
 
65
+ // true на touch-устройствах (мобильные, планшеты)
66
+ if (IS_TOUCH_DEVICE) { ... }
91
67
  ```
92
- --content-max-width
93
- --content-min-width
94
- --content-padding-lr
95
- ```
96
-
97
- See [common.less](source/common.less) file.
98
68
 
99
- ### Input styles
69
+ ## Стили
100
70
 
101
- Styles for:
71
+ Подключите стили через импорт в точке входа — они включаются автоматически вместе с пакетом.
102
72
 
103
- - reset for input, textarea, button
104
- - input[type=text]
105
- - input[type=tel]
106
- - input[type=email]
107
- - input[type=password]
108
- - input[type=search]
109
- - input[type=url]
110
- - input[type=date]
111
- - input[type=datetime]
112
- - input[type=datetime-local]
113
- - input[type=time]
114
- - input[type=file]
115
- - input[type=number]
116
- - input[type=checkbox]
117
- - textarea
118
- - select
73
+ ### Переменные Less
119
74
 
120
- See [inputs.less](source/inputs.less) file.
75
+ Переопределите значения в файле `uikit.vars.less` в корне проекта перед сборкой. Файл с переменными по умолчанию: [vars.less](vars.less).
121
76
 
122
- ### Popups
77
+ **Адаптивные брейкпоинты:**
123
78
 
124
- Popups work with class `ui-popup`.
125
-
126
- ```HTML
127
- <button data-command="ui-popup-toggle">Menu1</button>
128
- <div class="ui-popup"></div>
79
+ ```less
80
+ @adaptive-desktop-small: 1650px;
81
+ @adaptive-notebook: 1550px;
82
+ @adaptive-notebook-small: 1370px;
83
+ @adaptive-tablet: 1030px;
84
+ @adaptive-tablet-small: 850px;
85
+ @adaptive-mobile: 500px;
86
+ @adaptive-mobile-small: 370px;
87
+ ```
129
88
 
130
- <button id="menu2">Menu2</button>
131
- <div id="popup2" class="ui-popup"></div>
89
+ **Общие:**
132
90
 
133
- <button>Menu3</button>
134
- <div id="popup2" class="ui-popup"></div>
91
+ ```less
92
+ @main-background: #fff;
93
+ @font-size: 14px;
94
+ @font-family: system-ui, ...;
95
+ @font-weight: 400;
96
+ @line-height: 130%;
97
+ @text-color: #222;
135
98
  ```
136
99
 
137
- Open popup by popup and initiator element:
100
+ **Заголовки (`h1`–`h5`):**
138
101
 
139
- ```TypeScript
140
- PopupManager.open(DOM.getById("popup2"), { initiator: DOM.getById("menu2") });
102
+ ```less
103
+ @h-line-height: 130%;
104
+ @h1-font-size: 56px; @h1-font-weight: 600;
105
+ @h2-font-size: 50px; @h2-font-weight: 600;
106
+ @h3-font-size: 28px; @h3-font-weight: 600;
107
+ @h4-font-size: 22px; @h4-font-weight: 600;
108
+ @h5-font-size: 18px; @h5-font-weight: 600;
141
109
  ```
142
110
 
143
- Open popup by only popup element:
111
+ **SVG:**
144
112
 
145
- ```TypeScript
146
- PopupManager.open(DOM.getById("popup3"));
113
+ ```less
114
+ @svg-size: 20px;
115
+ @svg-fill: @text-color;
116
+ @svg-stroke: none;
147
117
  ```
148
118
 
149
- If the initiator is specified, then when the popup is opened again, it will be closed.
119
+ **Блок контента (класс `content-width`):**
150
120
 
151
- ### Style variables
152
-
153
- Сreate uikit.vars.less in the root of the project.
121
+ ```less
122
+ @content-max-width: 1280px;
123
+ @content-min-width: 320px;
124
+ @content-padding-lr: 40px;
125
+ ```
154
126
 
155
- Connecting script to webpack:
127
+ **Попапы:**
156
128
 
157
- ```JS
158
- const parseLessVars = require("@brandup/ui-kit/build/parse-less-vars.cjs");
129
+ ```less
130
+ @popup-fill: @main-background;
131
+ @popup-color: @text-color;
132
+ @popup-border-radius: 5px;
133
+ @popup-box-shadow: 0px 4px 8px 2px rgba(0,0,0,0.12);
159
134
  ```
160
135
 
161
- Getting variables from a Less file.
136
+ **Поля ввода:**
162
137
 
163
- The function takes the path to the Less file (string) and returns an object with variables in the format:
138
+ ```less
139
+ @input-height: 46px;
140
+ @input-padding-lr: 20px;
141
+ @input-fill: #fff;
142
+ @input-color: @text-color;
143
+ @input-font-size: 14px;
164
144
 
165
- The key is the name of a variable with the @ symbol (for example, @MainColor).
166
- Value — a string with the value of a variable from a file (for example, #ff0000).
145
+ // Состояния: hover, focus, readonly, disabled, invalid, incorrect
146
+ @hover--input-border-color: #666;
147
+ @focus--input-border-color: #222;
148
+ @readonly--input-fill: #f7f7f7;
149
+ @disabled--input-fill: #eee;
150
+ @invalid--input-border-color: red;
151
+ ```
167
152
 
168
- Example of a Less file:
153
+ ### parseLessVars
169
154
 
170
- ```Less
171
- @main-color: #ff0000;
172
- @secondary-color: rgba(0, 0, 0, 0.5);
173
- @font-size: 16px;
174
- ```
155
+ Утилита для чтения Less-переменных в конфигурации webpack.
175
156
 
176
- Result of parseLessVars:
157
+ ```js
158
+ const parseLessVars = require("@brandup/ui-kit/build/parse-less-vars.cjs");
177
159
 
178
- ```JS
179
- {
180
- '@main-color': '#ff0000',
181
- '@secondary-color': 'rgba(0,0,0,0.5)',
182
- '@font-size': '16px'
183
- }
184
- ```
160
+ // Читает uikit.vars.less из корня проекта
161
+ const vars = parseLessVars();
185
162
 
186
- ```JS
187
- const variables = parseLessVars('path/to/your/variables.less');
163
+ // Или явно указать путь к файлу
164
+ const vars = parseLessVars("path/to/variables.less");
165
+ // { '@main-color': '#ff0000', '@font-size': '16px', ... }
188
166
  ```
189
167
 
190
- if no parameter has been set, the function will refer to the uikit.vars.less into root directory.
191
-
192
- Usage in the less-loader configuration.
168
+ Использование в конфигурации `less-loader`:
193
169
 
194
- ```JS
170
+ ```js
195
171
  {
196
- lessOption: {
197
- modifyVars: parseLessVars()
198
- }
172
+ loader: "less-loader",
173
+ options: {
174
+ lessOptions: {
175
+ modifyVars: parseLessVars(),
176
+ },
177
+ },
199
178
  }
200
179
  ```
@@ -1,18 +1,17 @@
1
1
  const fs = require("fs");
2
2
 
3
3
  function parseLessVars(filePath) {
4
- filePath = filePath ?? 'uikit.vars.less';
5
- if (!fs.existsSync(filePath))
6
- throw new Error("Not found UI kit configuration file uikit.vars.less.");
4
+ filePath = filePath ?? "uikit.vars.less";
5
+ if (!fs.existsSync(filePath)) throw new Error("Not found UI kit configuration file uikit.vars.less.");
7
6
 
8
- const content = fs.readFileSync(filePath, 'utf-8');
7
+ const content = fs.readFileSync(filePath, "utf-8");
9
8
 
10
9
  let variables = {};
11
10
 
12
- content.split('\n').forEach(line => {
11
+ content.split("\n").forEach((line) => {
13
12
  const match = line.match(/@([\w-]+)\s*:\s*(.+);/);
14
13
  if (match) variables[`@${match[1]}`] = match[2].trim();
15
14
  });
16
15
  return variables;
17
16
  }
18
- module.exports = parseLessVars;
17
+ module.exports = parseLessVars;
package/package.json CHANGED
@@ -22,11 +22,11 @@
22
22
  },
23
23
  "type": "module",
24
24
  "license": "Apache-2.0",
25
- "version": "1.0.26",
25
+ "version": "1.0.28",
26
26
  "main": "source/index.ts",
27
27
  "types": "source/index.ts",
28
28
  "dependencies": {
29
- "@brandup/ui-app": "^1.0.44"
29
+ "@brandup/ui-app": "^2.0.2"
30
30
  },
31
31
  "files": [
32
32
  "source",
package/source/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { UiKitMiddleware } from "./middleware";
2
- export * from "./popup"
2
+ export * from "./popup";
3
3
  export { IS_TOUCH_DEVICE } from "./utils/compatibility";
4
4
  import "./styles.less";
5
5
 
6
- export const uiKitMiddlewareFactory = () => new UiKitMiddleware();
6
+ export const uiKitMiddlewareFactory = () => new UiKitMiddleware();
@@ -5,9 +5,9 @@ export class UiKitMiddleware implements Middleware {
5
5
  name = "uikit";
6
6
 
7
7
  start(context: StartContext, next: MiddlewareNext) {
8
- context.app.registerCommand(POPUP_COMMAND, context => {
8
+ context.app.registerCommand(POPUP_COMMAND, (context) => {
9
9
  if (!context.target.nextElementSibling?.classList.contains(POPUP_CLASS))
10
- throw new Error('Not found popup elem.');
10
+ throw new Error("Not found popup elem.");
11
11
 
12
12
  PopupManager.open(context.target.nextElementSibling as HTMLElement, { initiator: context.target });
13
13
  });
@@ -20,4 +20,4 @@ export class UiKitMiddleware implements Middleware {
20
20
 
21
21
  return next();
22
22
  }
23
- }
23
+ }
package/source/popup.ts CHANGED
@@ -3,17 +3,16 @@ export const POPUP_EXPANDED_CLASS = "ui-popup-expanded";
3
3
  export const POPUP_COMMAND = "ui-popup-toggle";
4
4
 
5
5
  type CurrentPopup = {
6
- initiator?: HTMLElement,
7
- popup: HTMLElement,
8
- closeCallback?: () => void
6
+ initiator?: HTMLElement;
7
+ popup: HTMLElement;
8
+ closeCallback?: () => void;
9
9
  };
10
10
 
11
- var current: CurrentPopup | null = null;
11
+ let current: CurrentPopup | null = null;
12
12
 
13
13
  const closePopupEventHandler = (e: MouseEvent) => {
14
14
  const target = e.target as HTMLElement;
15
- if (target.closest(`.${POPUP_CLASS}`))
16
- return; // если клик внутри popup, то делать ничего не нужно
15
+ if (target.closest(`.${POPUP_CLASS}`)) return; // если клик внутри popup, то делать ничего не нужно
17
16
 
18
17
  const clickedMenuItem = target.closest(`.${POPUP_EXPANDED_CLASS}`);
19
18
  const isInitiator = target == current?.initiator;
@@ -30,8 +29,7 @@ const closePopupEventHandler = (e: MouseEvent) => {
30
29
 
31
30
  const close = () => {
32
31
  if (current) {
33
- if (current.closeCallback)
34
- current.closeCallback();
32
+ if (current.closeCallback) current.closeCallback();
35
33
 
36
34
  current.initiator?.classList.remove(POPUP_EXPANDED_CLASS); // закрываем последнее открытое контекстное меню
37
35
  current.popup.classList.remove("opened");
@@ -40,12 +38,14 @@ const close = () => {
40
38
  }
41
39
 
42
40
  document.body.removeEventListener("click", closePopupEventHandler);
43
- }
41
+ };
44
42
 
45
43
  const open = (popupElem: HTMLElement, options?: PopupOptions) => {
46
- let newPopup: CurrentPopup = {
44
+ if (current && current.popup !== popupElem) close(); // если открыт другой popup, закрываем его, чтобы не оставлять «осиротевший» visible popup
45
+
46
+ const newPopup: CurrentPopup = {
47
47
  popup: popupElem,
48
- initiator: options?.initiator
48
+ initiator: options?.initiator,
49
49
  };
50
50
 
51
51
  newPopup.closeCallback = options?.onClose;
@@ -58,17 +58,16 @@ const open = (popupElem: HTMLElement, options?: PopupOptions) => {
58
58
  document.body.addEventListener("click", closePopupEventHandler);
59
59
 
60
60
  current = newPopup;
61
- }
62
- else {
61
+ } else {
63
62
  // данный popup уже открыт, закрываем его
64
63
  close();
65
64
  }
66
- }
65
+ };
67
66
 
68
67
  export const PopupManager: IPopupManager = {
69
68
  open,
70
69
  close,
71
- isOpened: () => !!current
70
+ isOpened: () => !!current,
72
71
  };
73
72
 
74
73
  interface IPopupManager {
@@ -79,5 +78,5 @@ interface IPopupManager {
79
78
 
80
79
  interface PopupOptions {
81
80
  initiator?: HTMLElement;
82
- onClose?: () => void
83
- }
81
+ onClose?: () => void;
82
+ }
@@ -1 +1,3 @@
1
- export const IS_TOUCH_DEVICE = window.document.documentElement ? "ontouchstart" in window.document.documentElement : false;
1
+ export const IS_TOUCH_DEVICE = window.document.documentElement
2
+ ? "ontouchstart" in window.document.documentElement
3
+ : false;