@bitrix24/b24ui-nuxt 0.2.8 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/.nuxt/b24ui/avatar.ts +1 -1
  2. package/.nuxt/b24ui/dropdown-menu.ts +15 -15
  3. package/.nuxt/b24ui/input-menu.ts +42 -0
  4. package/.nuxt/b24ui/modal.ts +3 -2
  5. package/.nuxt/b24ui/prose/table-wrapper.ts +46 -0
  6. package/.nuxt/b24ui/select-menu.ts +43 -1
  7. package/.nuxt/b24ui/select.ts +43 -1
  8. package/README.md +1 -1
  9. package/dist/meta.cjs +4840 -7546
  10. package/dist/meta.d.cts +4840 -7546
  11. package/dist/meta.d.mts +4840 -7546
  12. package/dist/meta.d.ts +4840 -7546
  13. package/dist/meta.mjs +4840 -7546
  14. package/dist/module.cjs +1 -1
  15. package/dist/module.json +1 -1
  16. package/dist/module.mjs +1 -1
  17. package/dist/runtime/components/Alert.vue +2 -2
  18. package/dist/runtime/components/Avatar.vue +21 -34
  19. package/dist/runtime/components/Checkbox.vue +3 -1
  20. package/dist/runtime/components/Form.vue +6 -4
  21. package/dist/runtime/components/InputMenu.vue +9 -8
  22. package/dist/runtime/components/Modal.vue +20 -15
  23. package/dist/runtime/components/Select.vue +12 -9
  24. package/dist/runtime/components/SelectMenu.vue +12 -9
  25. package/dist/runtime/components/Switch.vue +4 -1
  26. package/dist/runtime/components/Toast.vue +2 -2
  27. package/dist/runtime/components/Toaster.vue +2 -1
  28. package/dist/runtime/components/Tooltip.vue +1 -1
  29. package/dist/runtime/components/prose/TableWrapper.vue +67 -0
  30. package/dist/runtime/index.css +1 -1
  31. package/dist/runtime/plugins/colors.js +9 -7
  32. package/dist/runtime/types/index.d.ts +1 -0
  33. package/dist/runtime/types/index.js +1 -0
  34. package/dist/shared/{b24ui-nuxt.DBz6Z5xw.cjs → b24ui-nuxt.BDw9-NAb.cjs} +206 -25
  35. package/dist/shared/{b24ui-nuxt.BJy-SIWG.mjs → b24ui-nuxt.aLj37Bax.mjs} +206 -25
  36. package/dist/unplugin.cjs +13 -1
  37. package/dist/unplugin.mjs +13 -1
  38. package/dist/vite.cjs +1 -1
  39. package/dist/vite.mjs +1 -1
  40. package/package.json +13 -13
package/dist/module.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  const defu = require('defu');
4
4
  const kit = require('@nuxt/kit');
5
- const templates = require('./shared/b24ui-nuxt.DBz6Z5xw.cjs');
5
+ const templates = require('./shared/b24ui-nuxt.BDw9-NAb.cjs');
6
6
  require('node:url');
7
7
  require('scule');
8
8
 
package/dist/module.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "nuxt": ">=3.13.1"
6
6
  },
7
7
  "docs": "https://bitrix24.github.io/b24ui/guide/installation-nuxt-app.html",
8
- "version": "0.2.8",
8
+ "version": "0.3.0",
9
9
  "builder": {
10
10
  "@nuxt/module-builder": "0.8.4",
11
11
  "unbuild": "2.0.0"
package/dist/module.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { defu } from 'defu';
2
2
  import { defineNuxtModule, createResolver, addVitePlugin, addPlugin, addComponentsDir, addImportsDir, hasNuxtModule, installModule } from '@nuxt/kit';
3
- import { d as defaultOptions, a as getDefaultUiConfig, b as addTemplates } from './shared/b24ui-nuxt.BJy-SIWG.mjs';
3
+ import { d as defaultOptions, a as getDefaultUiConfig, b as addTemplates } from './shared/b24ui-nuxt.aLj37Bax.mjs';
4
4
  import 'node:url';
5
5
  import 'scule';
6
6
 
@@ -38,7 +38,7 @@ export interface AlertProps {
38
38
  * @emits 'update:open'
39
39
  * @defaultValue false
40
40
  */
41
- close?: ButtonProps | boolean
41
+ close?: boolean | Partial<ButtonProps>
42
42
  /**
43
43
  * The icon displayed in the close button.
44
44
  * @defaultValue icons.close
@@ -129,7 +129,7 @@ const b24ui = computed(() => alert({
129
129
  size="xs"
130
130
  color="link"
131
131
  :aria-label="t('alert.close')"
132
- v-bind="typeof close === 'object' ? close : undefined"
132
+ v-bind="(typeof close === 'object' ? close as Partial<ButtonProps> : {})"
133
133
  :class="b24ui.close({ class: props.b24ui?.close })"
134
134
  @click="emits('update:open', false)"
135
135
  />
@@ -1,6 +1,5 @@
1
1
  <script lang="ts">
2
2
  import type { VariantProps } from 'tailwind-variants'
3
- import type { AvatarFallbackProps } from 'reka-ui'
4
3
  import type { AppConfig } from '@nuxt/schema'
5
4
  import _appConfig from '#build/app.config'
6
5
  import theme from '#build/b24ui/avatar'
@@ -13,7 +12,7 @@ const avatar = tv({ extend: tv(theme), ...(appConfigAvatar.b24ui?.avatar || {})
13
12
 
14
13
  type AvatarVariants = VariantProps<typeof avatar>
15
14
 
16
- export interface AvatarProps extends Pick<AvatarFallbackProps, 'delayMs'> {
15
+ export interface AvatarProps {
17
16
  /**
18
17
  * The element or component this component should render as.
19
18
  * @defaultValue 'span'
@@ -34,18 +33,14 @@ export interface AvatarSlots {
34
33
  </script>
35
34
 
36
35
  <script setup lang="ts">
37
- import { ref, computed, useAttrs, onMounted } from 'vue'
38
- import { AvatarRoot, AvatarFallback, useForwardProps } from 'reka-ui'
39
- import { reactivePick, useImage } from '@vueuse/core'
36
+ import { ref, computed, watch } from 'vue'
37
+ import { Primitive } from 'reka-ui'
40
38
  import ImageComponent from '#build/b24ui-image-component'
41
39
  import { useAvatarGroup } from '../composables/useAvatarGroup'
42
40
 
43
41
  defineOptions({ inheritAttrs: false })
44
42
 
45
43
  const props = withDefaults(defineProps<AvatarProps>(), { as: 'span' })
46
- const attrs = useAttrs() as any
47
-
48
- const fallbackProps = useForwardProps(reactivePick(props, 'delayMs'))
49
44
 
50
45
  const fallback = computed(() => props.text || (props.alt || '')
51
46
  .replace(/[+\-*)(}\][{]/g, '')
@@ -55,8 +50,6 @@ const fallback = computed(() => props.text || (props.alt || '')
55
50
  .substring(0, 2)
56
51
  )
57
52
 
58
- const imageLoaded = ref(false)
59
-
60
53
  const { size } = useAvatarGroup(props)
61
54
 
62
55
  // eslint-disable-next-line vue/no-dupe-keys
@@ -76,43 +69,37 @@ const sizePx = computed(() => ({
76
69
  '3xl': 94
77
70
  })[props.size || 'md'])
78
71
 
79
- // Reproduces Reka UI's [AvatarImage](https://reka-ui.com/docs/components/avatar#image) component behavior which cannot be used with NuxtImg component
80
- onMounted(() => {
81
- if (!props.src || (ImageComponent as unknown as string) !== 'img') {
82
- return
83
- }
84
-
85
- const { then } = useImage({ ...props, ...attrs, src: props.src! })
72
+ const error = ref(false)
86
73
 
87
- then((img) => {
88
- if (img.isReady.value) {
89
- imageLoaded.value = true
90
- }
91
- })
74
+ watch(() => props.src, () => {
75
+ if (error.value) {
76
+ error.value = false
77
+ }
92
78
  })
79
+
80
+ function onError() {
81
+ error.value = true
82
+ }
93
83
  </script>
94
84
 
95
85
  <template>
96
- <AvatarRoot :as="as" :class="b24ui.root({ class: [props.class, props.b24ui?.root] })">
86
+ <Primitive :as="as" :class="b24ui.root({ class: [props.class, props.b24ui?.root] })">
97
87
  <component
98
88
  :is="ImageComponent"
99
- v-if="src"
100
- v-show="imageLoaded"
89
+ v-if="src && !error"
101
90
  role="img"
102
91
  :src="src"
103
92
  :alt="alt"
104
93
  :width="sizePx"
105
94
  :height="sizePx"
106
- v-bind="attrs"
95
+ v-bind="$attrs"
107
96
  :class="b24ui.image({ class: props.b24ui?.image })"
108
- @load="imageLoaded = true"
97
+ @error="onError"
109
98
  />
110
99
 
111
- <AvatarFallback v-if="!imageLoaded" as-child v-bind="{ ...fallbackProps, ...$attrs }">
112
- <slot>
113
- <Component :is="icon" v-if="icon" :class="b24ui.icon({ class: props.b24ui?.icon })" />
114
- <span v-else :class="b24ui.fallback({ class: props.b24ui?.fallback })">{{ fallback || '&nbsp;' }}</span>
115
- </slot>
116
- </AvatarFallback>
117
- </AvatarRoot>
100
+ <slot v-else>
101
+ <Component :is="icon" v-if="icon" :class="b24ui.icon({ class: props.b24ui?.icon })" />
102
+ <span v-else :class="b24ui.fallback({ class: props.b24ui?.fallback })">{{ fallback || '&nbsp;' }}</span>
103
+ </slot>
104
+ </Primitive>
118
105
  </template>
@@ -44,6 +44,8 @@ import { useFormField } from '../composables/useFormField'
44
44
  import Minus20Icon from '@bitrix24/b24icons-vue/actions/Minus20Icon'
45
45
  import CheckIcon from '@bitrix24/b24icons-vue/main/CheckIcon'
46
46
 
47
+ defineOptions({ inheritAttrs: false })
48
+
47
49
  const props = defineProps<CheckboxProps>()
48
50
  const slots = defineSlots<CheckboxSlots>()
49
51
  const emits = defineEmits<CheckboxEmits>()
@@ -78,7 +80,7 @@ function onUpdate(value: any) {
78
80
  <div :class="b24ui.container({ class: props.b24ui?.container })">
79
81
  <CheckboxRoot
80
82
  :id="id"
81
- v-bind="{ ...rootProps, ...ariaAttrs }"
83
+ v-bind="{ ...rootProps, ...$attrs, ...ariaAttrs }"
82
84
  v-model="modelValue"
83
85
  :name="name"
84
86
  :disabled="disabled"
@@ -19,6 +19,7 @@ export interface FormProps<T extends object> {
19
19
  disabled?: boolean
20
20
  validateOnInputDelay?: number
21
21
  class?: any
22
+ transform?: boolean
22
23
  onSubmit?: ((event: FormSubmitEvent<T>) => void | Promise<void>) | (() => void | Promise<void>)
23
24
  }
24
25
 
@@ -43,7 +44,8 @@ const props = withDefaults(defineProps<FormProps<T>>(), {
43
44
  validateOn() {
44
45
  return ['input', 'blur', 'change'] as FormInputEvents[]
45
46
  },
46
- validateOnInputDelay: 300
47
+ validateOnInputDelay: 300,
48
+ transform: true
47
49
  })
48
50
  const emits = defineEmits<FormEmits<T>>()
49
51
  defineSlots<FormSlots>()
@@ -192,7 +194,7 @@ async function onSubmitWrapper(payload: Event) {
192
194
  const event = payload as FormSubmitEvent<any>
193
195
 
194
196
  try {
195
- event.data = await _validate({ nested: true, transform: true })
197
+ event.data = await _validate({ nested: true, transform: props.transform })
196
198
  await props.onSubmit?.(event)
197
199
  } catch (error) {
198
200
  if (!(error instanceof FormValidationException)) {
@@ -205,9 +207,9 @@ async function onSubmitWrapper(payload: Event) {
205
207
  children: error.children
206
208
  }
207
209
  emits('error', errorEvent)
210
+ } finally {
211
+ loading.value = false
208
212
  }
209
-
210
- loading.value = false
211
213
  }
212
214
 
213
215
  const disabled = computed(() => props.disabled || loading.value)
@@ -14,10 +14,13 @@ const appConfigInputMenu = _appConfig as AppConfig & { b24ui: { inputMenu: Parti
14
14
 
15
15
  const inputMenu = tv({ extend: tv(theme), ...(appConfigInputMenu.b24ui?.inputMenu || {}) })
16
16
 
17
+ type InputMenuVariants = VariantProps<typeof inputMenu>
18
+
17
19
  export interface InputMenuItem {
18
20
  label?: string
19
21
  icon?: IconComponent
20
22
  avatar?: AvatarProps
23
+ color?: InputMenuVariants['color']
21
24
  chip?: ChipProps
22
25
  /**
23
26
  * The item type.
@@ -28,8 +31,6 @@ export interface InputMenuItem {
28
31
  onSelect?(e?: Event): void
29
32
  }
30
33
 
31
- type InputMenuVariants = VariantProps<typeof inputMenu>
32
-
33
34
  export interface InputMenuProps<T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<InputMenuItem | AcceptableValue | boolean> = MaybeArrayOfArray<InputMenuItem | AcceptableValue | boolean>, V extends SelectItemKey<T> | undefined = undefined, M extends boolean = false> extends Pick<ComboboxRootProps<T>, 'open' | 'defaultOpen' | 'disabled' | 'name' | 'resetSearchTermOnBlur' | 'highlightOnHover'>, UseComponentIconsProps {
34
35
  /**
35
36
  * The element or component this component should render as.
@@ -453,7 +454,7 @@ defineExpose({
453
454
 
454
455
  <ComboboxItem
455
456
  v-else
456
- :class="b24ui.item({ class: props.b24ui?.item })"
457
+ :class="b24ui.item({ class: props.b24ui?.item, colorItem: item?.color })"
457
458
  :disabled="item.disabled"
458
459
  :value="valueKey && typeof item === 'object' ? get(item, props.valueKey as string) : item"
459
460
  @select="item.onSelect"
@@ -463,16 +464,16 @@ defineExpose({
463
464
  <Component
464
465
  :is="item.icon"
465
466
  v-if="item.icon"
466
- :class="b24ui.itemLeadingIcon({ class: props.b24ui?.itemLeadingIcon })"
467
+ :class="b24ui.itemLeadingIcon({ class: props.b24ui?.itemLeadingIcon, colorItem: item?.color })"
467
468
  />
468
- <B24Avatar v-else-if="item.avatar" :size="((props.b24ui?.itemLeadingAvatarSize || b24ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="b24ui.itemLeadingAvatar({ class: props.b24ui?.itemLeadingAvatar })" />
469
+ <B24Avatar v-else-if="item.avatar" :size="((props.b24ui?.itemLeadingAvatarSize || b24ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="b24ui.itemLeadingAvatar({ class: props.b24ui?.itemLeadingAvatar, colorItem: item?.color })" />
469
470
  <B24Chip
470
471
  v-else-if="item.chip"
471
472
  :size="((props.b24ui?.itemLeadingChipSize || b24ui.itemLeadingChipSize()) as ChipProps['size'])"
472
473
  inset
473
474
  standalone
474
475
  v-bind="item.chip"
475
- :class="b24ui.itemLeadingChip({ class: props.b24ui?.itemLeadingChip })"
476
+ :class="b24ui.itemLeadingChip({ class: props.b24ui?.itemLeadingChip, colorItem: item?.color })"
476
477
  />
477
478
  </slot>
478
479
 
@@ -482,13 +483,13 @@ defineExpose({
482
483
  </slot>
483
484
  </span>
484
485
 
485
- <span :class="b24ui.itemTrailing({ class: props.b24ui?.itemTrailing })">
486
+ <span :class="b24ui.itemTrailing({ class: props.b24ui?.itemTrailing, colorItem: item?.color })">
486
487
  <slot name="item-trailing" :item="(item as T)" :index="index" />
487
488
 
488
489
  <ComboboxItemIndicator as-child>
489
490
  <Component
490
491
  :is="selectedIcon || icons.check"
491
- :class="b24ui.itemTrailingIcon({ class: props.b24ui?.itemTrailingIcon })"
492
+ :class="b24ui.itemTrailingIcon({ class: props.b24ui?.itemTrailingIcon, colorItem: item?.color })"
492
493
  />
493
494
  </ComboboxItemIndicator>
494
495
  </span>
@@ -40,7 +40,7 @@ export interface ModalProps extends DialogRootProps {
40
40
  * `{ size: 'xs', color: 'link' }`{lang="ts-type"}
41
41
  * @defaultValue true
42
42
  */
43
- close?: ButtonProps | boolean
43
+ close?: boolean | Partial<ButtonProps>
44
44
  /**
45
45
  * The icon displayed in the close button.
46
46
  * @defaultValue icons.close
@@ -97,11 +97,14 @@ const contentEvents = computed(() => {
97
97
  return {
98
98
  pointerDownOutside: (e: Event) => e.preventDefault(),
99
99
  interactOutside: (e: Event) => e.preventDefault(),
100
- escapeKeyDown: (e: Event) => e.preventDefault()
100
+ escapeKeyDown: (e: Event) => e.preventDefault(),
101
+ closeAutoFocus: (e: Event) => e.preventDefault()
101
102
  }
102
103
  }
103
104
 
104
- return {}
105
+ return {
106
+ closeAutoFocus: (e: Event) => e.preventDefault()
107
+ }
105
108
  })
106
109
 
107
110
  const b24ui = computed(() => modal({
@@ -137,17 +140,19 @@ const b24ui = computed(() => modal({
137
140
  <slot name="content">
138
141
  <div v-if="!!slots.header || (title || !!slots.title) || (description || !!slots.description) || (close || !!slots.close)" :class="b24ui.header({ class: props.b24ui?.header })">
139
142
  <slot name="header">
140
- <DialogTitle v-if="title || !!slots.title" :class="b24ui.title({ class: props.b24ui?.title })">
141
- <slot name="title">
142
- {{ title }}
143
- </slot>
144
- </DialogTitle>
145
-
146
- <DialogDescription v-if="description || !!slots.description" :class="b24ui.description({ class: props.b24ui?.description })">
147
- <slot name="description">
148
- {{ description }}
149
- </slot>
150
- </DialogDescription>
143
+ <div :class="b24ui.wrapper({ class: props.b24ui?.wrapper })">
144
+ <DialogTitle v-if="title || !!slots.title" :class="b24ui.title({ class: props.b24ui?.title })">
145
+ <slot name="title">
146
+ {{ title }}
147
+ </slot>
148
+ </DialogTitle>
149
+
150
+ <DialogDescription v-if="description || !!slots.description" :class="b24ui.description({ class: props.b24ui?.description })">
151
+ <slot name="description">
152
+ {{ description }}
153
+ </slot>
154
+ </DialogDescription>
155
+ </div>
151
156
 
152
157
  <DialogClose as-child>
153
158
  <slot name="close" :b24ui="b24ui">
@@ -157,7 +162,7 @@ const b24ui = computed(() => modal({
157
162
  size="xs"
158
163
  color="link"
159
164
  :aria-label="t('modal.close')"
160
- v-bind="typeof close === 'object' ? close : undefined"
165
+ v-bind="(typeof close === 'object' ? close as Partial<ButtonProps> : {})"
161
166
  :class="b24ui.close({ class: props.b24ui?.close })"
162
167
  />
163
168
  </slot>
@@ -13,10 +13,13 @@ const appConfigSelect = _appConfig as AppConfig & { b24ui: { select: Partial<typ
13
13
 
14
14
  const select = tv({ extend: tv(theme), ...(appConfigSelect.b24ui?.select || {}) })
15
15
 
16
+ type SelectVariants = VariantProps<typeof select>
17
+
16
18
  export interface SelectItem {
17
19
  label?: string
18
20
  icon?: IconComponent
19
21
  avatar?: AvatarProps
22
+ color?: SelectVariants['color']
20
23
  chip?: ChipProps
21
24
  /**
22
25
  * The item type.
@@ -27,8 +30,6 @@ export interface SelectItem {
27
30
  disabled?: boolean
28
31
  }
29
32
 
30
- type SelectVariants = VariantProps<typeof select>
31
-
32
33
  export interface SelectProps<T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<SelectItem | AcceptableValue | boolean> = MaybeArrayOfArray<SelectItem | AcceptableValue | boolean>, V extends SelectItemKey<T> | undefined = undefined, M extends boolean = false> extends Omit<SelectRootProps<T>, 'dir' | 'multiple' | 'modelValue' | 'defaultValue' | 'by'>, UseComponentIconsProps {
33
34
  id?: string
34
35
  /** The placeholder text when the select is empty. */
@@ -125,6 +126,8 @@ import icons from '../dictionary/icons'
125
126
  import B24Avatar from './Avatar.vue'
126
127
  import B24Chip from './Chip.vue'
127
128
 
129
+ defineOptions({ inheritAttrs: false })
130
+
128
131
  const props = withDefaults(defineProps<SelectProps<T, I, V, M>>(), {
129
132
  valueKey: 'value' as never,
130
133
  labelKey: 'label' as never,
@@ -214,7 +217,7 @@ function onUpdateOpen(value: boolean) {
214
217
  @update:model-value="onUpdate"
215
218
  @update:open="onUpdateOpen"
216
219
  >
217
- <SelectTrigger :id="id" :class="b24ui.base({ class: [props.class, props.b24ui?.base] })" v-bind="ariaAttrs">
220
+ <SelectTrigger :id="id" :class="b24ui.base({ class: [props.class, props.b24ui?.base] })" v-bind="{ ...$attrs, ...ariaAttrs }">
218
221
  <div v-if="isTag" :class="b24ui.tag({ class: props.b24ui?.tag })">
219
222
  {{ props.tag }}
220
223
  </div>
@@ -271,7 +274,7 @@ function onUpdateOpen(value: boolean) {
271
274
 
272
275
  <SelectItem
273
276
  v-else
274
- :class="b24ui.item({ class: props.b24ui?.item })"
277
+ :class="b24ui.item({ class: props.b24ui?.item, colorItem: item?.color })"
275
278
  :disabled="item.disabled"
276
279
  :value="typeof item === 'object' ? get(item, props.valueKey as string) : item"
277
280
  >
@@ -280,16 +283,16 @@ function onUpdateOpen(value: boolean) {
280
283
  <Component
281
284
  :is="item.icon"
282
285
  v-if="item.icon"
283
- :class="b24ui.itemLeadingIcon({ class: props.b24ui?.itemLeadingIcon })"
286
+ :class="b24ui.itemLeadingIcon({ class: props.b24ui?.itemLeadingIcon, colorItem: item?.color })"
284
287
  />
285
- <B24Avatar v-else-if="item.avatar" :size="((props.b24ui?.itemLeadingAvatarSize || b24ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="b24ui.itemLeadingAvatar({ class: props.b24ui?.itemLeadingAvatar })" />
288
+ <B24Avatar v-else-if="item.avatar" :size="((props.b24ui?.itemLeadingAvatarSize || b24ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="b24ui.itemLeadingAvatar({ class: props.b24ui?.itemLeadingAvatar, colorItem: item?.color })" />
286
289
  <B24Chip
287
290
  v-else-if="item.chip"
288
291
  :size="((props.b24ui?.itemLeadingChipSize || b24ui.itemLeadingChipSize()) as ChipProps['size'])"
289
292
  inset
290
293
  standalone
291
294
  v-bind="item.chip"
292
- :class="b24ui.itemLeadingChip({ class: props.b24ui?.itemLeadingChip })"
295
+ :class="b24ui.itemLeadingChip({ class: props.b24ui?.itemLeadingChip, colorItem: item?.color })"
293
296
  />
294
297
  </slot>
295
298
 
@@ -299,13 +302,13 @@ function onUpdateOpen(value: boolean) {
299
302
  </slot>
300
303
  </SelectItemText>
301
304
 
302
- <span :class="b24ui.itemTrailing({ class: props.b24ui?.itemTrailing })">
305
+ <span :class="b24ui.itemTrailing({ class: props.b24ui?.itemTrailing, colorItem: item?.color })">
303
306
  <slot name="item-trailing" :item="(item as T)" :index="index" />
304
307
 
305
308
  <SelectItemIndicator as-child>
306
309
  <Component
307
310
  :is="selectedIcon || icons.check"
308
- :class="b24ui.itemTrailingIcon({ class: props.b24ui?.itemTrailingIcon })"
311
+ :class="b24ui.itemTrailingIcon({ class: props.b24ui?.itemTrailingIcon, colorItem: item?.color })"
309
312
  />
310
313
  </SelectItemIndicator>
311
314
  </span>
@@ -13,10 +13,13 @@ const appConfigSelectMenu = _appConfig as AppConfig & { b24ui: { selectMenu: Par
13
13
 
14
14
  const selectMenu = tv({ extend: tv(theme), ...(appConfigSelectMenu.b24ui?.selectMenu || {}) })
15
15
 
16
+ type SelectMenuVariants = VariantProps<typeof selectMenu>
17
+
16
18
  export interface SelectMenuItem {
17
19
  label?: string
18
20
  icon?: IconComponent
19
21
  avatar?: AvatarProps
22
+ color?: SelectMenuVariants['color']
20
23
  chip?: ChipProps
21
24
  /**
22
25
  * The item type.
@@ -27,8 +30,6 @@ export interface SelectMenuItem {
27
30
  onSelect?(e?: Event): void
28
31
  }
29
32
 
30
- type SelectMenuVariants = VariantProps<typeof selectMenu>
31
-
32
33
  export interface SelectMenuProps<T extends MaybeArrayOfArrayItem<I>, I extends MaybeArrayOfArray<SelectMenuItem | AcceptableValue | boolean> = MaybeArrayOfArray<SelectMenuItem | AcceptableValue | boolean>, V extends SelectItemKey<T> | undefined = undefined, M extends boolean = false> extends Pick<ComboboxRootProps<T>, 'open' | 'defaultOpen' | 'disabled' | 'name' | 'resetSearchTermOnBlur' | 'highlightOnHover'>, UseComponentIconsProps {
33
34
  id?: string
34
35
  /** The placeholder text when the select is empty. */
@@ -172,6 +173,8 @@ import B24Avatar from './Avatar.vue'
172
173
  import B24Chip from './Chip.vue'
173
174
  import B24Input from './Input.vue'
174
175
 
176
+ defineOptions({ inheritAttrs: false })
177
+
175
178
  const props = withDefaults(defineProps<SelectMenuProps<T, I, V, M>>(), {
176
179
  portal: true,
177
180
  searchInput: true,
@@ -341,7 +344,7 @@ function onUpdateOpen(value: boolean) {
341
344
  <ComboboxRoot
342
345
  :id="id"
343
346
  v-slot="{ modelValue, open }"
344
- v-bind="{ ...rootProps, ...ariaAttrs }"
347
+ v-bind="{ ...rootProps, ...$attrs, ...ariaAttrs }"
345
348
  ignore-filter
346
349
  as-child
347
350
  :name="name"
@@ -414,7 +417,7 @@ function onUpdateOpen(value: boolean) {
414
417
 
415
418
  <ComboboxItem
416
419
  v-else
417
- :class="b24ui.item({ class: props.b24ui?.item })"
420
+ :class="b24ui.item({ class: props.b24ui?.item, colorItem: item?.color })"
418
421
  :disabled="item.disabled"
419
422
  :value="valueKey && typeof item === 'object' ? get(item, props.valueKey as string) : item"
420
423
  @select="item.onSelect"
@@ -424,16 +427,16 @@ function onUpdateOpen(value: boolean) {
424
427
  <Component
425
428
  :is="item.icon"
426
429
  v-if="item.icon"
427
- :class="b24ui.itemLeadingIcon({ class: props.b24ui?.itemLeadingIcon })"
430
+ :class="b24ui.itemLeadingIcon({ class: props.b24ui?.itemLeadingIcon, colorItem: item?.color })"
428
431
  />
429
- <B24Avatar v-else-if="item.avatar" :size="((props.b24ui?.itemLeadingAvatarSize || b24ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="b24ui.itemLeadingAvatar({ class: props.b24ui?.itemLeadingAvatar })" />
432
+ <B24Avatar v-else-if="item.avatar" :size="((props.b24ui?.itemLeadingAvatarSize || b24ui.itemLeadingAvatarSize()) as AvatarProps['size'])" v-bind="item.avatar" :class="b24ui.itemLeadingAvatar({ class: props.b24ui?.itemLeadingAvatar, colorItem: item?.color })" />
430
433
  <B24Chip
431
434
  v-else-if="item.chip"
432
435
  :size="((props.b24ui?.itemLeadingChipSize || b24ui.itemLeadingChipSize()) as ChipProps['size'])"
433
436
  inset
434
437
  standalone
435
438
  v-bind="item.chip"
436
- :class="b24ui.itemLeadingChip({ class: props.b24ui?.itemLeadingChip })"
439
+ :class="b24ui.itemLeadingChip({ class: props.b24ui?.itemLeadingChip, colorItem: item?.color })"
437
440
  />
438
441
  </slot>
439
442
 
@@ -443,13 +446,13 @@ function onUpdateOpen(value: boolean) {
443
446
  </slot>
444
447
  </span>
445
448
 
446
- <span :class="b24ui.itemTrailing({ class: props.b24ui?.itemTrailing })">
449
+ <span :class="b24ui.itemTrailing({ class: props.b24ui?.itemTrailing, colorItem: item?.color })">
447
450
  <slot name="item-trailing" :item="(item as T)" :index="index" />
448
451
 
449
452
  <ComboboxItemIndicator as-child>
450
453
  <Component
451
454
  :is="selectedIcon || icons.check"
452
- :class="b24ui.itemTrailingIcon({ class: props.b24ui?.itemTrailingIcon })"
455
+ :class="b24ui.itemTrailingIcon({ class: props.b24ui?.itemTrailingIcon, colorItem: item?.color })"
453
456
  />
454
457
  </ComboboxItemIndicator>
455
458
  </span>
@@ -54,8 +54,11 @@ import { computed, useId } from 'vue'
54
54
  import { Primitive, SwitchRoot, SwitchThumb, useForwardProps, Label } from 'reka-ui'
55
55
  import { reactivePick } from '@vueuse/core'
56
56
  import { useFormField } from '../composables/useFormField'
57
+ import { omit } from '../utils'
57
58
  import icons from '../dictionary/icons'
58
59
 
60
+ defineOptions({ inheritAttrs: false })
61
+
59
62
  const props = defineProps<SwitchProps>()
60
63
  const slots = defineSlots<SwitchSlots>()
61
64
  const emits = defineEmits<SwitchEmits>()
@@ -89,7 +92,7 @@ function onUpdate(value: any) {
89
92
  <div :class="b24ui.container({ class: props.b24ui?.container })">
90
93
  <SwitchRoot
91
94
  :id="id"
92
- v-bind="{ ...rootProps, ...ariaAttrs }"
95
+ v-bind="{ ...rootProps, ...omit({ ...$attrs }, ['data-state']), ...ariaAttrs }"
93
96
  v-model="modelValue"
94
97
  :name="name"
95
98
  :disabled="disabled || loading"
@@ -38,7 +38,7 @@ export interface ToastProps extends Pick<ToastRootProps, 'defaultOpen' | 'open'
38
38
  * `{ size: 'md', color: 'neutral', variant: 'link' }`{lang="ts-type"}
39
39
  * @defaultValue true
40
40
  */
41
- close?: ButtonProps | boolean
41
+ close?: boolean | Partial<ButtonProps>
42
42
  /**
43
43
  * The icon displayed in the close button.
44
44
  * @defaultValue icons.close
@@ -167,7 +167,7 @@ defineExpose({
167
167
  size="xs"
168
168
  color="link"
169
169
  :aria-label="t('toast.close')"
170
- v-bind="typeof close === 'object' ? close : undefined"
170
+ v-bind="(typeof close === 'object' ? close as Partial<ButtonProps> : {})"
171
171
  :class="b24ui.close({ class: props.b24ui?.close })"
172
172
  @click.stop
173
173
  />
@@ -106,7 +106,8 @@ function getOffset(index: number) {
106
106
  v-for="(toast, index) of toasts"
107
107
  :key="toast.id"
108
108
  ref="refs"
109
- v-bind="omit(toast, ['id'])"
109
+ v-bind="omit(toast, ['id', 'close'])"
110
+ :close="(toast.close as boolean)"
110
111
  :data-expanded="expanded"
111
112
  :data-front="!expanded && index === toasts.length - 1"
112
113
  :style="{
@@ -67,7 +67,7 @@ const b24ui = computed(() => tooltip({
67
67
 
68
68
  <template>
69
69
  <TooltipRoot v-slot="{ open }" v-bind="rootProps">
70
- <TooltipTrigger v-if="!!slots.default" as-child :class="props.class">
70
+ <TooltipTrigger v-if="!!slots.default" v-bind="$attrs" as-child :class="props.class">
71
71
  <slot :open="open" />
72
72
  </TooltipTrigger>
73
73
 
@@ -0,0 +1,67 @@
1
+ <script lang="ts">
2
+ import type { VariantProps } from 'tailwind-variants'
3
+ import type { AppConfig } from '@nuxt/schema'
4
+ import _appConfig from '#build/app.config'
5
+ import theme from '#build/b24ui/prose/table-wrapper'
6
+ import { tv } from '../../utils/tv'
7
+
8
+ const appConfigTableWrapper = _appConfig as AppConfig & { b24ui: { prose: { tableWrapper: Partial<typeof theme> } } }
9
+
10
+ const tableWrapper = tv({ extend: tv(theme), ...(appConfigTableWrapper.b24ui?.prose?.tableWrapper || {}) })
11
+
12
+ type TableWrapperVariants = VariantProps<typeof tableWrapper>
13
+
14
+ export interface TableWrapperProps {
15
+ /**
16
+ * The element or component this component should render as.
17
+ * @defaultValue 'div'
18
+ */
19
+ as?: any
20
+ size?: TableWrapperVariants['size']
21
+ rounded?: boolean
22
+ zebra?: boolean
23
+ pinRows?: boolean
24
+ pinCols?: boolean
25
+ rowHover?: boolean
26
+ bordered?: boolean
27
+ scrollbarThin?: boolean
28
+ class?: any
29
+ b24ui?: Partial<typeof tableWrapper.slots>
30
+ }
31
+
32
+ export interface TableWrapperSlots {
33
+ default(props?: {}): any
34
+ }
35
+ </script>
36
+
37
+ <script setup lang="ts">
38
+ import { computed } from 'vue'
39
+ import { Primitive } from 'reka-ui'
40
+
41
+ defineOptions({ inheritAttrs: false })
42
+
43
+ const props = withDefaults(defineProps<TableWrapperProps>(), {
44
+ as: 'div',
45
+ scrollbarThin: true
46
+ })
47
+
48
+ const b24ui = computed(() => tableWrapper({
49
+ size: props.size,
50
+ rounded: Boolean(props.rounded),
51
+ zebra: Boolean(props.zebra),
52
+ pinRows: Boolean(props.pinRows),
53
+ pinCols: Boolean(props.pinCols),
54
+ rowHover: Boolean(props.rowHover),
55
+ bordered: Boolean(props.bordered),
56
+ scrollbarThin: Boolean(props.scrollbarThin)
57
+ }))
58
+ </script>
59
+
60
+ <template>
61
+ <Primitive
62
+ :as="as"
63
+ :class="b24ui.base({ class: [props.class, props.b24ui?.base] })"
64
+ >
65
+ <slot />
66
+ </Primitive>
67
+ </template>
@@ -1 +1 @@
1
- @plugin "@bitrix24/b24style";@import "#build/b24ui.css";@import "./keyframes.css";@variant light (&:where(.light, .light *));@variant dark (&:where(.dark, .dark *));@layer base{body{@apply antialiased scheme-light dark:scheme-dark}}
1
+ @plugin "@bitrix24/b24style";@import "#build/b24ui.css";@import "./keyframes.css";@variant light (&:where(.light, .light *));@variant dark (&:where(.dark, .dark *));@layer base{body{@apply antialiased scheme-light dark:scheme-dark}.scrollbar-thin{scrollbar-width:thin}}