@globalbrain/sefirot 4.59.1 → 4.61.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/lib/blocks/lens/FieldData.ts +10 -0
- package/lib/blocks/lens/components/LensCatalog.vue +60 -23
- package/lib/blocks/lens/components/LensSheet.vue +6 -0
- package/lib/blocks/lens/components/LensSheetField.vue +261 -31
- package/lib/blocks/lens/components/LensTable.vue +4 -3
- package/lib/blocks/lens/components/LensTableAvatarCell.vue +2 -1
- package/lib/blocks/lens/components/LensTableEditableCell.vue +2 -1
- package/lib/blocks/lens/composables/LensInlineEdit.ts +6 -4
- package/lib/blocks/lens/fields/AvatarField.ts +0 -4
- package/lib/blocks/lens/fields/DateField.ts +1 -1
- package/lib/blocks/lens/fields/Field.ts +24 -6
- package/lib/blocks/lens/fields/FileUploadField.ts +1 -5
- package/lib/blocks/lens/fields/LinkField.ts +1 -1
- package/lib/blocks/lens/fields/SelectField.ts +2 -6
- package/lib/blocks/lens/fields/TextField.ts +1 -1
- package/lib/blocks/lens/fields/TextareaField.ts +1 -1
- package/lib/components/SButton.vue +8 -2
- package/lib/components/SDataListItem.vue +51 -2
- package/lib/components/SDropdownSectionFilter.vue +28 -5
- package/lib/components/SInputAsyncDropdown.vue +63 -8
- package/lib/components/SInputDropdown.vue +57 -4
- package/lib/composables/Utils.ts +48 -8
- package/lib/support/Dom.ts +72 -2
- package/package.json +9 -8
package/lib/support/Dom.ts
CHANGED
|
@@ -17,6 +17,75 @@ export function isTextLikeInput(target: EventTarget | null): boolean {
|
|
|
17
17
|
return ['text', 'search', 'url', 'email', 'tel', 'password', 'number'].includes(type)
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
export type EditorSubmitShortcut = 'enter' | 'command-enter' | 'control-enter'
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* The user-facing shortcut to show for the currently focused editor control.
|
|
24
|
+
* Plain Enter is truthful only for simple text-like inputs; other controls need
|
|
25
|
+
* the platform's primary modifier to avoid clashing with their own Enter key
|
|
26
|
+
* behavior. A text input nested inside a dropdown (its search filter, see
|
|
27
|
+
* `SDropdownSectionFilter` / `SInputAsyncDropdown`) keeps Enter to itself
|
|
28
|
+
* too, so only the modifier gesture reaches the editor from there.
|
|
29
|
+
*/
|
|
30
|
+
export function editorSubmitShortcutForTarget(
|
|
31
|
+
target: EventTarget | null,
|
|
32
|
+
platform = currentPlatform()
|
|
33
|
+
): EditorSubmitShortcut {
|
|
34
|
+
if (
|
|
35
|
+
isTextLikeInput(target)
|
|
36
|
+
&& !(target as HTMLElement).closest('.SDropdown, .SInputAsyncDropdown')
|
|
37
|
+
) {
|
|
38
|
+
return 'enter'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return hasCommandShortcutModifier(platform) ? 'command-enter' : 'control-enter'
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const commandShortcutPlatforms = new Set([
|
|
45
|
+
'ios',
|
|
46
|
+
'ipados',
|
|
47
|
+
'macos',
|
|
48
|
+
|
|
49
|
+
// `navigator.platform` fallback values.
|
|
50
|
+
'ipad',
|
|
51
|
+
'iphone',
|
|
52
|
+
'macintel'
|
|
53
|
+
])
|
|
54
|
+
|
|
55
|
+
function hasCommandShortcutModifier(platform: string): boolean {
|
|
56
|
+
return commandShortcutPlatforms.has(platform.toLowerCase())
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function currentPlatform(): string {
|
|
60
|
+
if (typeof navigator === 'undefined') {
|
|
61
|
+
return ''
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const nav = navigator as Navigator & { userAgentData?: { platform?: string } }
|
|
65
|
+
|
|
66
|
+
return nav.userAgentData?.platform ?? nav.platform ?? ''
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Keydown handler for a text input nested inside a dropdown-like control (a
|
|
71
|
+
* search filter): Enter operates the control, not an enclosing inline editor,
|
|
72
|
+
* so it is stopped — with its default prevented — unless it carries the
|
|
73
|
+
* universal submit modifier (Cmd/Ctrl, see {@link isEditorSubmitKeydown}).
|
|
74
|
+
* Shift/Alt+Enter are contained too: the editor's submit predicate would read
|
|
75
|
+
* them off a text-like input as a plain submitting Enter. The Enter that
|
|
76
|
+
* commits an IME composition belongs to the IME — swallowing its default would
|
|
77
|
+
* drop the composed text — so it passes untouched (the editor ignores it).
|
|
78
|
+
*/
|
|
79
|
+
export function stopNonSubmitEnterKeydown(event: KeyboardEvent): void {
|
|
80
|
+
if (event.isComposing) {
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
if (event.key === 'Enter' && !event.metaKey && !event.ctrlKey) {
|
|
84
|
+
event.stopPropagation()
|
|
85
|
+
event.preventDefault()
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
20
89
|
/**
|
|
21
90
|
* Whether an Enter keydown should submit an inline editor. Ctrl/Cmd+Enter
|
|
22
91
|
* submits from any control — it's the near-universal "submit" gesture (GitHub,
|
|
@@ -65,8 +134,9 @@ export function isEditorCancelKeydown(event: KeyboardEvent): boolean {
|
|
|
65
134
|
* throw on `formInputComponent()` (not yet editable). When making one editable,
|
|
66
135
|
* if its input is a composite control with its own nested text input (e.g. a
|
|
67
136
|
* dropdown's search filter), that nested input must keep Enter/Escape from
|
|
68
|
-
* bubbling to this handler —
|
|
69
|
-
*
|
|
137
|
+
* bubbling to this handler — {@link stopNonSubmitEnterKeydown} is the Enter
|
|
138
|
+
* half; see `SDropdownSectionFilter` — otherwise typing a value and pressing
|
|
139
|
+
* Enter would submit/cancel the whole editor.
|
|
70
140
|
*/
|
|
71
141
|
export function dispatchEditorKeydown(
|
|
72
142
|
event: KeyboardEvent,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@globalbrain/sefirot",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.61.0",
|
|
4
4
|
"description": "Vue Components for Global Brain Design System.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"components",
|
|
@@ -56,11 +56,12 @@
|
|
|
56
56
|
"release": "npm whoami >/dev/null 2>&1 || npm login && release-it"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
+
"@iconify-json/lucide": "^1.2.116",
|
|
59
60
|
"@iconify-json/ph": "^1.2.2",
|
|
60
61
|
"@iconify-json/ri": "^1.2.10",
|
|
61
62
|
"@popperjs/core": "^2.11.8",
|
|
62
|
-
"@sentry/browser": "^10.
|
|
63
|
-
"@sentry/vue": "^10.
|
|
63
|
+
"@sentry/browser": "^10.63.0",
|
|
64
|
+
"@sentry/vue": "^10.63.0",
|
|
64
65
|
"@tanstack/vue-virtual": "3.0.0-beta.62",
|
|
65
66
|
"@tinyhttp/content-disposition": "^2.2.4",
|
|
66
67
|
"@tinyhttp/cookie": "^2.1.1",
|
|
@@ -84,11 +85,11 @@
|
|
|
84
85
|
"jsdom": "^29.1.1",
|
|
85
86
|
"lodash-es": "^4.18.1",
|
|
86
87
|
"magic-string": "^0.30.21",
|
|
87
|
-
"markdown-it": "^14.
|
|
88
|
+
"markdown-it": "^14.3.0",
|
|
88
89
|
"normalize.css": "^8.0.1",
|
|
89
90
|
"ofetch": "^1.5.1",
|
|
90
91
|
"pinia": "^3.0.4",
|
|
91
|
-
"postcss": "^8.5.
|
|
92
|
+
"postcss": "^8.5.16",
|
|
92
93
|
"postcss-nested": "^7.0.2",
|
|
93
94
|
"punycode": "^2.3.1",
|
|
94
95
|
"qs": "^6.15.3",
|
|
@@ -104,8 +105,8 @@
|
|
|
104
105
|
"@histoire/plugin-vue": "1.0.0-beta.1",
|
|
105
106
|
"@release-it/conventional-changelog": "^11.0.1",
|
|
106
107
|
"@types/jsdom": "^28.0.3",
|
|
107
|
-
"@types/node": "^26.0
|
|
108
|
-
"@typescript-eslint/rule-tester": "^8.62.
|
|
108
|
+
"@types/node": "^26.1.0",
|
|
109
|
+
"@typescript-eslint/rule-tester": "^8.62.1",
|
|
109
110
|
"@vitest/coverage-v8": "^4.1.9",
|
|
110
111
|
"@vue/test-utils": "^2.4.11",
|
|
111
112
|
"eslint": "^9.39.4",
|
|
@@ -115,7 +116,7 @@
|
|
|
115
116
|
"typescript": "~6.0.3",
|
|
116
117
|
"vitepress": "^2.0.0-alpha.17",
|
|
117
118
|
"vitest": "^4.1.9",
|
|
118
|
-
"vue-tsc": "^3.3.
|
|
119
|
+
"vue-tsc": "^3.3.6"
|
|
119
120
|
},
|
|
120
121
|
"packageManager": "pnpm@11.9.0"
|
|
121
122
|
}
|