@retailcrm/embed-ui-v1-components 0.9.7 → 0.9.8

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/dist/remote.cjs CHANGED
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const vue = require("vue");
4
4
  require("@remote-ui/rpc");
5
+ const isEqual = require("lodash.isequal");
5
6
  const imagePreview = require("@retailcrm/image-preview");
6
7
  const dateFns = require("date-fns");
7
8
  const REMOTE_SLOT = "RemoteSlot";
@@ -173,6 +174,14 @@ const UiTag = defineRemoteComponent(
173
174
  UiTagType,
174
175
  ["click", "focus", "blur", "remove"]
175
176
  );
177
+ var SIZE$1 = /* @__PURE__ */ ((SIZE2) => {
178
+ SIZE2["XS"] = "xs";
179
+ SIZE2["SM"] = "sm";
180
+ SIZE2["MD"] = "md";
181
+ SIZE2["LG"] = "lg";
182
+ SIZE2["XL"] = "xl";
183
+ return SIZE2;
184
+ })(SIZE$1 || {});
176
185
  const events = [
177
186
  "input",
178
187
  "keydown",
@@ -211,6 +220,850 @@ const UiYandexMap = defineRemoteComponent(
211
220
  "update:address"
212
221
  ]
213
222
  );
223
+ const UiMenuItemType = "UiMenuItem";
224
+ const UiMenuItem = defineRemoteComponent(
225
+ UiMenuItemType,
226
+ [],
227
+ [
228
+ "default",
229
+ "avatar",
230
+ "leading-icon",
231
+ "description",
232
+ "trailing-icon"
233
+ ]
234
+ );
235
+ const UiMenuItemGroupType = "UiMenuItemGroup";
236
+ const UiMenuItemGroup = defineRemoteComponent(
237
+ UiMenuItemGroupType,
238
+ [],
239
+ [
240
+ "default",
241
+ "option",
242
+ "label",
243
+ "quantity"
244
+ ]
245
+ );
246
+ const UiSelectTriggerType = "UiSelectTrigger";
247
+ const UiSelectTrigger = defineRemoteComponent(
248
+ UiSelectTriggerType,
249
+ [
250
+ "input",
251
+ "focus",
252
+ "blur",
253
+ "clear",
254
+ "update:value",
255
+ "update:expanded"
256
+ ]
257
+ );
258
+ const UiSelectPopperType = "UiSelectPopper";
259
+ const UiSelectPopper = defineRemoteComponent(
260
+ UiSelectPopperType,
261
+ [
262
+ "update:visible",
263
+ "show",
264
+ "hide",
265
+ "shown",
266
+ "hidden",
267
+ "dispose"
268
+ ]
269
+ );
270
+ const UiSelectOptionType = "UiSelectOption";
271
+ defineRemoteComponent(
272
+ UiSelectOptionType
273
+ );
274
+ const pluralization_en_GB = (choice) => choice === 1 ? 0 : 1;
275
+ const pluralization_es_ES = (choice) => choice === 1 ? 0 : 1;
276
+ const pluralization_ru_RU = (choice, choicesLength) => {
277
+ if (choicesLength === 2) {
278
+ return choice === 1 ? 0 : 1;
279
+ }
280
+ const mod100 = choice % 100;
281
+ return mod100 % 10 === 1 && mod100 !== 11 ? 0 : mod100 % 10 >= 2 && mod100 % 10 <= 4 && !(mod100 >= 10 && mod100 < 15) ? 1 : 2;
282
+ };
283
+ const get = (messages, path) => {
284
+ let i = 0;
285
+ let slice = messages[path[0]];
286
+ while (i < path.length) {
287
+ if (typeof slice === "string" && i + 1 === path.length) {
288
+ return slice;
289
+ }
290
+ if (typeof slice !== "object") {
291
+ return void 0;
292
+ }
293
+ slice = slice[path[++i]];
294
+ }
295
+ return slice;
296
+ };
297
+ const replace = (message, values) => {
298
+ return Object.keys(values).reduce((message2, key) => {
299
+ const pattern = new RegExp(`\\{${key}\\}`, "g");
300
+ const replacement = String(values[key]);
301
+ return message2.replace(pattern, replacement);
302
+ }, message);
303
+ };
304
+ const compile = (messages, path, values = void 0) => {
305
+ const message = get(messages, path);
306
+ if (typeof message === "string" && values) {
307
+ return replace(message, values);
308
+ }
309
+ return message;
310
+ };
311
+ const fail = (message) => {
312
+ throw new Error(message);
313
+ };
314
+ const t = (locale, messages, path, values = void 0) => {
315
+ const keys = path.split(".");
316
+ if (locale) {
317
+ const message = compile(messages[locale] ?? {}, keys, values);
318
+ return typeof message !== "object" ? message : fail(`Translation for "${locale}:${path}" is not translatable`);
319
+ }
320
+ return void 0;
321
+ };
322
+ const plural = (template, choice, rule) => {
323
+ const forms = template.split("|");
324
+ return forms[rule(choice, forms.length)];
325
+ };
326
+ class I18n {
327
+ parent;
328
+ messages;
329
+ computed;
330
+ pluralization;
331
+ fallback;
332
+ constructor(options = void 0, parent = void 0) {
333
+ this.parent = parent;
334
+ this.messages = options?.messages ?? {};
335
+ this.computed = options?.computed ?? {};
336
+ this.pluralization = {
337
+ "en-GB": pluralization_en_GB,
338
+ "es-ES": pluralization_es_ES,
339
+ "ru-RU": pluralization_ru_RU,
340
+ ...options?.pluralization ?? {}
341
+ };
342
+ this.fallback = options?.fallback;
343
+ }
344
+ t(locale, path, values = void 0) {
345
+ try {
346
+ const _t = (locale2) => t(locale2, this.messages, path, values);
347
+ return _t(locale) ?? _t(this.fallback) ?? fail(`Translation for "${path}" does not exists`);
348
+ } catch (e) {
349
+ if (this.parent) {
350
+ return this.parent.t(locale, path, values);
351
+ }
352
+ throw e;
353
+ }
354
+ }
355
+ tc(locale, path, choice, values = void 0) {
356
+ return plural(
357
+ this.t(
358
+ locale,
359
+ path,
360
+ values
361
+ ),
362
+ choice,
363
+ this.pluralization[locale]
364
+ );
365
+ }
366
+ compute(locale, key, values) {
367
+ const computed = this.computed[key];
368
+ if (computed) {
369
+ return computed(localize$3(this, locale), values);
370
+ }
371
+ if (this.parent) {
372
+ return this.parent.compute(locale, key, values);
373
+ }
374
+ return fail("Key " + key + " is not registered");
375
+ }
376
+ extend(options) {
377
+ return new I18n({
378
+ pluralization: this.pluralization,
379
+ fallback: this.fallback,
380
+ ...options
381
+ }, this);
382
+ }
383
+ }
384
+ const localize$3 = (i18n, locale) => ({
385
+ t(path, values = void 0) {
386
+ return i18n.t(locale, path, values);
387
+ },
388
+ tc(path, choice, values = void 0) {
389
+ return i18n.tc(locale, path, choice, values);
390
+ },
391
+ compute(key, values) {
392
+ return i18n.compute(locale, key, values);
393
+ }
394
+ });
395
+ const fallback = "en-GB";
396
+ const define = (options = void 0, parent = void 0) => {
397
+ const i18n = new I18n({
398
+ ...options,
399
+ fallback
400
+ }, parent);
401
+ const extend = (i18n2, options2 = void 0) => options2 ? i18n2.extend(options2) : i18n2;
402
+ return {
403
+ i18n,
404
+ init: (locale, options2 = void 0) => localize$3(
405
+ extend(i18n, options2),
406
+ locale
407
+ ),
408
+ fallback
409
+ };
410
+ };
411
+ const selected$2 = "Selected";
412
+ const search$2 = { "placeholder": "", "noResult": "Nothing found" };
413
+ const messages_en_GB = {
414
+ selected: selected$2,
415
+ search: search$2
416
+ };
417
+ const selected$1 = "Seleccionado";
418
+ const search$1 = { "placeholder": "", "noResult": "No se ha encontrado" };
419
+ const messages_es_ES = {
420
+ selected: selected$1,
421
+ search: search$1
422
+ };
423
+ const selected = "Выбрано";
424
+ const search = { "placeholder": "", "noResult": "Ничего не найдено" };
425
+ const messages_ru_RU = {
426
+ selected,
427
+ search
428
+ };
429
+ const _18n = define({
430
+ messages: {
431
+ "en-GB": messages_en_GB,
432
+ "es-ES": messages_es_ES,
433
+ "ru-RU": messages_ru_RU
434
+ }
435
+ });
436
+ var PLACEMENT = /* @__PURE__ */ ((PLACEMENT2) => {
437
+ PLACEMENT2["TOP"] = "top";
438
+ PLACEMENT2["TOP_START"] = "top-start";
439
+ PLACEMENT2["TOP_END"] = "top-end";
440
+ PLACEMENT2["BOTTOM"] = "bottom";
441
+ PLACEMENT2["BOTTOM_START"] = "bottom-start";
442
+ PLACEMENT2["BOTTOM_END"] = "bottom-end";
443
+ PLACEMENT2["LEFT"] = "left";
444
+ PLACEMENT2["LEFT_START"] = "left-start";
445
+ return PLACEMENT2;
446
+ })(PLACEMENT || {});
447
+ const escapeSpecialSymbols = (text) => text.replace(
448
+ /([\\^$.*+?()[\]{}|=!<>:-])/g,
449
+ "\\$1"
450
+ );
451
+ const highlight = (text, term, style) => text.replace(
452
+ new RegExp(`(${escapeSpecialSymbols(term)})`, "gi"),
453
+ `<span style="${style}">$1</span>`
454
+ );
455
+ let counter = 0;
456
+ const uid = (prefix = "ui-v1-select") => `${prefix}-${++counter}`;
457
+ const IsSelectedKey = Symbol("UiSelectedIsSelected");
458
+ const RegisterKey = Symbol("UiSelectRegister");
459
+ const SyncKey = Symbol("UiSelectSync");
460
+ const UnregisterKey = Symbol("UiSelectUnregister");
461
+ const ToggleKey = Symbol("UiSelectToggle");
462
+ const FilterKey = Symbol("UiSelectFilter");
463
+ const FilteredKey = Symbol("UiSelectFiltered");
464
+ const TickerKey = Symbol("UiSelectTicker");
465
+ const MultipleKey = Symbol("UiSelectMultiple");
466
+ const FastenedKey = Symbol("UiSelectFastened");
467
+ const UnregisterOptionKey = Symbol("UiSelectUnregisterOption");
468
+ const RegisterOptionKey = Symbol("UiSelectRegisterOption");
469
+ const RegisterGroupKey = Symbol("UiSelectOptionGroupRegister");
470
+ const UnregisterGroupKey = Symbol("UiSelectOptionGroupUnregister");
471
+ const RegisterHeaderOptionKey = Symbol("UiSelectOptionGroupRegisterHeaderOption");
472
+ const UnregisterHeaderOptionKey = Symbol("UiSelectOptionGroupUnregisterHeaderOption");
473
+ const I18nInjectKey = Symbol("$embedI18n");
474
+ const _hoisted_1$3 = {
475
+ key: 0,
476
+ class: "ui-v1-select__no-results-text"
477
+ };
478
+ const _sfc_main$3 = /* @__PURE__ */ vue.defineComponent({
479
+ __name: "UiSelect",
480
+ props: {
481
+ /** Атрибут id корневого элемента выпадающего списка. Должен быть уникальным на странице */
482
+ id: {
483
+ type: String,
484
+ default: void 0
485
+ },
486
+ /** Атрибут value, содержащий выбранный элемент из выпадающего списка */
487
+ value: {
488
+ type: null,
489
+ default: void 0
490
+ },
491
+ /** Атрибут placeholder нативного поля ввода input */
492
+ placeholder: {
493
+ type: String,
494
+ default: "test"
495
+ },
496
+ /** Отображает иконку сброса введённого или выбранного значения в виде крестика */
497
+ clearable: {
498
+ type: Boolean,
499
+ default: false
500
+ },
501
+ /** Фильтрация строк выпадающего списка на соответствие введённого выражения в input */
502
+ filterable: {
503
+ type: Boolean,
504
+ default: false
505
+ },
506
+ /** Подсвечивает поле как содержащее некорректное значение */
507
+ invalid: {
508
+ type: Boolean,
509
+ default: false
510
+ },
511
+ /** Устанавливает поле ввода в состояние доступное только для чтения */
512
+ readonly: {
513
+ type: Boolean,
514
+ default: false
515
+ },
516
+ /** Блокировка поля ввода */
517
+ disabled: {
518
+ type: Boolean,
519
+ default: false
520
+ },
521
+ /** Функция для проверки равенства элементов */
522
+ equalsFn: {
523
+ type: Function,
524
+ default: (a, b) => a === b
525
+ },
526
+ /**
527
+ * Сторона цели, у которой появится плавающий элемент,
528
+ * или подробный объект настройки положения и адаптации положения при нехватке места
529
+ */
530
+ placement: {
531
+ type: String,
532
+ validator: (placement) => Object.values(PLACEMENT).includes(placement),
533
+ default: PLACEMENT.BOTTOM
534
+ },
535
+ /** События целевого элемента, по которым производится переключение видимости */
536
+ targetTriggers: {
537
+ type: [Array, Object],
538
+ default: () => ({
539
+ show: ["click"]
540
+ })
541
+ },
542
+ /** События плавающего элемента, по которым производится переключение видимости */
543
+ popperTriggers: {
544
+ type: [Array, Object],
545
+ default: () => []
546
+ },
547
+ /**
548
+ * Флаг, устанавливающий ширину выпадающего списка по ширине целевого элемента.
549
+ * По-умолчанию отключает такое поведение
550
+ */
551
+ popperFitTrigger: {
552
+ type: Boolean,
553
+ default: false
554
+ },
555
+ /** Стиль для плавающего элемента */
556
+ popperClass: {
557
+ type: String,
558
+ default: null
559
+ },
560
+ /** Набор свойств плавающего элемента. See @/common/components/popper */
561
+ popperOptions: {
562
+ type: Object,
563
+ default: () => ({})
564
+ },
565
+ /** Размер поля ввода */
566
+ textboxSize: {
567
+ type: String,
568
+ validator: (size) => Object.values(SIZE$1).includes(size),
569
+ default: SIZE$1.SM
570
+ },
571
+ /** Наличие множественного выбора среди элементов выпадающего списка */
572
+ multiple: {
573
+ type: Boolean,
574
+ default: false
575
+ },
576
+ /** Состояние открытия выпадающего списка */
577
+ expanded: {
578
+ type: Boolean,
579
+ default: false
580
+ },
581
+ /** Устанавливает в качестве выводимого в input значения только содержимое placeholder */
582
+ placeholderOnly: {
583
+ type: Boolean,
584
+ default: false
585
+ },
586
+ /** Добавляет анимацию показала полной строки при переполнении */
587
+ ticker: {
588
+ type: Boolean,
589
+ default: false
590
+ }
591
+ },
592
+ setup(__props) {
593
+ const props = __props;
594
+ const state = vue.reactive({
595
+ expanded: props.expanded,
596
+ filter: "",
597
+ value: props.value
598
+ });
599
+ const i18n = vue.computed(() => _18n.init(vue.inject(I18nInjectKey, null)?.locale ?? _18n.fallback));
600
+ const noResult = vue.computed(() => i18n.value.t("search.noResult", { filter: state.filter }));
601
+ const optionsRegistry = vue.ref([]);
602
+ const selection = vue.computed(() => {
603
+ const model = arraify(state.value);
604
+ const selectedOptions = [];
605
+ model.forEach((item) => {
606
+ const option = optionsRegistry.value.find((o) => equals(o.value, item));
607
+ if (option) {
608
+ selectedOptions.push(option);
609
+ }
610
+ });
611
+ return selectedOptions;
612
+ });
613
+ const arraify = (value) => Array.isArray(value) ? [...value] : typeof value === "number" || typeof value === "boolean" || value ? [value] : [];
614
+ const equals = (a, b) => props.equalsFn(a, b);
615
+ const contains = (array, value) => array.some((v) => equals(v, value));
616
+ vue.provide(RegisterKey, (option) => {
617
+ if (optionsRegistry.value.some((item) => item.id === option.id)) {
618
+ throw new Error(`[UiSelect] Component with id ${option.id} already registered. Unregister it before using again.`);
619
+ }
620
+ optionsRegistry.value.push(option);
621
+ });
622
+ vue.provide(SyncKey, (id, data) => {
623
+ const option = optionsRegistry.value.find((option2) => option2.id === id);
624
+ if (option) {
625
+ option.label = data.label;
626
+ option.value = data.value;
627
+ }
628
+ });
629
+ vue.provide(UnregisterKey, (id) => {
630
+ const index = optionsRegistry.value.findIndex((option) => option.id === id);
631
+ if (index !== -1) {
632
+ optionsRegistry.value.splice(index, 1);
633
+ }
634
+ });
635
+ vue.provide(IsSelectedKey, vue.computed(() => (value) => {
636
+ return Array.isArray(state.value) ? contains(state.value, value) : equals(state.value, value);
637
+ }));
638
+ vue.provide(ToggleKey, (value) => {
639
+ if (props.multiple) {
640
+ const model = arraify(state.value);
641
+ const index = model.findIndex((item) => equals(item, value));
642
+ if (index !== -1) {
643
+ model.splice(index, 1);
644
+ } else {
645
+ model.push(value);
646
+ }
647
+ state.value = model;
648
+ if (!props.multiple) {
649
+ close();
650
+ }
651
+ } else {
652
+ state.value = value;
653
+ close();
654
+ }
655
+ });
656
+ vue.provide(FilterKey, vue.computed(() => state.filter));
657
+ vue.provide(FilteredKey, vue.computed(() => props.filterable && state.filter.length > 0));
658
+ vue.provide(TickerKey, vue.computed(() => props.ticker));
659
+ vue.provide(MultipleKey, vue.computed(() => props.multiple));
660
+ const onInput = (value) => {
661
+ state.filter = value;
662
+ };
663
+ const close = () => {
664
+ if (state.expanded) {
665
+ state.expanded = false;
666
+ state.filter = "";
667
+ }
668
+ };
669
+ vue.watch(() => props.expanded, (newVal) => {
670
+ state.expanded = newVal;
671
+ if (!newVal) {
672
+ state.filter = "";
673
+ }
674
+ });
675
+ vue.watch(() => props.value, (newVal) => {
676
+ state.value = newVal;
677
+ });
678
+ return (_ctx, _cache) => {
679
+ return vue.openBlock(), vue.createBlock(vue.unref(UiPopperConnector), null, {
680
+ default: vue.withCtx(() => [
681
+ vue.createVNode(vue.unref(UiSelectTrigger), {
682
+ id: __props.id,
683
+ value: state.value,
684
+ multiple: __props.multiple,
685
+ selection: selection.value,
686
+ filter: state.filter,
687
+ filterable: __props.filterable,
688
+ clearable: __props.clearable,
689
+ expanded: state.expanded,
690
+ invalid: __props.invalid,
691
+ disabled: __props.disabled,
692
+ readonly: __props.readonly,
693
+ "placeholder-only": __props.placeholderOnly,
694
+ placeholder: __props.placeholder,
695
+ "textbox-size": __props.textboxSize,
696
+ onInput,
697
+ "onUpdate:value": _cache[0] || (_cache[0] = ($event) => state.value = $event),
698
+ "onUpdate:expanded": _cache[1] || (_cache[1] = ($event) => state.expanded = $event)
699
+ }, null, 8, ["id", "value", "multiple", "selection", "filter", "filterable", "clearable", "expanded", "invalid", "disabled", "readonly", "placeholder-only", "placeholder", "textbox-size"]),
700
+ vue.createVNode(vue.unref(UiSelectPopper), {
701
+ id: __props.id,
702
+ disabled: __props.disabled || __props.readonly,
703
+ multiple: __props.multiple,
704
+ opened: state.expanded,
705
+ placement: __props.placement,
706
+ "popper-class": __props.popperClass,
707
+ "popper-fit-trigger": __props.popperFitTrigger,
708
+ "popper-options": __props.popperOptions,
709
+ "popper-triggers": __props.popperTriggers,
710
+ readonly: __props.readonly,
711
+ "target-triggers": __props.targetTriggers,
712
+ ticker: __props.ticker,
713
+ filterable: __props.filterable,
714
+ "options-registry": optionsRegistry.value,
715
+ onHide: close
716
+ }, {
717
+ default: vue.withCtx(() => [
718
+ __props.filterable && optionsRegistry.value.every((o) => !o.isMatched()) && noResult.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_1$3, vue.toDisplayString(noResult.value), 1)) : vue.createCommentVNode("", true),
719
+ vue.renderSlot(_ctx.$slots, "default")
720
+ ]),
721
+ _: 3
722
+ }, 8, ["id", "disabled", "multiple", "opened", "placement", "popper-class", "popper-fit-trigger", "popper-options", "popper-triggers", "readonly", "target-triggers", "ticker", "filterable", "options-registry"])
723
+ ]),
724
+ _: 3
725
+ });
726
+ };
727
+ }
728
+ });
729
+ const _hoisted_1$2 = {
730
+ xmlns: "http://www.w3.org/2000/svg",
731
+ viewBox: "0 0 24 24"
732
+ };
733
+ function render$1(_ctx, _cache) {
734
+ return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$2, [..._cache[0] || (_cache[0] = [
735
+ vue.createElementVNode("path", {
736
+ fill: "currentColor",
737
+ "fill-rule": "evenodd",
738
+ d: "M2 12C2 6.477 6.477 2 12 2A10 10 0 1 1 2 12m8.73 3.35 5.62-5.62a.5.5 0 0 0 0-.69l-.53-.53a.5.5 0 0 0-.7 0l-4.74 4.74-1.5-1.49a.48.48 0 0 0-.7 0l-.53.53a.5.5 0 0 0 0 .71l2.38 2.35a.48.48 0 0 0 .7 0",
739
+ "clip-rule": "evenodd"
740
+ }, null, -1)
741
+ ])]);
742
+ }
743
+ const IconCheckmarkCircle = { render: render$1 };
744
+ const _hoisted_1$1 = {
745
+ xmlns: "http://www.w3.org/2000/svg",
746
+ viewBox: "0 0 24 24"
747
+ };
748
+ function render(_ctx, _cache) {
749
+ return vue.openBlock(), vue.createElementBlock("svg", _hoisted_1$1, [..._cache[0] || (_cache[0] = [
750
+ vue.createElementVNode("path", {
751
+ fill: "currentColor",
752
+ "fill-rule": "evenodd",
753
+ d: "M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10A10 10 0 0 0 12 2m0 18a8 8 0 1 1 0-16 8 8 0 0 1 0 16m1-9h2.5a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5H13v2.5a.5.5 0 0 1-.5.5h-1a.5.5 0 0 1-.5-.5V13H8.5a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5H11V8.5a.5.5 0 0 1 .5-.5h1a.5.5 0 0 1 .5.5z",
754
+ "clip-rule": "evenodd"
755
+ }, null, -1)
756
+ ])]);
757
+ }
758
+ const IconAddCircleOutlined = { render };
759
+ var SIZE = /* @__PURE__ */ ((SIZE2) => {
760
+ SIZE2["XS"] = "xs";
761
+ SIZE2["SM"] = "sm";
762
+ SIZE2["MD"] = "md";
763
+ SIZE2["LG"] = "lg";
764
+ return SIZE2;
765
+ })(SIZE || {});
766
+ const _hoisted_1 = ["aria-selected"];
767
+ const _hoisted_2 = ["innerHTML"];
768
+ const _hoisted_3 = ["innerHTML"];
769
+ const _sfc_main$2 = /* @__PURE__ */ vue.defineComponent({
770
+ __name: "UiSelectOption",
771
+ props: {
772
+ /** Значение опции */
773
+ value: {
774
+ type: null,
775
+ required: true
776
+ },
777
+ /** Заголовок */
778
+ label: {
779
+ type: String,
780
+ required: true
781
+ },
782
+ /** Описание */
783
+ description: {
784
+ type: String,
785
+ default: ""
786
+ },
787
+ /** Опция выбрана/не выбрана в списке */
788
+ active: {
789
+ type: Boolean,
790
+ default: false
791
+ },
792
+ /** Заблокированный */
793
+ disabled: {
794
+ type: Boolean,
795
+ default: false
796
+ },
797
+ /** Размер шрифта, иконок и внутренних отступов компонента */
798
+ size: {
799
+ type: String,
800
+ validator: (size) => Object.values(SIZE).includes(size),
801
+ default: SIZE.MD
802
+ },
803
+ /** Счетчик количества */
804
+ counter: {
805
+ type: null,
806
+ validator: (counter2) => counter2 === null || ["string", "number"].includes(typeof counter2),
807
+ default: null
808
+ },
809
+ /** Жирное начертание текста */
810
+ accent: {
811
+ type: Boolean,
812
+ default: false
813
+ }
814
+ },
815
+ setup(__props) {
816
+ const props = __props;
817
+ const id = uid("u1-v1-select-option");
818
+ const isSelected = vue.inject(IsSelectedKey, vue.ref(() => false));
819
+ const syncInSelect = vue.inject(SyncKey, () => {
820
+ });
821
+ const registerInGroup = vue.inject(RegisterOptionKey, () => {
822
+ });
823
+ const registerInSelect = vue.inject(RegisterKey, () => {
824
+ });
825
+ const unregisterInGroup = vue.inject(UnregisterOptionKey, () => {
826
+ });
827
+ const unregisterInSelect = vue.inject(UnregisterKey, () => {
828
+ });
829
+ const toggle = vue.inject(ToggleKey, () => {
830
+ });
831
+ const fastened = vue.inject(FastenedKey, false);
832
+ const filter = vue.inject(FilterKey, vue.ref(""));
833
+ const filtered = vue.inject(FilteredKey, vue.ref(false));
834
+ const ticker = vue.inject(TickerKey, vue.ref(false));
835
+ const multiple = vue.inject(MultipleKey, vue.ref(false));
836
+ const highlight$1 = (text, style = "font-weight: 500;") => highlight(text, filter.value, style);
837
+ const texts = vue.computed(() => ({
838
+ label: filtered.value ? highlight$1(props.label) : props.label,
839
+ description: filtered.value ? highlight$1(props.description, "font-weight: 600;") : props.description
840
+ }));
841
+ const matched = vue.computed(() => texts.value.label !== props.label || texts.value.description !== props.description);
842
+ const selected2 = vue.computed(() => props.active || isSelected.value(props.value));
843
+ const hidden = vue.computed(() => !(fastened || !filtered.value || matched.value));
844
+ const onClick = () => {
845
+ if (!props.disabled) {
846
+ toggle(props.value);
847
+ }
848
+ };
849
+ const off = vue.watch([
850
+ () => props.label,
851
+ () => props.value
852
+ ], ([newLabel, newValue], [oldLabel, oldValue]) => {
853
+ if (newLabel !== oldLabel || !isEqual(newValue, oldValue)) {
854
+ syncInSelect(id, {
855
+ label: newLabel,
856
+ value: newValue
857
+ });
858
+ }
859
+ });
860
+ vue.onBeforeMount(() => {
861
+ const option = {
862
+ id,
863
+ value: props.value,
864
+ label: props.label,
865
+ isMatched: () => !filtered.value || matched.value
866
+ };
867
+ registerInSelect(option);
868
+ registerInGroup(option);
869
+ });
870
+ vue.onBeforeUnmount(() => {
871
+ off();
872
+ unregisterInSelect(id);
873
+ unregisterInGroup(id);
874
+ });
875
+ return (_ctx, _cache) => {
876
+ return vue.openBlock(), vue.createElementBlock("div", vue.mergeProps(_ctx.$attrs, {
877
+ "aria-selected": selected2.value ? "true" : "false",
878
+ class: {
879
+ "ui-v1-select-option": true,
880
+ "ui-v1-select-option_selected": selected2.value,
881
+ "ui-v1-select-option_disabled": __props.disabled,
882
+ "ui-v1-select-option_hidden": hidden.value
883
+ },
884
+ role: "option",
885
+ onClick
886
+ }), [
887
+ vue.renderSlot(_ctx.$slots, "default", {
888
+ highlight: highlight$1,
889
+ selected: selected2.value
890
+ }, () => [
891
+ vue.createVNode(vue.unref(UiMenuItem), {
892
+ accent: __props.accent,
893
+ counter: __props.counter,
894
+ disabled: __props.disabled,
895
+ size: __props.size,
896
+ ticker: vue.unref(ticker)
897
+ }, vue.createSlots({
898
+ "trailing-icon": vue.withCtx(() => [
899
+ vue.renderSlot(_ctx.$slots, "trailing-icon", { selected: selected2.value }, () => [
900
+ selected2.value ? (vue.openBlock(), vue.createBlock(vue.unref(IconCheckmarkCircle), {
901
+ key: 0,
902
+ class: "ui-v1-select-option__checkmark-icon",
903
+ "aria-hidden": "true"
904
+ })) : vue.unref(multiple) ? (vue.openBlock(), vue.createBlock(vue.unref(IconAddCircleOutlined), {
905
+ key: 1,
906
+ class: "ui-v1-select-option__add-icon",
907
+ "aria-hidden": "true"
908
+ })) : vue.createCommentVNode("", true)
909
+ ])
910
+ ]),
911
+ default: vue.withCtx(() => [
912
+ vue.renderSlot(_ctx.$slots, "value", { selected: selected2.value }, () => [
913
+ vue.createElementVNode("span", {
914
+ innerHTML: texts.value.label
915
+ }, null, 8, _hoisted_2)
916
+ ])
917
+ ]),
918
+ _: 2
919
+ }, [
920
+ _ctx.$slots["leading-icon"] ? {
921
+ name: "leading-icon",
922
+ fn: vue.withCtx(() => [
923
+ vue.renderSlot(_ctx.$slots, "leading-icon", { selected: selected2.value })
924
+ ]),
925
+ key: "0"
926
+ } : void 0,
927
+ texts.value.description ? {
928
+ name: "description",
929
+ fn: vue.withCtx(() => [
930
+ vue.createElementVNode("span", {
931
+ innerHTML: texts.value.description
932
+ }, null, 8, _hoisted_3)
933
+ ]),
934
+ key: "1"
935
+ } : void 0
936
+ ]), 1032, ["accent", "counter", "disabled", "size", "ticker"])
937
+ ])
938
+ ], 16, _hoisted_1);
939
+ };
940
+ }
941
+ });
942
+ const _sfc_main$1 = /* @__PURE__ */ vue.defineComponent({
943
+ __name: "UiSelectOptionGroupHeader",
944
+ setup(__props) {
945
+ vue.provide(RegisterOptionKey, vue.inject(RegisterHeaderOptionKey, () => {
946
+ }));
947
+ vue.provide(UnregisterOptionKey, vue.inject(UnregisterHeaderOptionKey, () => {
948
+ }));
949
+ vue.provide(FastenedKey, vue.computed(() => true));
950
+ return (_ctx, _cache) => {
951
+ return vue.openBlock(), vue.createElementBlock("div", null, [
952
+ vue.renderSlot(_ctx.$slots, "default")
953
+ ]);
954
+ };
955
+ }
956
+ });
957
+ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
958
+ __name: "UiSelectOptionGroup",
959
+ props: {
960
+ /** Заголовок группы опций */
961
+ label: {
962
+ type: String,
963
+ default: ""
964
+ }
965
+ },
966
+ setup(__props) {
967
+ const id = uid("u1-v1-select-option-group");
968
+ const options = vue.ref([]);
969
+ const groups = vue.ref([]);
970
+ const headerOptions = vue.ref([]);
971
+ const COMPONENT_ALREADY_REGISTERED = (prefix, id2) => {
972
+ return `[${prefix}] Component with id ${id2} already registered. Unregister it before using again.`;
973
+ };
974
+ vue.provide(RegisterOptionKey, (option) => {
975
+ if (options.value.some((item) => item.id === option.id)) {
976
+ throw new Error(COMPONENT_ALREADY_REGISTERED("UiSelect", option.id));
977
+ }
978
+ options.value.push(option);
979
+ });
980
+ vue.provide(UnregisterOptionKey, (id2) => {
981
+ const index = options.value.findIndex((option) => option.id === id2);
982
+ if (index !== -1) {
983
+ options.value.splice(index, 1);
984
+ }
985
+ });
986
+ vue.provide(RegisterGroupKey, (group) => {
987
+ if (groups.value.some((g) => g.id === group.id)) {
988
+ throw new Error(COMPONENT_ALREADY_REGISTERED("UiSelectOptionGroup", group.id));
989
+ }
990
+ groups.value.push(group);
991
+ });
992
+ vue.provide(UnregisterGroupKey, (id2) => {
993
+ const index = groups.value.findIndex((group) => group.id === id2);
994
+ if (index !== -1) {
995
+ groups.value.splice(index, 1);
996
+ }
997
+ });
998
+ vue.provide(RegisterHeaderOptionKey, (option) => {
999
+ if (headerOptions.value.some((item) => item.id === option.id)) {
1000
+ throw new Error(COMPONENT_ALREADY_REGISTERED("UiSelectOptionGroupHeader", option.id));
1001
+ }
1002
+ headerOptions.value.push(option);
1003
+ });
1004
+ vue.provide(UnregisterHeaderOptionKey, (id2) => {
1005
+ const index = headerOptions.value.findIndex((o) => o.id === id2);
1006
+ if (index !== -1) {
1007
+ headerOptions.value.splice(index, 1);
1008
+ }
1009
+ });
1010
+ vue.provide(FastenedKey, vue.computed(() => false));
1011
+ const registerInGroup = vue.inject(RegisterGroupKey, () => {
1012
+ });
1013
+ const unregisterInGroup = vue.inject(UnregisterGroupKey, () => {
1014
+ });
1015
+ const filtered = vue.inject(FilteredKey, vue.ref(false));
1016
+ const matchedOptionsQuantity = vue.computed(() => {
1017
+ return options.value.filter((o) => o.isMatched()).length + groups.value.reduce((total, g) => total + g.matchedQuantity(), 0);
1018
+ });
1019
+ const matched = vue.computed(() => !!matchedOptionsQuantity.value || headerOptions.value.some((o) => o.isMatched()) || groups.value.some((g) => g.isMatched()));
1020
+ const hidden = vue.computed(() => !filtered.value || matched.value);
1021
+ vue.onMounted(() => registerInGroup({
1022
+ id,
1023
+ matchedQuantity: () => matchedOptionsQuantity.value,
1024
+ isMatched: () => matched.value
1025
+ }));
1026
+ vue.onBeforeUnmount(() => unregisterInGroup(id));
1027
+ return (_ctx, _cache) => {
1028
+ return vue.openBlock(), vue.createElementBlock("div", vue.mergeProps(_ctx.$attrs, {
1029
+ class: {
1030
+ "ui-v1-select-option-group": true,
1031
+ "ui-v1-select-option-group_hidden": hidden.value
1032
+ }
1033
+ }), [
1034
+ vue.createVNode(vue.unref(UiMenuItemGroup), null, vue.createSlots({
1035
+ label: vue.withCtx(() => [
1036
+ vue.renderSlot(_ctx.$slots, "label", {}, () => [
1037
+ vue.createTextVNode(vue.toDisplayString(__props.label), 1)
1038
+ ])
1039
+ ]),
1040
+ quantity: vue.withCtx(() => [
1041
+ vue.renderSlot(_ctx.$slots, "quantity", { quantity: matchedOptionsQuantity.value }, () => [
1042
+ vue.createTextVNode(vue.toDisplayString(matchedOptionsQuantity.value), 1)
1043
+ ])
1044
+ ]),
1045
+ default: vue.withCtx(() => [
1046
+ vue.renderSlot(_ctx.$slots, "default")
1047
+ ]),
1048
+ _: 2
1049
+ }, [
1050
+ _ctx.$slots.option ? {
1051
+ name: "option",
1052
+ fn: vue.withCtx(() => [
1053
+ vue.createVNode(_sfc_main$1, null, {
1054
+ default: vue.withCtx(() => [
1055
+ vue.renderSlot(_ctx.$slots, "option")
1056
+ ]),
1057
+ _: 3
1058
+ })
1059
+ ]),
1060
+ key: "0"
1061
+ } : void 0
1062
+ ]), 1024)
1063
+ ], 16);
1064
+ };
1065
+ }
1066
+ });
214
1067
  const ImageWorkersKey = Symbol("$image.workers");
215
1068
  const usePreview = (workers = vue.ref([])) => {
216
1069
  const _workers = vue.inject(ImageWorkersKey, workers);
@@ -1869,6 +2722,10 @@ exports.UiLink = UiLink;
1869
2722
  exports.UiLinkType = UiLinkType;
1870
2723
  exports.UiLoader = UiLoader;
1871
2724
  exports.UiLoaderType = UiLoaderType;
2725
+ exports.UiMenuItem = UiMenuItem;
2726
+ exports.UiMenuItemGroup = UiMenuItemGroup;
2727
+ exports.UiMenuItemGroupType = UiMenuItemGroupType;
2728
+ exports.UiMenuItemType = UiMenuItemType;
1872
2729
  exports.UiModalSidebar = UiModalSidebar;
1873
2730
  exports.UiModalSidebarType = UiModalSidebarType;
1874
2731
  exports.UiModalWindow = UiModalWindow;
@@ -1885,6 +2742,9 @@ exports.UiRadio = UiRadio;
1885
2742
  exports.UiRadioType = UiRadioType;
1886
2743
  exports.UiScrollBox = UiScrollBox;
1887
2744
  exports.UiScrollBoxType = UiScrollBoxType;
2745
+ exports.UiSelect = _sfc_main$3;
2746
+ exports.UiSelectOption = _sfc_main$2;
2747
+ exports.UiSelectOptionGroup = _sfc_main;
1888
2748
  exports.UiTag = UiTag;
1889
2749
  exports.UiTagType = UiTagType;
1890
2750
  exports.UiTextbox = UiTextbox;