@bitrix24/b24ui-nuxt 0.1.1

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 (159) hide show
  1. package/.nuxt/b24ui/advice.ts +52 -0
  2. package/.nuxt/b24ui/alert.ts +118 -0
  3. package/.nuxt/b24ui/avatar-group.ts +52 -0
  4. package/.nuxt/b24ui/avatar.ts +63 -0
  5. package/.nuxt/b24ui/badge.ts +256 -0
  6. package/.nuxt/b24ui/button-group.ts +27 -0
  7. package/.nuxt/b24ui/button.ts +342 -0
  8. package/.nuxt/b24ui/checkbox.ts +128 -0
  9. package/.nuxt/b24ui/chip.ts +205 -0
  10. package/.nuxt/b24ui/container.ts +3 -0
  11. package/.nuxt/b24ui/content/description-list.ts +62 -0
  12. package/.nuxt/b24ui/countdown.ts +94 -0
  13. package/.nuxt/b24ui/form-field.ts +57 -0
  14. package/.nuxt/b24ui/form.ts +3 -0
  15. package/.nuxt/b24ui/index.ts +28 -0
  16. package/.nuxt/b24ui/input.ts +472 -0
  17. package/.nuxt/b24ui/kbd.ts +31 -0
  18. package/.nuxt/b24ui/link.ts +20 -0
  19. package/.nuxt/b24ui/progress.ts +303 -0
  20. package/.nuxt/b24ui/radio-group.ts +135 -0
  21. package/.nuxt/b24ui/range.ts +172 -0
  22. package/.nuxt/b24ui/select.ts +550 -0
  23. package/.nuxt/b24ui/separator.ts +176 -0
  24. package/.nuxt/b24ui/skeleton.ts +3 -0
  25. package/.nuxt/b24ui/switch.ts +134 -0
  26. package/.nuxt/b24ui/tabs.ts +341 -0
  27. package/.nuxt/b24ui/textarea.ts +332 -0
  28. package/.nuxt/b24ui/toast.ts +89 -0
  29. package/.nuxt/b24ui/toaster.ts +91 -0
  30. package/.nuxt/b24ui/tooltip.ts +16 -0
  31. package/LICENSE +21 -0
  32. package/README.md +101 -0
  33. package/cli/commands/make/component.mjs +95 -0
  34. package/cli/commands/make/index.mjs +14 -0
  35. package/cli/commands/make/locale.mjs +64 -0
  36. package/cli/index.mjs +15 -0
  37. package/cli/package.json +13 -0
  38. package/cli/templates.mjs +240 -0
  39. package/cli/utils.mjs +31 -0
  40. package/dist/meta.cjs +23610 -0
  41. package/dist/meta.d.cts +23608 -0
  42. package/dist/meta.d.mts +23608 -0
  43. package/dist/meta.d.ts +23608 -0
  44. package/dist/meta.mjs +23608 -0
  45. package/dist/module.cjs +54 -0
  46. package/dist/module.d.cts +14 -0
  47. package/dist/module.d.mts +14 -0
  48. package/dist/module.d.ts +14 -0
  49. package/dist/module.json +13 -0
  50. package/dist/module.mjs +51 -0
  51. package/dist/runtime/components/Advice.vue +115 -0
  52. package/dist/runtime/components/Alert.vue +136 -0
  53. package/dist/runtime/components/App.vue +52 -0
  54. package/dist/runtime/components/Avatar.vue +118 -0
  55. package/dist/runtime/components/AvatarGroup.vue +99 -0
  56. package/dist/runtime/components/Badge.vue +114 -0
  57. package/dist/runtime/components/Button.vue +177 -0
  58. package/dist/runtime/components/ButtonGroup.vue +58 -0
  59. package/dist/runtime/components/Checkbox.vue +110 -0
  60. package/dist/runtime/components/Chip.vue +81 -0
  61. package/dist/runtime/components/Container.vue +36 -0
  62. package/dist/runtime/components/Countdown.vue +498 -0
  63. package/dist/runtime/components/Form.vue +271 -0
  64. package/dist/runtime/components/FormField.vue +128 -0
  65. package/dist/runtime/components/Input.vue +224 -0
  66. package/dist/runtime/components/Kbd.vue +50 -0
  67. package/dist/runtime/components/Link.vue +219 -0
  68. package/dist/runtime/components/LinkBase.vue +63 -0
  69. package/dist/runtime/components/Progress.vue +182 -0
  70. package/dist/runtime/components/RadioGroup.vue +178 -0
  71. package/dist/runtime/components/Range.vue +114 -0
  72. package/dist/runtime/components/Select.vue +328 -0
  73. package/dist/runtime/components/Separator.vue +82 -0
  74. package/dist/runtime/components/Skeleton.vue +31 -0
  75. package/dist/runtime/components/Switch.vue +133 -0
  76. package/dist/runtime/components/Tabs.vue +127 -0
  77. package/dist/runtime/components/Textarea.vue +216 -0
  78. package/dist/runtime/components/Toast.vue +168 -0
  79. package/dist/runtime/components/Toaster.vue +143 -0
  80. package/dist/runtime/components/Tooltip.vue +94 -0
  81. package/dist/runtime/components/content/DescriptionList.vue +220 -0
  82. package/dist/runtime/composables/defineLocale.d.ts +9 -0
  83. package/dist/runtime/composables/defineLocale.js +4 -0
  84. package/dist/runtime/composables/defineShortcuts.d.ts +15 -0
  85. package/dist/runtime/composables/defineShortcuts.js +135 -0
  86. package/dist/runtime/composables/useAvatarGroup.d.ts +10 -0
  87. package/dist/runtime/composables/useAvatarGroup.js +10 -0
  88. package/dist/runtime/composables/useButtonGroup.d.ts +17 -0
  89. package/dist/runtime/composables/useButtonGroup.js +10 -0
  90. package/dist/runtime/composables/useComponentIcons.d.ts +20 -0
  91. package/dist/runtime/composables/useComponentIcons.js +25 -0
  92. package/dist/runtime/composables/useFormField.d.ts +42 -0
  93. package/dist/runtime/composables/useFormField.js +65 -0
  94. package/dist/runtime/composables/useKbd.d.ts +35 -0
  95. package/dist/runtime/composables/useKbd.js +52 -0
  96. package/dist/runtime/composables/useLocale.d.ts +4 -0
  97. package/dist/runtime/composables/useLocale.js +10 -0
  98. package/dist/runtime/composables/useToast.d.ts +12 -0
  99. package/dist/runtime/composables/useToast.js +62 -0
  100. package/dist/runtime/dictionary/icons.d.ts +20 -0
  101. package/dist/runtime/dictionary/icons.js +35 -0
  102. package/dist/runtime/index.css +1 -0
  103. package/dist/runtime/keyframes.css +1 -0
  104. package/dist/runtime/locale/en.d.ts +2 -0
  105. package/dist/runtime/locale/en.js +48 -0
  106. package/dist/runtime/locale/es.d.ts +2 -0
  107. package/dist/runtime/locale/es.js +48 -0
  108. package/dist/runtime/locale/index.d.ts +3 -0
  109. package/dist/runtime/locale/index.js +3 -0
  110. package/dist/runtime/locale/ru.d.ts +2 -0
  111. package/dist/runtime/locale/ru.js +48 -0
  112. package/dist/runtime/plugins/colors.d.ts +2 -0
  113. package/dist/runtime/plugins/colors.js +40 -0
  114. package/dist/runtime/types/app.config.d.ts +6 -0
  115. package/dist/runtime/types/form.d.ts +84 -0
  116. package/dist/runtime/types/form.js +12 -0
  117. package/dist/runtime/types/icons.d.ts +3 -0
  118. package/dist/runtime/types/icons.js +0 -0
  119. package/dist/runtime/types/index.d.ts +33 -0
  120. package/dist/runtime/types/index.js +33 -0
  121. package/dist/runtime/types/locale.d.ts +50 -0
  122. package/dist/runtime/types/locale.js +0 -0
  123. package/dist/runtime/types/utils.d.ts +22 -0
  124. package/dist/runtime/types/utils.js +0 -0
  125. package/dist/runtime/utils/form.d.ts +17 -0
  126. package/dist/runtime/utils/form.js +153 -0
  127. package/dist/runtime/utils/fuse.d.ts +4 -0
  128. package/dist/runtime/utils/fuse.js +63 -0
  129. package/dist/runtime/utils/index.d.ts +6 -0
  130. package/dist/runtime/utils/index.js +63 -0
  131. package/dist/runtime/utils/link.d.ts +29 -0
  132. package/dist/runtime/utils/link.js +4 -0
  133. package/dist/runtime/utils/locale.d.ts +15 -0
  134. package/dist/runtime/utils/locale.js +25 -0
  135. package/dist/runtime/utils/tv.d.ts +1 -0
  136. package/dist/runtime/utils/tv.js +4 -0
  137. package/dist/runtime/vue/components/Link.vue +203 -0
  138. package/dist/runtime/vue/plugins/color-mode.d.ts +4 -0
  139. package/dist/runtime/vue/plugins/color-mode.js +6 -0
  140. package/dist/runtime/vue/plugins/head.d.ts +4 -0
  141. package/dist/runtime/vue/plugins/head.js +6 -0
  142. package/dist/runtime/vue/stubs.d.ts +15 -0
  143. package/dist/runtime/vue/stubs.js +27 -0
  144. package/dist/shared/b24ui-nuxt.CNGvMe2S.mjs +4074 -0
  145. package/dist/shared/b24ui-nuxt.D22QQtm8.cjs +4079 -0
  146. package/dist/types.d.mts +1 -0
  147. package/dist/types.d.ts +1 -0
  148. package/dist/unplugin.cjs +213 -0
  149. package/dist/unplugin.d.cts +22 -0
  150. package/dist/unplugin.d.mts +22 -0
  151. package/dist/unplugin.d.ts +22 -0
  152. package/dist/unplugin.mjs +202 -0
  153. package/dist/vite.cjs +21 -0
  154. package/dist/vite.d.cts +12 -0
  155. package/dist/vite.d.mts +12 -0
  156. package/dist/vite.d.ts +12 -0
  157. package/dist/vite.mjs +19 -0
  158. package/package.json +166 -0
  159. package/vue-plugin.d.ts +5 -0
@@ -0,0 +1,54 @@
1
+ 'use strict';
2
+
3
+ const defu = require('defu');
4
+ const kit = require('@nuxt/kit');
5
+ const templates = require('./shared/b24ui-nuxt.D22QQtm8.cjs');
6
+ require('node:url');
7
+ require('scule');
8
+
9
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
10
+ const module$1 = kit.defineNuxtModule({
11
+ meta: {
12
+ name: "b24ui",
13
+ configKey: "b24ui",
14
+ compatibility: {
15
+ nuxt: ">=3.13.1"
16
+ },
17
+ docs: "https://bitrix24.github.io/b24ui/guide/installation-nuxt-app.html"
18
+ },
19
+ defaults: templates.defaultOptions,
20
+ async setup(options, nuxt) {
21
+ const { resolve } = kit.createResolver((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('module.cjs', document.baseURI).href)));
22
+ nuxt.options.b24ui = options;
23
+ nuxt.options.alias["#b24ui"] = resolve("./runtime");
24
+ nuxt.options.appConfig.b24ui = defu.defu(nuxt.options.appConfig.b24ui || {}, templates.getDefaultUiConfig());
25
+ nuxt.options.app.rootAttrs = nuxt.options.app.rootAttrs || {};
26
+ nuxt.options.app.rootAttrs.class = [nuxt.options.app.rootAttrs.class, "isolate"].filter(Boolean).join(" ");
27
+ if (nuxt.options.builder === "@nuxt/vite-builder") {
28
+ const plugin = await import('@tailwindcss/vite').then((r) => r.default);
29
+ kit.addVitePlugin(plugin());
30
+ } else {
31
+ nuxt.options.postcss.plugins["@tailwindcss/postcss"] = {};
32
+ }
33
+ async function registerModule(name, options2) {
34
+ if (!kit.hasNuxtModule(name)) {
35
+ await kit.installModule(name, options2);
36
+ } else {
37
+ nuxt.options[name] = defu.defu(nuxt.options[name], options2);
38
+ }
39
+ }
40
+ if (options.colorMode) {
41
+ await registerModule("@nuxtjs/color-mode", { classSuffix: "", disableTransition: true });
42
+ }
43
+ kit.addPlugin({ src: resolve("./runtime/plugins/colors") });
44
+ kit.addComponentsDir({
45
+ path: resolve("./runtime/components"),
46
+ prefix: "B24",
47
+ pathPrefix: false
48
+ });
49
+ kit.addImportsDir(resolve("./runtime/composables"));
50
+ templates.addTemplates(options, nuxt, resolve);
51
+ }
52
+ });
53
+
54
+ module.exports = module$1;
@@ -0,0 +1,14 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+ export * from '../dist/runtime/types/index.js';
3
+
4
+ interface ModuleOptions {
5
+ /**
6
+ * Enable or disable `@nuxtjs/color-mode` module
7
+ * @defaultValue `true`
8
+ * @link https://ui3.nuxt.dev/getting-started/installation#colormode
9
+ */
10
+ colorMode?: boolean;
11
+ }
12
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
13
+
14
+ export { type ModuleOptions, _default as default };
@@ -0,0 +1,14 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+ export * from '../dist/runtime/types/index.js';
3
+
4
+ interface ModuleOptions {
5
+ /**
6
+ * Enable or disable `@nuxtjs/color-mode` module
7
+ * @defaultValue `true`
8
+ * @link https://ui3.nuxt.dev/getting-started/installation#colormode
9
+ */
10
+ colorMode?: boolean;
11
+ }
12
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
13
+
14
+ export { type ModuleOptions, _default as default };
@@ -0,0 +1,14 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+ export * from '../dist/runtime/types/index.js';
3
+
4
+ interface ModuleOptions {
5
+ /**
6
+ * Enable or disable `@nuxtjs/color-mode` module
7
+ * @defaultValue `true`
8
+ * @link https://ui3.nuxt.dev/getting-started/installation#colormode
9
+ */
10
+ colorMode?: boolean;
11
+ }
12
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
13
+
14
+ export { type ModuleOptions, _default as default };
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "b24ui",
3
+ "configKey": "b24ui",
4
+ "compatibility": {
5
+ "nuxt": ">=3.13.1"
6
+ },
7
+ "docs": "https://bitrix24.github.io/b24ui/guide/installation-nuxt-app.html",
8
+ "version": "0.1.1",
9
+ "builder": {
10
+ "@nuxt/module-builder": "0.8.4",
11
+ "unbuild": "2.0.0"
12
+ }
13
+ }
@@ -0,0 +1,51 @@
1
+ import { defu } from 'defu';
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.CNGvMe2S.mjs';
4
+ import 'node:url';
5
+ import 'scule';
6
+
7
+ const module = defineNuxtModule({
8
+ meta: {
9
+ name: "b24ui",
10
+ configKey: "b24ui",
11
+ compatibility: {
12
+ nuxt: ">=3.13.1"
13
+ },
14
+ docs: "https://bitrix24.github.io/b24ui/guide/installation-nuxt-app.html"
15
+ },
16
+ defaults: defaultOptions,
17
+ async setup(options, nuxt) {
18
+ const { resolve } = createResolver(import.meta.url);
19
+ nuxt.options.b24ui = options;
20
+ nuxt.options.alias["#b24ui"] = resolve("./runtime");
21
+ nuxt.options.appConfig.b24ui = defu(nuxt.options.appConfig.b24ui || {}, getDefaultUiConfig());
22
+ nuxt.options.app.rootAttrs = nuxt.options.app.rootAttrs || {};
23
+ nuxt.options.app.rootAttrs.class = [nuxt.options.app.rootAttrs.class, "isolate"].filter(Boolean).join(" ");
24
+ if (nuxt.options.builder === "@nuxt/vite-builder") {
25
+ const plugin = await import('@tailwindcss/vite').then((r) => r.default);
26
+ addVitePlugin(plugin());
27
+ } else {
28
+ nuxt.options.postcss.plugins["@tailwindcss/postcss"] = {};
29
+ }
30
+ async function registerModule(name, options2) {
31
+ if (!hasNuxtModule(name)) {
32
+ await installModule(name, options2);
33
+ } else {
34
+ nuxt.options[name] = defu(nuxt.options[name], options2);
35
+ }
36
+ }
37
+ if (options.colorMode) {
38
+ await registerModule("@nuxtjs/color-mode", { classSuffix: "", disableTransition: true });
39
+ }
40
+ addPlugin({ src: resolve("./runtime/plugins/colors") });
41
+ addComponentsDir({
42
+ path: resolve("./runtime/components"),
43
+ prefix: "B24",
44
+ pathPrefix: false
45
+ });
46
+ addImportsDir(resolve("./runtime/composables"));
47
+ addTemplates(options, nuxt, resolve);
48
+ }
49
+ });
50
+
51
+ export { module as default };
@@ -0,0 +1,115 @@
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/advice'
6
+ import type { UseComponentIconsProps } from '../composables/useComponentIcons'
7
+ import { tv } from '../utils/tv'
8
+ import type { AvatarProps } from '../types'
9
+
10
+ const appConfigAdvice = _appConfig as AppConfig & { b24ui: { advice: Partial<typeof theme> } }
11
+
12
+ const advice = tv({ extend: tv(theme), ...(appConfigAdvice.b24ui?.advice || {}) })
13
+
14
+ type AdviceVariants = VariantProps<typeof advice>
15
+
16
+ export interface AdviceProps extends Omit<UseComponentIconsProps, 'loading' | 'trailing' | 'trailingIcon'> {
17
+ /**
18
+ * The element or component this component should render as.
19
+ * @defaultValue 'div'
20
+ */
21
+ as?: any
22
+ description?: string
23
+ angle?: AdviceVariants['angle']
24
+ class?: any
25
+ b24ui?: Partial<typeof advice.slots>
26
+ }
27
+
28
+ export interface AdviceSlots {
29
+ leading(props?: {}): any
30
+ default(props?: {}): any
31
+ }
32
+ </script>
33
+
34
+ <script setup lang="ts">
35
+ import { computed } from 'vue'
36
+ import { Primitive } from 'reka-ui'
37
+ import { useComponentIcons } from '../composables/useComponentIcons'
38
+ import B24Avatar from './Avatar.vue'
39
+ import PersonIcon from '@bitrix24/b24icons-vue/main/PersonIcon'
40
+
41
+ defineOptions({ inheritAttrs: false })
42
+
43
+ const props = withDefaults(defineProps<AdviceProps>(), {
44
+ as: 'div',
45
+ angle: 'bottom'
46
+ })
47
+ const slots = defineSlots<AdviceSlots>()
48
+
49
+ const { isLeading, leadingIconName } = useComponentIcons(
50
+ computed(() => ({ ...props, loading: false }))
51
+ )
52
+
53
+ const b24ui = computed(() => advice({
54
+ angle: props.angle
55
+ }))
56
+ </script>
57
+
58
+ <template>
59
+ <Primitive :as="as" :class="b24ui.root({ class: [props.class, props.b24ui?.root] })">
60
+ <div v-if="isLeading || !!avatar || !!slots.leading" :class="b24ui.leading({ class: props.b24ui?.leading })">
61
+ <slot name="leading">
62
+ <Component
63
+ :is="leadingIconName"
64
+ v-if="isLeading && leadingIconName"
65
+ :class="b24ui.leadingIcon({ class: props.b24ui?.leadingIcon })"
66
+ />
67
+ <B24Avatar
68
+ v-else-if="!!avatar"
69
+ :size="((props.b24ui?.leadingAvatarSize || b24ui.leadingAvatarSize()) as AvatarProps['size'])"
70
+ v-bind="avatar"
71
+ :class="b24ui.leadingAvatar({ class: props.b24ui?.leadingAvatar })"
72
+ />
73
+ </slot>
74
+ </div>
75
+ <div
76
+ v-else
77
+ :class="b24ui.leading({ class: props.b24ui?.leading })"
78
+ >
79
+ <B24Avatar
80
+ :size="((props.b24ui?.leadingAvatarSize || b24ui.leadingAvatarSize()) as AvatarProps['size'])"
81
+ :icon="PersonIcon"
82
+ alt="Person"
83
+ :class="b24ui.leadingAvatar({ class: props.b24ui?.leadingAvatar })"
84
+ :b24ui="{ icon: 'text-white bg-base-800 dark:text-200' }"
85
+ />
86
+ </div>
87
+ <div :class="b24ui.descriptionWrapper({ class: props.b24ui?.descriptionWrapper })">
88
+ <div :class="b24ui.descriptionAngle({ class: props.b24ui?.descriptionAngle })">
89
+ <svg
90
+ xmlns="http://www.w3.org/2000/svg"
91
+ width="14"
92
+ height="12"
93
+ viewBox="0 0 14 12"
94
+ fill="none"
95
+ >
96
+ <path
97
+ :class="b24ui.descriptionBg({ class: props.b24ui?.descriptionBg })"
98
+ fill-rule="evenodd"
99
+ clip-rule="evenodd"
100
+ d="M11.3513 11.1621C11.3492 11.1591 11.3471 11.1562 11.3449 11.1532C8.41055 10.7202 3.75061 9.56187 0.411676 6.46663C-0.404067 5.71042 0.0889447 4.42611 1.14665 4.08179C3.50511 3.31403 5.56665 2.10552 7.2199 0.897773L7.23071 0.893616L8.27368 0.163147L10.7925 5.46165L13.8677 11.5454L11.3513 11.1621Z"
101
+ /><path
102
+ :class="b24ui.descriptionBorder({ class: props.b24ui?.descriptionBorder })"
103
+ fill-rule="evenodd"
104
+ clip-rule="evenodd"
105
+ d="M11.4909 10.1639C11.7603 10.2036 12.0018 10.3515 12.1597 10.5733C12.3534 10.8456 12.5531 11.1134 12.7585 11.3765L11.3513 11.1621C11.3492 11.1591 11.3471 11.1561 11.3449 11.1531C8.41055 10.7202 3.75061 9.56187 0.411676 6.46662C-0.404067 5.71041 0.0889447 4.4261 1.14665 4.08178C3.50511 3.31403 5.56665 2.10551 7.2199 0.897764L7.23071 0.893607L8.16412 0.239868C8.18419 0.40792 8.20611 0.57539 8.22987 0.742259C8.28188 1.1077 8.12836 1.47208 7.8305 1.6901C6.11459 2.94612 3.95168 4.2203 1.45619 5.03267C1.22829 5.10686 1.07777 5.27921 1.02492 5.43712C1.00004 5.51147 1.00122 5.56804 1.00948 5.60492C1.01647 5.63618 1.03368 5.67964 1.09152 5.73326C4.20493 8.61944 8.61693 9.73979 11.4909 10.1639Z"
106
+ /></svg>
107
+ </div>
108
+ <div :class="b24ui.description({ class: props.b24ui?.description })">
109
+ <slot>
110
+ {{ description }}
111
+ </slot>
112
+ </div>
113
+ </div>
114
+ </Primitive>
115
+ </template>
@@ -0,0 +1,136 @@
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/alert'
6
+ import { tv } from '../utils/tv'
7
+ import type { AvatarProps, ButtonProps, IconComponent } from '../types'
8
+
9
+ const appConfigAlert = _appConfig as AppConfig & { b24ui: { alert: Partial<typeof theme> } }
10
+
11
+ const alert = tv({ extend: tv(theme), ...(appConfigAlert.b24ui?.alert || {}) })
12
+
13
+ type AlertVariants = VariantProps<typeof alert>
14
+
15
+ export interface AlertProps {
16
+ /**
17
+ * The element or component this component should render as.
18
+ * @defaultValue 'div'
19
+ */
20
+ as?: any
21
+ title?: string
22
+ description?: string
23
+ icon?: IconComponent
24
+ avatar?: AvatarProps
25
+ color?: AlertVariants['color']
26
+ size?: AlertVariants['size']
27
+ /**
28
+ * Display a list of actions:
29
+ * - under the title and description if multiline
30
+ * - next to the close button if not multiline
31
+ * `{ size: 'xs' }`{lang="ts-type"}
32
+ */
33
+ actions?: ButtonProps[]
34
+ /**
35
+ * Display a close button to dismiss the alert.
36
+ * `{ size: 'md', color: 'neutral', variant: 'link' }`{lang="ts-type"}
37
+ * @emits 'update:open'
38
+ * @defaultValue false
39
+ */
40
+ close?: ButtonProps | boolean
41
+ /**
42
+ * The icon displayed in the close button.
43
+ * @defaultValue icons.close
44
+ */
45
+ closeIcon?: IconComponent
46
+ class?: any
47
+ b24ui?: Partial<typeof alert.slots>
48
+ }
49
+
50
+ export interface AlertEmits {
51
+ (e: 'update:open', value: boolean): void
52
+ }
53
+
54
+ export interface AlertSlots {
55
+ leading(props?: {}): any
56
+ title(props?: {}): any
57
+ description(props?: {}): any
58
+ actions(props?: {}): any
59
+ close(props: { b24ui: any }): any
60
+ }
61
+ </script>
62
+
63
+ <script setup lang="ts">
64
+ import { computed } from 'vue'
65
+ import { Primitive } from 'reka-ui'
66
+ import { useLocale } from '../composables/useLocale'
67
+ import icons from '../dictionary/icons'
68
+ import B24Avatar from './Avatar.vue'
69
+ import B24Button from './Button.vue'
70
+
71
+ const props = defineProps<AlertProps>()
72
+ const emits = defineEmits<AlertEmits>()
73
+ const slots = defineSlots<AlertSlots>()
74
+
75
+ const { t } = useLocale()
76
+
77
+ const multiline = computed(() => !!props.title && !!props.description)
78
+
79
+ const b24ui = computed(() => alert({
80
+ color: props.color,
81
+ size: props.size
82
+ }))
83
+ </script>
84
+
85
+ <template>
86
+ <Primitive :as="as" :class="b24ui.root({ class: [props.class, props.b24ui?.root], multiline })">
87
+ <slot name="leading">
88
+ <B24Avatar v-if="avatar" :size="((props.b24ui?.avatarSize || b24ui.avatarSize()) as AvatarProps['size'])" v-bind="avatar" :class="b24ui.avatar({ class: props.b24ui?.avatar })" />
89
+ <Component
90
+ :is="icon"
91
+ v-if="icon"
92
+ :class="b24ui.icon({ class: props.b24ui?.icon })"
93
+ />
94
+ </slot>
95
+
96
+ <div :class="b24ui.wrapper({ class: props.b24ui?.wrapper })">
97
+ <div v-if="title || !!slots.title" :class="b24ui.title({ class: props.b24ui?.title })">
98
+ <slot name="title">
99
+ {{ title }}
100
+ </slot>
101
+ </div>
102
+ <div v-if="description || !!slots.description" :class="b24ui.description({ class: props.b24ui?.description })">
103
+ <slot name="description">
104
+ {{ description }}
105
+ </slot>
106
+ </div>
107
+
108
+ <div v-if="multiline && actions?.length" :class="b24ui.actions({ class: props.b24ui?.actions, multiline: true })">
109
+ <slot name="actions">
110
+ <B24Button v-for="(action, index) in actions" :key="index" size="xs" v-bind="action" />
111
+ </slot>
112
+ </div>
113
+ </div>
114
+
115
+ <div v-if="(!multiline && actions?.length) || close" :class="b24ui.actions({ class: props.b24ui?.actions, multiline: false })">
116
+ <template v-if="!multiline">
117
+ <slot name="actions">
118
+ <B24Button v-for="(action, index) in actions" :key="index" size="xs" v-bind="action" />
119
+ </slot>
120
+ </template>
121
+
122
+ <slot name="close" :b24ui="b24ui">
123
+ <B24Button
124
+ v-if="close"
125
+ :icon="closeIcon || icons.close"
126
+ size="xs"
127
+ color="link"
128
+ :aria-label="t('alert.close')"
129
+ v-bind="typeof close === 'object' ? close : undefined"
130
+ :class="b24ui.close({ class: props.b24ui?.close })"
131
+ @click="emits('update:open', false)"
132
+ />
133
+ </slot>
134
+ </div>
135
+ </Primitive>
136
+ </template>
@@ -0,0 +1,52 @@
1
+ <script lang="ts">
2
+ import type { ConfigProviderProps, TooltipProviderProps } from 'reka-ui'
3
+ import { localeContextInjectionKey } from '../composables/useLocale'
4
+ import type { ToasterProps, Locale } from '../types'
5
+
6
+ export interface AppProps extends Omit<ConfigProviderProps, 'useId' | 'dir' | 'locale'> {
7
+ tooltip?: TooltipProviderProps
8
+ toaster?: ToasterProps | null
9
+ locale?: Locale
10
+ }
11
+
12
+ export interface AppSlots {
13
+ default(props?: {}): any
14
+ }
15
+
16
+ export default {
17
+ name: 'App'
18
+ }
19
+ </script>
20
+
21
+ <script setup lang="ts">
22
+ import { toRef, useId, provide } from 'vue'
23
+ import { ConfigProvider, TooltipProvider, useForwardProps } from 'reka-ui'
24
+ import { reactivePick } from '@vueuse/core'
25
+ import B24Toaster from './Toaster.vue'
26
+ // import B24ModalProvider from './ModalProvider.vue'
27
+ // import B24SlideoverProvider from './SlideoverProvider.vue'
28
+
29
+ const props = defineProps<AppProps>()
30
+ defineSlots<AppSlots>()
31
+
32
+ const configProviderProps = useForwardProps(reactivePick(props, 'scrollBody'))
33
+ const tooltipProps = toRef(() => props.tooltip)
34
+ const toasterProps = toRef(() => props.toaster)
35
+
36
+ const locale = toRef(() => props.locale)
37
+ provide(localeContextInjectionKey, locale)
38
+ </script>
39
+
40
+ <template>
41
+ <ConfigProvider :use-id="() => (useId() as string)" :dir="locale?.dir" :locale="locale?.code" v-bind="configProviderProps">
42
+ <TooltipProvider v-bind="tooltipProps">
43
+ <B24Toaster v-if="toaster !== null" v-bind="toasterProps">
44
+ <slot />
45
+ </B24Toaster>
46
+ <slot v-else />
47
+ </TooltipProvider>
48
+
49
+ <!-- B24ModalProvider / -->
50
+ <!-- B24SlideoverProvider / -->
51
+ </ConfigProvider>
52
+ </template>
@@ -0,0 +1,118 @@
1
+ <script lang="ts">
2
+ import type { VariantProps } from 'tailwind-variants'
3
+ import type { AvatarFallbackProps } from 'reka-ui'
4
+ import type { AppConfig } from '@nuxt/schema'
5
+ import _appConfig from '#build/app.config'
6
+ import theme from '#build/b24ui/avatar'
7
+ import { tv } from '../utils/tv'
8
+ import type { IconComponent } from '../types'
9
+
10
+ const appConfigAvatar = _appConfig as AppConfig & { b24ui: { avatar: Partial<typeof theme> } }
11
+
12
+ const avatar = tv({ extend: tv(theme), ...(appConfigAvatar.b24ui?.avatar || {}) })
13
+
14
+ type AvatarVariants = VariantProps<typeof avatar>
15
+
16
+ export interface AvatarProps extends Pick<AvatarFallbackProps, 'delayMs'> {
17
+ /**
18
+ * The element or component this component should render as.
19
+ * @defaultValue 'span'
20
+ */
21
+ as?: any
22
+ src?: string
23
+ alt?: string
24
+ icon?: IconComponent
25
+ text?: string
26
+ size?: AvatarVariants['size']
27
+ class?: any
28
+ b24ui?: Partial<typeof avatar.slots>
29
+ }
30
+
31
+ export interface AvatarSlots {
32
+ default(props?: {}): any
33
+ }
34
+ </script>
35
+
36
+ <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'
40
+ import ImageComponent from '#build/b24ui-image-component'
41
+ import { useAvatarGroup } from '../composables/useAvatarGroup'
42
+
43
+ defineOptions({ inheritAttrs: false })
44
+
45
+ const props = withDefaults(defineProps<AvatarProps>(), { as: 'span' })
46
+ const attrs = useAttrs()
47
+
48
+ const fallbackProps = useForwardProps(reactivePick(props, 'delayMs'))
49
+
50
+ const fallback = computed(() => props.text || (props.alt || '')
51
+ .replace(/[+\-*)(}\][{]/g, '')
52
+ .split(' ')
53
+ .map(word => word.charAt(0))
54
+ .join('')
55
+ .substring(0, 2)
56
+ )
57
+
58
+ const imageLoaded = ref(false)
59
+
60
+ const { size } = useAvatarGroup(props)
61
+
62
+ // eslint-disable-next-line vue/no-dupe-keys
63
+ const b24ui = computed(() => avatar({
64
+ size: size.value
65
+ }))
66
+
67
+ const sizePx = computed(() => ({
68
+ '3xs': 10,
69
+ '2xs': 14,
70
+ 'xs': 18,
71
+ 'sm': 22,
72
+ 'md': 32,
73
+ 'lg': 42,
74
+ 'xl': 48,
75
+ '2xl': 60,
76
+ '3xl': 94
77
+ })[props.size || 'md'])
78
+
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! })
86
+
87
+ then((img) => {
88
+ if (img.isReady.value) {
89
+ imageLoaded.value = true
90
+ }
91
+ })
92
+ })
93
+ </script>
94
+
95
+ <template>
96
+ <AvatarRoot :as="as" :class="b24ui.root({ class: [props.class, props.b24ui?.root] })">
97
+ <component
98
+ :is="ImageComponent"
99
+ v-if="src"
100
+ v-show="imageLoaded"
101
+ role="img"
102
+ :src="src"
103
+ :alt="alt"
104
+ :width="sizePx"
105
+ :height="sizePx"
106
+ v-bind="attrs"
107
+ :class="b24ui.image({ class: props.b24ui?.image })"
108
+ @load="imageLoaded = true"
109
+ />
110
+
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>
118
+ </template>
@@ -0,0 +1,99 @@
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/avatar-group'
6
+ import { tv } from '../utils/tv'
7
+
8
+ const appConfigAvatarGroup = _appConfig as AppConfig & { b24ui: { avatarGroup: Partial<typeof theme> } }
9
+
10
+ const avatarGroup = tv({ extend: tv(theme), ...(appConfigAvatarGroup.b24ui?.avatarGroup || {}) })
11
+
12
+ type AvatarGroupVariants = VariantProps<typeof avatarGroup>
13
+
14
+ export interface AvatarGroupProps {
15
+ /**
16
+ * The element or component this component should render as.
17
+ * @defaultValue 'div'
18
+ */
19
+ as?: any
20
+ size?: AvatarGroupVariants['size']
21
+ /**
22
+ * The maximum number of avatars to display.
23
+ */
24
+ max?: number | string
25
+ class?: any
26
+ b24ui?: Partial<typeof avatarGroup.slots>
27
+ }
28
+
29
+ export interface AvatarGroupSlots {
30
+ default(props?: {}): any
31
+ }
32
+ </script>
33
+
34
+ <script setup lang="ts">
35
+ import { computed, provide } from 'vue'
36
+ import { Primitive } from 'reka-ui'
37
+ import { avatarGroupInjectionKey } from '../composables/useAvatarGroup'
38
+ import B24Avatar from './Avatar.vue'
39
+
40
+ const props = defineProps<AvatarGroupProps>()
41
+ const slots = defineSlots<AvatarGroupSlots>()
42
+
43
+ const b24ui = computed(() => avatarGroup({
44
+ size: props.size
45
+ }))
46
+
47
+ const max = computed(() => typeof props.max === 'string' ? Number.parseInt(props.max, 10) : props.max)
48
+
49
+ const children = computed(() => {
50
+ let children = slots.default?.()
51
+ if (children?.length) {
52
+ children = children.flatMap((child: any) => {
53
+ if (typeof child.type === 'symbol') {
54
+ // `v-if="false"` or commented node
55
+ if (typeof child.children === 'string') {
56
+ return
57
+ }
58
+
59
+ return child.children
60
+ }
61
+
62
+ return child
63
+ }).filter(Boolean)
64
+ }
65
+
66
+ return children || []
67
+ })
68
+
69
+ const visibleAvatars = computed(() => {
70
+ if (!children.value.length) {
71
+ return []
72
+ }
73
+
74
+ if (!max.value || max.value <= 0) {
75
+ return [...children.value]
76
+ }
77
+
78
+ return [...children.value].slice(0, max.value)
79
+ })
80
+
81
+ const hiddenCount = computed(() => {
82
+ if (!children.value.length) {
83
+ return 0
84
+ }
85
+
86
+ return children.value.length - visibleAvatars.value.length
87
+ })
88
+
89
+ provide(avatarGroupInjectionKey, computed(() => ({
90
+ size: props.size
91
+ })))
92
+ </script>
93
+
94
+ <template>
95
+ <Primitive :as="as" :class="b24ui.root({ class: [props.class, props.b24ui?.root] })">
96
+ <component :is="avatar" v-for="(avatar, count) in visibleAvatars" :key="count" :class="b24ui.base({ class: props.b24ui?.base })" />
97
+ <B24Avatar v-if="hiddenCount > 0" :text="`+${hiddenCount}`" :class="b24ui.base({ class: props.b24ui?.base })" />
98
+ </Primitive>
99
+ </template>