mirror of
https://github.com/linsa-io/linsa.git
synced 2026-04-23 08:48:37 +02:00
fix: Link, Pages, Topic, Hook and Others (#178)
* chore: remove useKeyDownListener * chore: remove react-use, update jazz version and add query string * chore: update jazz version * chore: use simple mac or win utils code * feat(util): add isTextInput * feat(hooks): all needed hooks * fix: link bunch stuff * fix: page bunch stuff * chore: bunch update for custom component * chore: use throttle from internal hook * chore: topic bunch stuff * chore: update layout * fix: truncate content header of topic detail
This commit is contained in:
@@ -34,22 +34,16 @@ export function shuffleArray<T>(array: T[]): T[] {
|
||||
return shuffled
|
||||
}
|
||||
|
||||
export const isEditableElement = (element: HTMLElement): boolean => {
|
||||
if (element.isContentEditable) {
|
||||
return true
|
||||
}
|
||||
const inputs = ["input", "select", "button", "textarea"] // detect if node is a text input element
|
||||
|
||||
const tagName = element.tagName.toLowerCase()
|
||||
const editableTags = ["input", "textarea", "select", "option"]
|
||||
|
||||
if (editableTags.includes(tagName)) {
|
||||
return true
|
||||
}
|
||||
|
||||
const role = element.getAttribute("role")
|
||||
const editableRoles = ["textbox", "combobox", "listbox"]
|
||||
|
||||
return role ? editableRoles.includes(role) : false
|
||||
export function isTextInput(element: Element): boolean {
|
||||
return !!(
|
||||
element &&
|
||||
element.tagName &&
|
||||
(inputs.indexOf(element.tagName.toLowerCase()) !== -1 ||
|
||||
element.attributes.getNamedItem("role")?.value === "textbox" ||
|
||||
element.attributes.getNamedItem("contenteditable")?.value === "true")
|
||||
)
|
||||
}
|
||||
|
||||
export * from "./urls"
|
||||
|
||||
@@ -1,47 +1,4 @@
|
||||
let isMac: boolean | undefined
|
||||
|
||||
interface Navigator {
|
||||
userAgentData?: {
|
||||
brands: { brand: string; version: string }[]
|
||||
mobile: boolean
|
||||
platform: string
|
||||
getHighEntropyValues: (hints: string[]) => Promise<{
|
||||
platform: string
|
||||
platformVersion: string
|
||||
uaFullVersion: string
|
||||
}>
|
||||
}
|
||||
}
|
||||
|
||||
function getPlatform(): string {
|
||||
const nav = navigator as Navigator
|
||||
|
||||
if (nav.userAgentData) {
|
||||
if (nav.userAgentData.platform) {
|
||||
return nav.userAgentData.platform
|
||||
}
|
||||
|
||||
nav.userAgentData.getHighEntropyValues(["platform"]).then(highEntropyValues => {
|
||||
if (highEntropyValues.platform) {
|
||||
return highEntropyValues.platform
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (typeof navigator.platform === "string") {
|
||||
return navigator.platform
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
export function isMacOS() {
|
||||
if (isMac === undefined) {
|
||||
isMac = getPlatform().toLowerCase().includes("mac")
|
||||
}
|
||||
|
||||
return isMac
|
||||
}
|
||||
const SSR = typeof window === "undefined"
|
||||
|
||||
interface ShortcutKeyResult {
|
||||
symbol: string
|
||||
@@ -51,11 +8,11 @@ interface ShortcutKeyResult {
|
||||
export function getShortcutKey(key: string): ShortcutKeyResult {
|
||||
const lowercaseKey = key.toLowerCase()
|
||||
if (lowercaseKey === "mod") {
|
||||
return isMacOS() ? { symbol: "⌘", readable: "Command" } : { symbol: "Ctrl", readable: "Control" }
|
||||
return isMac() ? { symbol: "⌘", readable: "Command" } : { symbol: "Ctrl", readable: "Control" }
|
||||
} else if (lowercaseKey === "alt") {
|
||||
return isMacOS() ? { symbol: "⌥", readable: "Option" } : { symbol: "Alt", readable: "Alt" }
|
||||
return isMac() ? { symbol: "⌥", readable: "Option" } : { symbol: "Alt", readable: "Alt" }
|
||||
} else if (lowercaseKey === "shift") {
|
||||
return isMacOS() ? { symbol: "⇧", readable: "Shift" } : { symbol: "Shift", readable: "Shift" }
|
||||
return isMac() ? { symbol: "⇧", readable: "Shift" } : { symbol: "Shift", readable: "Shift" }
|
||||
} else {
|
||||
return { symbol: key.toUpperCase(), readable: key }
|
||||
}
|
||||
@@ -64,3 +21,39 @@ export function getShortcutKey(key: string): ShortcutKeyResult {
|
||||
export function getShortcutKeys(keys: string[]): ShortcutKeyResult[] {
|
||||
return keys.map(key => getShortcutKey(key))
|
||||
}
|
||||
|
||||
export function isModKey(event: KeyboardEvent | MouseEvent | React.KeyboardEvent) {
|
||||
return isMac() ? event.metaKey : event.ctrlKey
|
||||
}
|
||||
|
||||
export function isMac(): boolean {
|
||||
if (SSR) {
|
||||
return false
|
||||
}
|
||||
return window.navigator.platform === "MacIntel"
|
||||
}
|
||||
|
||||
export function isWindows(): boolean {
|
||||
if (SSR) {
|
||||
return false
|
||||
}
|
||||
return window.navigator.platform === "Win32"
|
||||
}
|
||||
|
||||
let supportsPassive = false
|
||||
|
||||
try {
|
||||
const opts = Object.defineProperty({}, "passive", {
|
||||
get() {
|
||||
supportsPassive = true
|
||||
}
|
||||
})
|
||||
// @ts-expect-error ts-migrate(2769) testPassive is not a real event
|
||||
window.addEventListener("testPassive", null, opts)
|
||||
// @ts-expect-error ts-migrate(2769) testPassive is not a real event
|
||||
window.removeEventListener("testPassive", null, opts)
|
||||
} catch (e) {
|
||||
// No-op
|
||||
}
|
||||
|
||||
export const supportsPassiveListener = supportsPassive
|
||||
|
||||
Reference in New Issue
Block a user