@globalbrain/sefirot 4.30.1 → 4.31.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.
- package/config/nuxt.js +7 -4
- package/config/vite.js +1 -11
- package/lib/components/SActionMenu.vue +43 -7
- package/lib/components/SDescText.vue +1 -1
- package/lib/composables/Api.ts +1 -1
- package/lib/composables/App.ts +13 -11
- package/lib/composables/Lang.ts +7 -15
- package/lib/composables/Theme.ts +0 -12
- package/package.json +20 -18
- package/lib/composables/Http.ts +0 -18
package/config/nuxt.js
CHANGED
|
@@ -5,9 +5,6 @@ import icons from 'unplugin-icons/nuxt'
|
|
|
5
5
|
import { mergeConfig } from 'vite'
|
|
6
6
|
import { baseConfig as baseViteConfig } from './vite.js'
|
|
7
7
|
|
|
8
|
-
delete baseViteConfig.plugins
|
|
9
|
-
delete baseViteConfig.resolve?.alias
|
|
10
|
-
|
|
11
8
|
export const baseConfig = {
|
|
12
9
|
alias: { sefirot: fileURLToPath(new URL('../lib', import.meta.url)) },
|
|
13
10
|
app: { teleportId: 'sefirot-modals' },
|
|
@@ -23,7 +20,13 @@ export const baseConfig = {
|
|
|
23
20
|
],
|
|
24
21
|
postcss: { plugins: { 'postcss-nested': {} } },
|
|
25
22
|
telemetry: false,
|
|
26
|
-
vite:
|
|
23
|
+
vite: {
|
|
24
|
+
...baseViteConfig,
|
|
25
|
+
resolve: { ...baseViteConfig.resolve, alias: {} },
|
|
26
|
+
plugins: baseViteConfig.plugins?.filter(
|
|
27
|
+
(plugin) => plugin && 'name' in plugin && plugin.name !== 'unplugin-icons'
|
|
28
|
+
)
|
|
29
|
+
}
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
export function defineConfig(config = {}) {
|
package/config/vite.js
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* Adapted from
|
|
5
|
-
* @see https://github.com/unplugin/unplugin-icons/blob/67fd9b7791dc1754cb8dc46b854b22c8bb4cf380/src/core/compilers/vue3.ts
|
|
6
|
-
* @see https://github.com/unplugin/unplugin-icons/blob/639ec9691e022e52c641d0f96f585dbf04dab095/src/core/svgId.ts
|
|
7
|
-
*
|
|
8
|
-
* Original licenses:
|
|
9
|
-
*
|
|
10
|
-
* Copyright (c) 2020 Anthony Fu <https://github.com/antfu>
|
|
11
|
-
* @license MIT
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
3
|
import { fileURLToPath } from 'node:url'
|
|
15
4
|
import MagicString from 'magic-string'
|
|
16
5
|
import icons from 'unplugin-icons/vite'
|
|
@@ -48,6 +37,7 @@ export const baseConfig = {
|
|
|
48
37
|
|
|
49
38
|
// list the client-side direct dependencies/peerDependencies which get bundled
|
|
50
39
|
dedupe: [
|
|
40
|
+
'@popperjs/core',
|
|
51
41
|
'@sentry/browser',
|
|
52
42
|
'@sentry/vue',
|
|
53
43
|
'@tanstack/vue-virtual',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { type Component, ref } from 'vue'
|
|
2
|
+
import { type Component, ref, useTemplateRef } from 'vue'
|
|
3
3
|
import { type DropdownSection, useManualDropdownPosition } from '../composables/Dropdown'
|
|
4
4
|
import { useFlyout } from '../composables/Flyout'
|
|
5
5
|
import SButton, { type Mode, type Size, type Tooltip, type Type } from './SButton.vue'
|
|
@@ -29,21 +29,52 @@ const props = withDefaults(defineProps<{
|
|
|
29
29
|
dropdownAlign: 'left'
|
|
30
30
|
})
|
|
31
31
|
|
|
32
|
-
const
|
|
32
|
+
const containerRef = useTemplateRef('container')
|
|
33
|
+
const dropdownRef = useTemplateRef('dropdown')
|
|
33
34
|
|
|
34
|
-
const { isOpen, toggle } = useFlyout(
|
|
35
|
-
const { position, update:
|
|
35
|
+
const { isOpen, toggle } = useFlyout(containerRef)
|
|
36
|
+
const { position: verticalPlacement, update: updateVerticalPlacement }
|
|
37
|
+
= useManualDropdownPosition(containerRef)
|
|
38
|
+
|
|
39
|
+
const actualAlign = ref(props.dropdownAlign)
|
|
40
|
+
|
|
41
|
+
function calculateOptimalAlign(dropdownElement: HTMLElement): 'left' | 'right' {
|
|
42
|
+
// Temporarily show the dropdown to measure it (similar to tooltip approach)
|
|
43
|
+
const originalDisplay = dropdownElement.style.display
|
|
44
|
+
dropdownElement.style.display = 'block'
|
|
45
|
+
const dropdownRect = dropdownElement.getBoundingClientRect()
|
|
46
|
+
dropdownElement.style.display = originalDisplay
|
|
47
|
+
|
|
48
|
+
const dropdownWidth = dropdownRect.width
|
|
49
|
+
|
|
50
|
+
const viewportWidth = window.innerWidth
|
|
51
|
+
const containerRect = containerRef.value!.getBoundingClientRect()
|
|
52
|
+
|
|
53
|
+
const spaceOnRight = viewportWidth - containerRect.left
|
|
54
|
+
const spaceOnLeft = containerRect.right
|
|
55
|
+
|
|
56
|
+
if (props.dropdownAlign === 'left') {
|
|
57
|
+
return spaceOnRight >= dropdownWidth ? 'left' : 'right'
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return spaceOnLeft >= dropdownWidth ? 'right' : 'left'
|
|
61
|
+
}
|
|
36
62
|
|
|
37
63
|
async function onOpen() {
|
|
38
64
|
if (!props.disabled) {
|
|
39
|
-
|
|
65
|
+
updateVerticalPlacement()
|
|
66
|
+
|
|
67
|
+
if (dropdownRef.value) {
|
|
68
|
+
actualAlign.value = calculateOptimalAlign(dropdownRef.value)
|
|
69
|
+
}
|
|
70
|
+
|
|
40
71
|
toggle()
|
|
41
72
|
}
|
|
42
73
|
}
|
|
43
74
|
</script>
|
|
44
75
|
|
|
45
76
|
<template>
|
|
46
|
-
<div class="SActionMenu" :class="[{ block },
|
|
77
|
+
<div class="SActionMenu" :class="[{ block }, actualAlign]" ref="container">
|
|
47
78
|
<div class="button">
|
|
48
79
|
<SButton
|
|
49
80
|
:tag
|
|
@@ -64,7 +95,12 @@ async function onOpen() {
|
|
|
64
95
|
@click="onOpen"
|
|
65
96
|
/>
|
|
66
97
|
</div>
|
|
67
|
-
<div
|
|
98
|
+
<div
|
|
99
|
+
class="dropdown"
|
|
100
|
+
:class="verticalPlacement"
|
|
101
|
+
:style="{ display: isOpen ? 'block' : 'none' }"
|
|
102
|
+
ref="dropdown"
|
|
103
|
+
>
|
|
68
104
|
<SDropdown :sections="options" />
|
|
69
105
|
</div>
|
|
70
106
|
</div>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { useLinkifyIt } from 'sefirot/composables/Markdown'
|
|
3
2
|
import { computed } from 'vue'
|
|
3
|
+
import { useLinkifyIt } from '../composables/Markdown'
|
|
4
4
|
import { useHasSlotContent } from '../composables/Utils'
|
|
5
5
|
import SDescEmpty from './SDescEmpty.vue'
|
|
6
6
|
|
package/lib/composables/Api.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useHttpConfig } from 'sefirot/stores/HttpConfig'
|
|
2
1
|
import { type Ref, type WatchSource, ref, watch } from 'vue'
|
|
3
2
|
import { Http } from '../http/Http'
|
|
3
|
+
import { useHttpConfig } from '../stores/HttpConfig'
|
|
4
4
|
import { tryOnMounted } from './Utils'
|
|
5
5
|
|
|
6
6
|
export interface Query<Data = any> {
|
package/lib/composables/App.ts
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
import { type HttpOptions } from '
|
|
2
|
-
import {
|
|
3
|
-
import { type
|
|
4
|
-
import { type HasTheme, useSetupTheme } from './Theme'
|
|
1
|
+
import { type HttpOptions, useHttpConfig } from '../stores/HttpConfig'
|
|
2
|
+
import { type Lang, getBrowserLang, provideLang } from './Lang'
|
|
3
|
+
import { type Theme, useTheme } from './Theme'
|
|
5
4
|
|
|
6
|
-
export interface SetupAppUser
|
|
5
|
+
export interface SetupAppUser {
|
|
6
|
+
lang?: Lang
|
|
7
|
+
theme?: Theme
|
|
8
|
+
}
|
|
7
9
|
|
|
8
10
|
export interface SetupAppOptions {
|
|
9
11
|
http?: HttpOptions
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
export function useSetupApp(): (user?: SetupAppUser | null, options?: SetupAppOptions) => void {
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const setupHttp = useSetupHttp()
|
|
15
|
+
const theme = useTheme()
|
|
16
|
+
const httpConfig = useHttpConfig()
|
|
16
17
|
|
|
17
18
|
return (user, options) => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
const lang = user?.lang ?? getBrowserLang()
|
|
20
|
+
provideLang(lang)
|
|
21
|
+
if (user?.theme) { theme.value = user.theme }
|
|
22
|
+
httpConfig.apply({ lang, ...options?.http })
|
|
21
23
|
}
|
|
22
24
|
}
|
package/lib/composables/Lang.ts
CHANGED
|
@@ -11,20 +11,8 @@ export interface TransMessages<T> {
|
|
|
11
11
|
ja: T
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
export interface HasLang {
|
|
15
|
-
lang: Lang
|
|
16
|
-
}
|
|
17
|
-
|
|
18
14
|
export const SefirotLangKey: InjectionKey<Lang> = Symbol.for('sefirot-lang-key')
|
|
19
15
|
|
|
20
|
-
export function useSetupLang(): (user?: HasLang | null) => void {
|
|
21
|
-
const browserLang = useBrowserLang()
|
|
22
|
-
|
|
23
|
-
return (user) => {
|
|
24
|
-
provideLang(user?.lang ?? browserLang)
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
16
|
export function provideLang(lang: Lang) {
|
|
29
17
|
getCurrentInstance()!.appContext.app._context.provides[SefirotLangKey] = lang
|
|
30
18
|
}
|
|
@@ -33,12 +21,16 @@ export function useLang(): Lang {
|
|
|
33
21
|
return inject(SefirotLangKey, 'en')
|
|
34
22
|
}
|
|
35
23
|
|
|
36
|
-
export function
|
|
37
|
-
const lang = navigator
|
|
38
|
-
|
|
24
|
+
export function getBrowserLang(): Lang {
|
|
25
|
+
const lang = String(globalThis.navigator?.language || 'en')
|
|
39
26
|
return lang.split('-')[0] === 'ja' ? 'ja' : 'en'
|
|
40
27
|
}
|
|
41
28
|
|
|
29
|
+
/** @deprecated use `getBrowserLang` instead */
|
|
30
|
+
export function useBrowserLang(): Lang {
|
|
31
|
+
return getBrowserLang()
|
|
32
|
+
}
|
|
33
|
+
|
|
42
34
|
export function useTrans<T>(messages: TransMessages<T>): Trans<T> {
|
|
43
35
|
const lang = useLang()
|
|
44
36
|
|
package/lib/composables/Theme.ts
CHANGED
|
@@ -3,18 +3,6 @@ import { type WritableComputedRef, computed } from 'vue'
|
|
|
3
3
|
|
|
4
4
|
export type Theme = 'light' | 'dark'
|
|
5
5
|
|
|
6
|
-
export interface HasTheme {
|
|
7
|
-
theme: Theme
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function useSetupTheme(): (user?: HasTheme | null) => void {
|
|
11
|
-
const theme = useTheme()
|
|
12
|
-
|
|
13
|
-
return (user) => {
|
|
14
|
-
theme.value = user?.theme ?? 'light'
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
6
|
export function useTheme(): WritableComputedRef<Theme> {
|
|
19
7
|
const _isDark = useDark()
|
|
20
8
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@globalbrain/sefirot",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.31.0",
|
|
5
5
|
"packageManager": "pnpm@9.15.4",
|
|
6
6
|
"description": "Vue Components for Global Brain Design System.",
|
|
7
7
|
"author": "Kia Ishii <ka.ishii@globalbrains.com>",
|
|
@@ -45,10 +45,11 @@
|
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"@iconify-json/ph": "^1.2.2",
|
|
47
47
|
"@iconify-json/ri": "^1.2.5",
|
|
48
|
+
"@popperjs/core": "^2.11.8",
|
|
48
49
|
"@types/body-scroll-lock": "^3.1.2",
|
|
49
50
|
"@types/lodash-es": "^4.17.12",
|
|
50
51
|
"@types/markdown-it": "^14.1.2",
|
|
51
|
-
"@vue/reactivity": "^3.5.
|
|
52
|
+
"@vue/reactivity": "^3.5.18",
|
|
52
53
|
"@vuelidate/core": "^2.0.3",
|
|
53
54
|
"@vuelidate/validators": "^2.0.4",
|
|
54
55
|
"@vueuse/core": "^12 || ^13",
|
|
@@ -59,15 +60,15 @@
|
|
|
59
60
|
"markdown-it": "^14.1.0",
|
|
60
61
|
"normalize.css": "^8.0.1",
|
|
61
62
|
"pinia": "^3.0.3",
|
|
62
|
-
"postcss": "^8.5.
|
|
63
|
+
"postcss": "^8.5.6",
|
|
63
64
|
"postcss-nested": "^7.0.2",
|
|
64
65
|
"v-calendar": "3.0.1",
|
|
65
|
-
"vue": "^3.5.
|
|
66
|
+
"vue": "^3.5.18",
|
|
66
67
|
"vue-router": "^4.5.1"
|
|
67
68
|
},
|
|
68
69
|
"dependencies": {
|
|
69
|
-
"@sentry/browser": "^
|
|
70
|
-
"@sentry/vue": "^
|
|
70
|
+
"@sentry/browser": "^10.5.0",
|
|
71
|
+
"@sentry/vue": "^10.5.0",
|
|
71
72
|
"@tanstack/vue-virtual": "3.0.0-beta.62",
|
|
72
73
|
"@tinyhttp/content-disposition": "^2.2.2",
|
|
73
74
|
"@tinyhttp/cookie": "^2.1.1",
|
|
@@ -81,21 +82,22 @@
|
|
|
81
82
|
"magic-string": "^0.30.17",
|
|
82
83
|
"ofetch": "^1.4.1",
|
|
83
84
|
"qs": "^6.14.0",
|
|
84
|
-
"unplugin-icons": "^22.
|
|
85
|
+
"unplugin-icons": "^22.2.0"
|
|
85
86
|
},
|
|
86
87
|
"devDependencies": {
|
|
87
88
|
"@globalbrain/eslint-config": "^1.7.1",
|
|
88
89
|
"@histoire/plugin-vue": "0.16.5",
|
|
89
90
|
"@iconify-json/ph": "^1.2.2",
|
|
90
91
|
"@iconify-json/ri": "^1.2.5",
|
|
92
|
+
"@popperjs/core": "^2.11.8",
|
|
91
93
|
"@release-it/conventional-changelog": "^10.0.1",
|
|
92
94
|
"@types/body-scroll-lock": "^3.1.2",
|
|
93
95
|
"@types/lodash-es": "^4.17.12",
|
|
94
96
|
"@types/markdown-it": "^14.1.2",
|
|
95
|
-
"@types/node": "^24.0
|
|
96
|
-
"@vitejs/plugin-vue": "^
|
|
97
|
-
"@vitest/coverage-v8": "^3.2.
|
|
98
|
-
"@vue/reactivity": "^3.5.
|
|
97
|
+
"@types/node": "^24.3.0",
|
|
98
|
+
"@vitejs/plugin-vue": "^6.0.1",
|
|
99
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
100
|
+
"@vue/reactivity": "^3.5.18",
|
|
99
101
|
"@vue/test-utils": "^2.4.6",
|
|
100
102
|
"@vuelidate/core": "^2.0.3",
|
|
101
103
|
"@vuelidate/validators": "^2.0.4",
|
|
@@ -110,17 +112,17 @@
|
|
|
110
112
|
"markdown-it": "^14.1.0",
|
|
111
113
|
"normalize.css": "^8.0.1",
|
|
112
114
|
"pinia": "^3.0.3",
|
|
113
|
-
"postcss": "^8.5.
|
|
115
|
+
"postcss": "^8.5.6",
|
|
114
116
|
"postcss-nested": "^7.0.2",
|
|
115
117
|
"punycode": "^2.3.1",
|
|
116
|
-
"release-it": "^19.0.
|
|
117
|
-
"typescript": "~5.
|
|
118
|
+
"release-it": "^19.0.4",
|
|
119
|
+
"typescript": "~5.9.2",
|
|
118
120
|
"v-calendar": "3.0.1",
|
|
119
121
|
"vite": "^6.3.5",
|
|
120
|
-
"vitepress": "^2.0.0-alpha.
|
|
121
|
-
"vitest": "^3.2.
|
|
122
|
-
"vue": "^3.5.
|
|
122
|
+
"vitepress": "^2.0.0-alpha.11",
|
|
123
|
+
"vitest": "^3.2.4",
|
|
124
|
+
"vue": "^3.5.18",
|
|
123
125
|
"vue-router": "^4.5.1",
|
|
124
|
-
"vue-tsc": "^3.0.
|
|
126
|
+
"vue-tsc": "^3.0.5"
|
|
125
127
|
}
|
|
126
128
|
}
|
package/lib/composables/Http.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { type Lang, useBrowserLang } from 'sefirot/composables/Lang'
|
|
2
|
-
import { type HttpOptions, useHttpConfig } from 'sefirot/stores/HttpConfig'
|
|
3
|
-
|
|
4
|
-
export interface HasLang {
|
|
5
|
-
lang: Lang
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function useSetupHttp(): (user?: HasLang | null, options?: HttpOptions) => void {
|
|
9
|
-
const browserLang = useBrowserLang()
|
|
10
|
-
const httpConfig = useHttpConfig()
|
|
11
|
-
|
|
12
|
-
return (user, options = {}) => {
|
|
13
|
-
httpConfig.apply({
|
|
14
|
-
lang: user?.lang ?? browserLang,
|
|
15
|
-
...options
|
|
16
|
-
})
|
|
17
|
-
}
|
|
18
|
-
}
|