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:
Aslam
2024-09-23 23:16:02 +07:00
committed by GitHub
parent 21084cd3f3
commit 867478d55c
43 changed files with 616 additions and 466 deletions

View File

@@ -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"

View File

@@ -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