@globalbrain/sefirot 4.30.1 → 4.32.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 (134) hide show
  1. package/client.d.ts +5 -0
  2. package/config/nuxt.d.ts +1 -0
  3. package/config/nuxt.js +8 -5
  4. package/config/vite.js +4 -13
  5. package/lib/components/SActionList.vue +2 -2
  6. package/lib/components/SActionMenu.vue +43 -7
  7. package/lib/components/SAvatar.vue +1 -1
  8. package/lib/components/SAvatarStack.vue +12 -12
  9. package/lib/components/SButton.vue +5 -7
  10. package/lib/components/SCard.vue +2 -2
  11. package/lib/components/SChartBar.vue +37 -12
  12. package/lib/components/SChartPie.vue +13 -7
  13. package/lib/components/SControlActionBarCollapse.vue +2 -4
  14. package/lib/components/SControlInputSearch.vue +7 -2
  15. package/lib/components/SDataListItem.vue +1 -3
  16. package/lib/components/SDescAvatar.vue +1 -1
  17. package/lib/components/SDescDay.vue +2 -2
  18. package/lib/components/SDescFile.vue +2 -4
  19. package/lib/components/SDescItem.vue +2 -1
  20. package/lib/components/SDescLabel.vue +1 -1
  21. package/lib/components/SDescLink.vue +2 -7
  22. package/lib/components/SDescPill.vue +2 -4
  23. package/lib/components/SDescText.vue +3 -3
  24. package/lib/components/SDropdown.vue +1 -1
  25. package/lib/components/SDropdownSectionFilter.vue +11 -11
  26. package/lib/components/SFragment.vue +1 -1
  27. package/lib/components/SInputAddon.vue +13 -11
  28. package/lib/components/SInputBase.vue +11 -11
  29. package/lib/components/SInputCheckbox.vue +6 -3
  30. package/lib/components/SInputCheckboxes.vue +7 -3
  31. package/lib/components/SInputDate.vue +3 -5
  32. package/lib/components/SInputDropdown.vue +26 -28
  33. package/lib/components/SInputDropdownItem.vue +21 -11
  34. package/lib/components/SInputFile.vue +9 -6
  35. package/lib/components/SInputFileUpload.vue +9 -11
  36. package/lib/components/SInputFileUploadItem.vue +8 -4
  37. package/lib/components/SInputHMS.vue +3 -1
  38. package/lib/components/SInputImage.vue +4 -2
  39. package/lib/components/SInputNumber.vue +9 -10
  40. package/lib/components/SInputRadio.vue +3 -2
  41. package/lib/components/SInputRadios.vue +6 -5
  42. package/lib/components/SInputSegments.vue +5 -7
  43. package/lib/components/SInputSegmentsOption.vue +1 -2
  44. package/lib/components/SInputSelect.vue +6 -4
  45. package/lib/components/SInputSwitch.vue +4 -1
  46. package/lib/components/SInputSwitches.vue +5 -3
  47. package/lib/components/SInputText.vue +16 -16
  48. package/lib/components/SInputTextarea.vue +7 -3
  49. package/lib/components/SInputYMD.vue +3 -1
  50. package/lib/components/SLink.vue +2 -2
  51. package/lib/components/SLocalNav.vue +1 -1
  52. package/lib/components/SLocalNavActions.vue +1 -1
  53. package/lib/components/SLocalNavMenu.vue +2 -2
  54. package/lib/components/SLoginPagePasswordDialog.vue +2 -2
  55. package/lib/components/SM.vue +1 -1
  56. package/lib/components/SMFade.vue +1 -1
  57. package/lib/components/SMarkdown.vue +3 -2
  58. package/lib/components/SModal.vue +2 -2
  59. package/lib/components/SSnackbar.vue +2 -2
  60. package/lib/components/SSteps.vue +6 -6
  61. package/lib/components/STable.vue +70 -27
  62. package/lib/components/STableCell.vue +14 -17
  63. package/lib/components/STableCellAvatars.vue +1 -1
  64. package/lib/components/STableCellDay.vue +12 -5
  65. package/lib/components/STableCellNumber.vue +2 -3
  66. package/lib/components/STableCellPath.vue +2 -2
  67. package/lib/components/STableCellText.vue +2 -3
  68. package/lib/components/STableColumn.vue +38 -16
  69. package/lib/components/STableFooter.vue +10 -2
  70. package/lib/components/STableHeader.vue +0 -1
  71. package/lib/components/STableHeaderMenu.vue +4 -4
  72. package/lib/components/STableHeaderMenuItem.vue +1 -1
  73. package/lib/components/STooltip.vue +3 -3
  74. package/lib/composables/Api.ts +1 -1
  75. package/lib/composables/App.ts +13 -11
  76. package/lib/composables/Dropdown.ts +10 -1
  77. package/lib/composables/Error.ts +37 -37
  78. package/lib/composables/Grid.ts +1 -4
  79. package/lib/composables/Image.ts +2 -3
  80. package/lib/composables/Lang.ts +8 -16
  81. package/lib/composables/Markdown.ts +1 -1
  82. package/lib/composables/Table.ts +0 -2
  83. package/lib/composables/Theme.ts +1 -13
  84. package/lib/composables/Utils.ts +11 -4
  85. package/lib/composables/Validation.ts +1 -4
  86. package/lib/http/Http.ts +23 -17
  87. package/lib/styles/variables-deprecated.css +0 -1
  88. package/lib/styles/variables.css +16 -16
  89. package/lib/support/Chart.ts +0 -1
  90. package/lib/support/DateRange.ts +1 -1
  91. package/lib/support/Day.ts +12 -65
  92. package/lib/support/File.ts +7 -16
  93. package/lib/support/Utils.ts +7 -40
  94. package/lib/validation/Rule.ts +6 -21
  95. package/lib/validation/rules/decimal.ts +3 -3
  96. package/lib/validation/rules/email.ts +1 -1
  97. package/lib/validation/rules/index.ts +1 -1
  98. package/lib/validation/rules/negativeInteger.ts +1 -1
  99. package/lib/validation/rules/positiveInteger.ts +1 -1
  100. package/lib/validation/rules/requiredHms.ts +2 -2
  101. package/lib/validation/rules/requiredIf.ts +1 -4
  102. package/lib/validation/rules/requiredYmd.ts +2 -2
  103. package/lib/validation/rules/slackChannelName.ts +4 -1
  104. package/lib/validation/rules/zeroOrNegativeInteger.ts +1 -1
  105. package/lib/validation/rules/zeroOrPositiveInteger.ts +1 -1
  106. package/lib/validation/validators/after.ts +1 -5
  107. package/lib/validation/validators/afterOrEqual.ts +1 -5
  108. package/lib/validation/validators/before.ts +1 -4
  109. package/lib/validation/validators/beforeOrEqual.ts +1 -5
  110. package/lib/validation/validators/decimal.ts +7 -9
  111. package/lib/validation/validators/email.ts +4 -8
  112. package/lib/validation/validators/fileExtension.ts +7 -15
  113. package/lib/validation/validators/hms.ts +26 -15
  114. package/lib/validation/validators/index.ts +0 -2
  115. package/lib/validation/validators/maxFileSize.ts +3 -13
  116. package/lib/validation/validators/maxLength.ts +1 -7
  117. package/lib/validation/validators/maxTotalFileSize.ts +3 -26
  118. package/lib/validation/validators/maxValue.ts +2 -6
  119. package/lib/validation/validators/minLength.ts +1 -7
  120. package/lib/validation/validators/minValue.ts +2 -6
  121. package/lib/validation/validators/month.ts +1 -7
  122. package/lib/validation/validators/negativeInteger.ts +1 -7
  123. package/lib/validation/validators/positiveInteger.ts +1 -7
  124. package/lib/validation/validators/required.ts +5 -28
  125. package/lib/validation/validators/requiredHmsIf.ts +11 -13
  126. package/lib/validation/validators/requiredIf.ts +5 -11
  127. package/lib/validation/validators/requiredYmdIf.ts +11 -13
  128. package/lib/validation/validators/slackChannelName.ts +11 -11
  129. package/lib/validation/validators/url.ts +7 -5
  130. package/lib/validation/validators/ymd.ts +36 -30
  131. package/package.json +44 -42
  132. package/lib/composables/Http.ts +0 -18
  133. package/lib/validation/validators/requiredHms.ts +0 -9
  134. package/lib/validation/validators/requiredYmd.ts +0 -9
@@ -3,17 +3,11 @@ import { required } from './required'
3
3
  export type RequiredIfCondition = boolean | string | (() => boolean) | (() => Promise<boolean>)
4
4
 
5
5
  export async function requiredIf(value: unknown, condition: RequiredIfCondition): Promise<boolean> {
6
- if (typeof condition === 'boolean' && condition) {
7
- return required(value)
8
- }
9
-
10
- if (typeof condition === 'string' && condition) {
11
- return required(value)
12
- }
13
-
14
- if (typeof condition === 'function' && (await condition())) {
15
- return required(value)
16
- }
6
+ if (
7
+ (typeof condition === 'boolean' && condition)
8
+ || (typeof condition === 'string' && condition)
9
+ || (typeof condition === 'function' && (await condition()))
10
+ ) { return required(value) }
17
11
 
18
12
  return true
19
13
  }
@@ -1,19 +1,17 @@
1
1
  import { type YmdType } from '../../support/Day'
2
2
  import { type RequiredIfCondition } from './requiredIf'
3
- import { requiredYmd } from './requiredYmd'
3
+ import { ymd } from './ymd'
4
4
 
5
- export async function requiredYmdIf(value: unknown, condition: RequiredIfCondition, required: YmdType[] = ['y', 'm', 'd']): Promise<boolean> {
6
- if (typeof condition === 'boolean' && condition) {
7
- return requiredYmd(value, required)
8
- }
9
-
10
- if (typeof condition === 'string' && condition) {
11
- return requiredYmd(value, required)
12
- }
13
-
14
- if (typeof condition === 'function' && (await condition())) {
15
- return requiredYmd(value, required)
16
- }
5
+ export async function requiredYmdIf(
6
+ value: unknown,
7
+ condition: RequiredIfCondition,
8
+ required: YmdType[] = ['y', 'm', 'd']
9
+ ): Promise<boolean> {
10
+ if (
11
+ (typeof condition === 'boolean' && condition)
12
+ || (typeof condition === 'string' && condition)
13
+ || (typeof condition === 'function' && (await condition()))
14
+ ) { return ymd(value, required, true) }
17
15
 
18
16
  return true
19
17
  }
@@ -1,16 +1,16 @@
1
- import { isString } from '../../support/Utils'
2
-
3
1
  export interface SlackChannelNameOptions {
4
2
  offset?: number
5
3
  }
6
4
 
7
- export function slackChannelName(value: unknown, options: SlackChannelNameOptions = {}): boolean {
8
- if (!isString(value)) {
9
- return false
10
- }
11
-
12
- const { offset = 0 } = options
13
- const maxLength = /* Slack channel name max length */ 80 - offset
14
-
15
- return new RegExp(`^[\\p{Ll}\\p{Lm}\\p{Lo}\\p{M}\\p{N}_-]{1,${maxLength}}$`, 'u').test(value)
5
+ export function slackChannelName(
6
+ value: unknown,
7
+ { offset = 0 }: SlackChannelNameOptions = {}
8
+ ): boolean {
9
+ return (
10
+ typeof value === 'string'
11
+ && /^[\p{L}\p{N}\p{M}_-]+$/u.test(value)
12
+ && /\p{L}|\p{N}/u.test(value)
13
+ && value.length <= 80 - offset
14
+ && value.toLowerCase() === value
15
+ )
16
16
  }
@@ -1,11 +1,13 @@
1
- import { isString } from '../../support/Utils'
1
+ import { hostnameRE } from './email'
2
2
 
3
- const regExp = /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00A1-\uFFFF][a-z0-9\u00A1-\uFFFF_-]{0,62})?[a-z0-9\u00A1-\uFFFF]\.)+(?:[a-z\u00A1-\uFFFF]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i
3
+ const protocolRE = /^https?:$/i
4
4
 
5
5
  export function url(value: unknown): boolean {
6
- if (!isString(value)) {
6
+ if (typeof value !== 'string') { return false }
7
+ try {
8
+ const url = new URL(value)
9
+ return protocolRE.test(url.protocol) && hostnameRE.test(url.hostname)
10
+ } catch {
7
11
  return false
8
12
  }
9
-
10
- return regExp.test(value)
11
13
  }
@@ -1,32 +1,38 @@
1
- import day from 'dayjs'
2
- import { YmdMap, type YmdType, isYmd } from '../../support/Day'
3
-
4
- export function ymd(value: unknown, required: YmdType[] = ['y', 'm', 'd']): boolean {
5
- if (!isYmd(value, required)) {
6
- return false
1
+ import { type YmdType } from '../../support/Day'
2
+ import { isObject } from '../../support/Utils'
3
+
4
+ export function ymd(
5
+ value: unknown,
6
+ required: YmdType[] = ['y', 'm', 'd'],
7
+ rejectNull = false
8
+ ): boolean {
9
+ if (!isObject(value)) { return false }
10
+
11
+ const { year, month, date } = value
12
+ const requiredSet = new Set(required)
13
+
14
+ if (
15
+ !isValidPart(year, requiredSet.has('y'), 1000, 2999)
16
+ || !isValidPart(month, requiredSet.has('m'), 1, 12)
17
+ || !isValidPart(date, requiredSet.has('d'), 1, 31)
18
+ ) { return false }
19
+
20
+ const now = new Date()
21
+ const y = year ?? now.getFullYear()
22
+ const m = month ?? (year ? 1 : now.getMonth() + 1)
23
+ const d = date ?? (year || month ? 1 : now.getDate())
24
+
25
+ const dt = new Date(y, m - 1, d)
26
+ return dt.getFullYear() === y && dt.getMonth() === m - 1 && dt.getDate() === d
27
+
28
+ function isValidPart(
29
+ v: unknown,
30
+ req: boolean,
31
+ min: number,
32
+ max: number
33
+ ): v is number | null | undefined {
34
+ if (v === undefined) { return !req }
35
+ if (v === null) { return !rejectNull || !req }
36
+ return Number.isInteger(v) && v >= min && v <= max
7
37
  }
8
-
9
- return required.every((r) => {
10
- const _value = value[YmdMap[r]]
11
-
12
- if (_value === null) {
13
- return true
14
- }
15
-
16
- if (r === 'y') {
17
- return _value > 0 && _value <= 9999
18
- }
19
-
20
- if (r === 'm') {
21
- return _value > 0 && _value <= 12
22
- }
23
-
24
- const d = day(new Date(2020, value.month ? value.month - 1 : 1, _value))
25
-
26
- if (d.month() + 1 !== (value.month ?? 1)) {
27
- return false
28
- }
29
-
30
- return d.isValid()
31
- })
32
38
  }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@globalbrain/sefirot",
3
3
  "type": "module",
4
- "version": "4.30.1",
5
- "packageManager": "pnpm@9.15.4",
4
+ "version": "4.32.0",
5
+ "packageManager": "pnpm@10.28.0",
6
6
  "description": "Vue Components for Global Brain Design System.",
7
7
  "author": "Kia Ishii <ka.ishii@globalbrains.com>",
8
8
  "license": "MIT",
@@ -33,8 +33,8 @@
33
33
  "story:build": "NODE_NO_WARNINGS=1 VITE_CJS_IGNORE_WARNING=1 histoire build",
34
34
  "story:preview": "NODE_NO_WARNINGS=1 VITE_CJS_IGNORE_WARNING=1 histoire preview --port 4010",
35
35
  "type": "vue-tsc --noEmit",
36
- "lint": "eslint --fix .",
37
- "lint:fail": "eslint .",
36
+ "lint": "eslint --fix",
37
+ "lint:fail": "eslint --max-warnings 0",
38
38
  "vitest": "vitest",
39
39
  "vitest:run": "vitest run",
40
40
  "coverage": "vitest run --coverage",
@@ -44,30 +44,31 @@
44
44
  },
45
45
  "peerDependencies": {
46
46
  "@iconify-json/ph": "^1.2.2",
47
- "@iconify-json/ri": "^1.2.5",
47
+ "@iconify-json/ri": "^1.2.7",
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.16",
52
+ "@vue/reactivity": "^3.5.26",
52
53
  "@vuelidate/core": "^2.0.3",
53
54
  "@vuelidate/validators": "^2.0.4",
54
- "@vueuse/core": "^12 || ^13",
55
+ "@vueuse/core": "^12 || ^13 || ^14",
55
56
  "body-scroll-lock": "4.0.0-beta.0",
56
- "dayjs": "^1.11.13",
57
+ "dayjs": "^1.11.19",
57
58
  "fuse.js": "^7.1.0",
58
- "lodash-es": "^4.17.21",
59
+ "lodash-es": "^4.17.22",
59
60
  "markdown-it": "^14.1.0",
60
61
  "normalize.css": "^8.0.1",
61
- "pinia": "^3.0.3",
62
- "postcss": "^8.5.5",
62
+ "pinia": "^3.0.4",
63
+ "postcss": "^8.5.6",
63
64
  "postcss-nested": "^7.0.2",
64
65
  "v-calendar": "3.0.1",
65
- "vue": "^3.5.16",
66
- "vue-router": "^4.5.1"
66
+ "vue": "^3.5.26",
67
+ "vue-router": "^4.6.4"
67
68
  },
68
69
  "dependencies": {
69
- "@sentry/browser": "^9.29.0",
70
- "@sentry/vue": "^9.29.0",
70
+ "@sentry/browser": "^10.33.0",
71
+ "@sentry/vue": "^10.33.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",
@@ -75,52 +76,53 @@
75
76
  "@types/file-saver": "^2.0.7",
76
77
  "@types/qs": "^6.14.0",
77
78
  "d3": "^7.9.0",
78
- "dompurify": "^3.2.6",
79
79
  "file-saver": "^2.0.5",
80
80
  "html2canvas": "^1.4.1",
81
- "magic-string": "^0.30.17",
82
- "ofetch": "^1.4.1",
83
- "qs": "^6.14.0",
84
- "unplugin-icons": "^22.1.0"
81
+ "isomorphic-dompurify": "^2.35.0",
82
+ "magic-string": "^0.30.21",
83
+ "ofetch": "^1.5.1",
84
+ "qs": "^6.14.1",
85
+ "unplugin-icons": "^22.5.0"
85
86
  },
86
87
  "devDependencies": {
87
- "@globalbrain/eslint-config": "^1.7.1",
88
+ "@globalbrain/eslint-config": "^2.1.0",
88
89
  "@histoire/plugin-vue": "0.16.5",
89
90
  "@iconify-json/ph": "^1.2.2",
90
- "@iconify-json/ri": "^1.2.5",
91
- "@release-it/conventional-changelog": "^10.0.1",
91
+ "@iconify-json/ri": "^1.2.7",
92
+ "@popperjs/core": "^2.11.8",
93
+ "@release-it/conventional-changelog": "^10.0.4",
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.1",
96
- "@vitejs/plugin-vue": "^5.2.4",
97
- "@vitest/coverage-v8": "^3.2.3",
98
- "@vue/reactivity": "^3.5.16",
97
+ "@types/node": "^25.0.7",
98
+ "@vitejs/plugin-vue": "^6.0.3",
99
+ "@vitest/coverage-v8": "^3.2.4",
100
+ "@vue/reactivity": "^3.5.26",
99
101
  "@vue/test-utils": "^2.4.6",
100
102
  "@vuelidate/core": "^2.0.3",
101
103
  "@vuelidate/validators": "^2.0.4",
102
- "@vueuse/core": "^13.0.0",
104
+ "@vueuse/core": "^14.1.0",
103
105
  "body-scroll-lock": "4.0.0-beta.0",
104
- "dayjs": "^1.11.13",
105
- "eslint": "8.57.0",
106
+ "dayjs": "^1.11.19",
107
+ "eslint": "^9.39.2",
106
108
  "fuse.js": "^7.1.0",
107
- "happy-dom": "^18.0.1",
109
+ "happy-dom": "^20.1.0",
108
110
  "histoire": "0.16.5",
109
- "lodash-es": "^4.17.21",
111
+ "lodash-es": "^4.17.22",
110
112
  "markdown-it": "^14.1.0",
111
113
  "normalize.css": "^8.0.1",
112
- "pinia": "^3.0.3",
113
- "postcss": "^8.5.5",
114
+ "pinia": "^3.0.4",
115
+ "postcss": "^8.5.6",
114
116
  "postcss-nested": "^7.0.2",
115
117
  "punycode": "^2.3.1",
116
- "release-it": "^19.0.3",
117
- "typescript": "~5.8.3",
118
+ "release-it": "^19.2.3",
119
+ "typescript": "~5.9.3",
118
120
  "v-calendar": "3.0.1",
119
- "vite": "^6.3.5",
120
- "vitepress": "^2.0.0-alpha.6",
121
- "vitest": "^3.2.3",
122
- "vue": "^3.5.16",
123
- "vue-router": "^4.5.1",
124
- "vue-tsc": "^3.0.4"
121
+ "vite": "^6.4.1",
122
+ "vitepress": "^2.0.0-alpha.15",
123
+ "vitest": "^3.2.4",
124
+ "vue": "^3.5.26",
125
+ "vue-router": "^4.6.4",
126
+ "vue-tsc": "^3.2.2"
125
127
  }
126
128
  }
@@ -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
- }
@@ -1,9 +0,0 @@
1
- import { HmsMap, type HmsType, isHms } from '../../support/Day'
2
-
3
- export function requiredHms(value: unknown, required: HmsType[] = ['h', 'm', 's']): boolean {
4
- if (!isHms(value, required)) {
5
- return false
6
- }
7
-
8
- return required.every((r) => value[HmsMap[r]] != null)
9
- }
@@ -1,9 +0,0 @@
1
- import { YmdMap, type YmdType, isYmd } from '../../support/Day'
2
-
3
- export function requiredYmd(value: unknown, required: YmdType[] = ['y', 'm', 'd']): boolean {
4
- if (!isYmd(value, required)) {
5
- return false
6
- }
7
-
8
- return required.every((r) => value[YmdMap[r]] != null)
9
- }