重组前端功能目录并统一代码规范工具链 (#10)
Reviewed-on: #10
This commit was merged in pull request #10.
This commit is contained in:
@@ -1,16 +0,0 @@
|
||||
import AMapLoader from '@amap/amap-jsapi-loader'
|
||||
|
||||
export function loadAMap() {
|
||||
return AMapLoader.load({
|
||||
key: import.meta.env.VITE_AMAP_KEY,
|
||||
version: '2.0',
|
||||
plugins: [
|
||||
'AMap.Scale',
|
||||
'AMap.ToolBar',
|
||||
'AMap.ControlBar',
|
||||
'AMap.Geolocation',
|
||||
'AMap.Marker',
|
||||
'AMap.InfoWindow',
|
||||
],
|
||||
})
|
||||
}
|
||||
+142
-136
@@ -1,9 +1,9 @@
|
||||
import type {
|
||||
ApiCloud,
|
||||
AuthUser,
|
||||
BackendCloudInfo,
|
||||
BackendCloudType,
|
||||
BackendUserProfile,
|
||||
ApiCloud,
|
||||
AuthUser,
|
||||
BackendCloudInfo,
|
||||
BackendCloudType,
|
||||
BackendUserProfile,
|
||||
} from '@/types/api'
|
||||
import type { CloudType } from '@/types/database'
|
||||
|
||||
@@ -13,185 +13,191 @@ export const API_URL = (import.meta.env.VITE_API_URL || DEFAULT_API_URL).replace
|
||||
export const AUTH_EXPIRED_EVENT = 'opencloud:auth-expired'
|
||||
|
||||
export class ApiError extends Error {
|
||||
status: number
|
||||
detail: unknown
|
||||
status: number
|
||||
detail: unknown
|
||||
|
||||
constructor(message: string, status: number, detail?: unknown) {
|
||||
super(message)
|
||||
this.name = 'ApiError'
|
||||
this.status = status
|
||||
this.detail = detail
|
||||
}
|
||||
constructor(message: string, status: number, detail?: unknown) {
|
||||
super(message)
|
||||
this.name = 'ApiError'
|
||||
this.status = status
|
||||
this.detail = detail
|
||||
}
|
||||
}
|
||||
|
||||
interface ApiRequestOptions extends Omit<RequestInit, 'body'> {
|
||||
body?: BodyInit | Record<string, unknown> | null
|
||||
auth?: boolean
|
||||
// Kept for callers that explicitly disable retries. Cookie sessions do not
|
||||
// use a refresh-and-retry flow, so this option is intentionally ignored.
|
||||
retry?: boolean
|
||||
body?: BodyInit | Record<string, unknown> | null
|
||||
auth?: boolean
|
||||
}
|
||||
|
||||
function isJsonBody(body: ApiRequestOptions['body']): body is Record<string, unknown> {
|
||||
return !!body
|
||||
&& typeof body === 'object'
|
||||
&& !(body instanceof FormData)
|
||||
&& !(body instanceof Blob)
|
||||
&& !(body instanceof URLSearchParams)
|
||||
&& !(body instanceof ArrayBuffer)
|
||||
return (
|
||||
!!body &&
|
||||
typeof body === 'object' &&
|
||||
!(body instanceof FormData) &&
|
||||
!(body instanceof Blob) &&
|
||||
!(body instanceof URLSearchParams) &&
|
||||
!(body instanceof ArrayBuffer)
|
||||
)
|
||||
}
|
||||
|
||||
function validationMessage(value: unknown) {
|
||||
if (typeof value !== 'string') return ''
|
||||
if (typeof value !== 'string') return ''
|
||||
|
||||
try {
|
||||
const issues = JSON.parse(value) as unknown
|
||||
if (!Array.isArray(issues)) return value
|
||||
const messages = issues
|
||||
.map(issue => issue && typeof issue === 'object' && 'message' in issue ? String(issue.message) : '')
|
||||
.filter(Boolean)
|
||||
return messages.join(';') || value
|
||||
} catch {
|
||||
return value
|
||||
}
|
||||
try {
|
||||
const issues = JSON.parse(value) as unknown
|
||||
if (!Array.isArray(issues)) return value
|
||||
const messages = issues
|
||||
.map(issue =>
|
||||
issue && typeof issue === 'object' && 'message' in issue
|
||||
? String(issue.message)
|
||||
: '',
|
||||
)
|
||||
.filter(Boolean)
|
||||
return messages.join(';') || value
|
||||
} catch {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
function errorMessage(payload: unknown, fallback: string) {
|
||||
if (!payload || typeof payload !== 'object') return fallback
|
||||
if (!payload || typeof payload !== 'object') return fallback
|
||||
|
||||
if ('detail' in payload) {
|
||||
const detail = payload.detail
|
||||
if (typeof detail === 'string') return detail
|
||||
if (Array.isArray(detail)) {
|
||||
const messages = detail
|
||||
.map(item => item && typeof item === 'object' && 'msg' in item ? String(item.msg) : '')
|
||||
.filter(Boolean)
|
||||
if (messages.length) return messages.join(';')
|
||||
if ('detail' in payload) {
|
||||
const detail = payload.detail
|
||||
if (typeof detail === 'string') return detail
|
||||
if (Array.isArray(detail)) {
|
||||
const messages = detail
|
||||
.map(item =>
|
||||
item && typeof item === 'object' && 'msg' in item ? String(item.msg) : '',
|
||||
)
|
||||
.filter(Boolean)
|
||||
if (messages.length) return messages.join(';')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ('error' in payload) {
|
||||
const error = payload.error
|
||||
if (typeof error === 'string') return error
|
||||
if (error && typeof error === 'object' && 'message' in error) {
|
||||
return validationMessage(error.message) || fallback
|
||||
if ('error' in payload) {
|
||||
const error = payload.error
|
||||
if (typeof error === 'string') return error
|
||||
if (error && typeof error === 'object' && 'message' in error) {
|
||||
return validationMessage(error.message) || fallback
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fallback
|
||||
return fallback
|
||||
}
|
||||
|
||||
async function readPayload(response: Response) {
|
||||
const text = await response.text()
|
||||
if (!text) return undefined
|
||||
const text = await response.text()
|
||||
if (!text) return undefined
|
||||
|
||||
const contentType = response.headers.get('content-type') || ''
|
||||
if (!contentType.includes('json')) return text
|
||||
const contentType = response.headers.get('content-type') || ''
|
||||
if (!contentType.includes('json')) return text
|
||||
|
||||
try {
|
||||
return JSON.parse(text) as unknown
|
||||
} catch {
|
||||
return text
|
||||
}
|
||||
try {
|
||||
return JSON.parse(text) as unknown
|
||||
} catch {
|
||||
return text
|
||||
}
|
||||
}
|
||||
|
||||
async function toApiError(response: Response) {
|
||||
const payload = await readPayload(response)
|
||||
const fallback = typeof payload === 'string' && payload.trim()
|
||||
? payload.trim()
|
||||
: `请求失败(${response.status})`
|
||||
const payload = await readPayload(response)
|
||||
const fallback =
|
||||
typeof payload === 'string' && payload.trim()
|
||||
? payload.trim()
|
||||
: `请求失败(${response.status})`
|
||||
|
||||
return new ApiError(errorMessage(payload, fallback), response.status, payload)
|
||||
return new ApiError(errorMessage(payload, fallback), response.status, payload)
|
||||
}
|
||||
|
||||
async function request<T>(path: string, options: ApiRequestOptions = {}) {
|
||||
const { body, auth = true, retry: _retry, ...requestOptions } = options
|
||||
const headers = new Headers(requestOptions.headers)
|
||||
let requestBody: BodyInit | null | undefined = body as BodyInit | null | undefined
|
||||
const { body, auth = true, ...requestOptions } = options
|
||||
const headers = new Headers(requestOptions.headers)
|
||||
let requestBody: BodyInit | null | undefined = body as BodyInit | null | undefined
|
||||
|
||||
if (isJsonBody(body)) {
|
||||
headers.set('Content-Type', 'application/json')
|
||||
requestBody = JSON.stringify(body)
|
||||
}
|
||||
if (isJsonBody(body)) {
|
||||
headers.set('Content-Type', 'application/json')
|
||||
requestBody = JSON.stringify(body)
|
||||
}
|
||||
|
||||
const response = await fetch(`${API_URL}${path}`, {
|
||||
...requestOptions,
|
||||
body: requestBody,
|
||||
headers,
|
||||
credentials: 'include',
|
||||
})
|
||||
const response = await fetch(`${API_URL}${path}`, {
|
||||
...requestOptions,
|
||||
body: requestBody,
|
||||
headers,
|
||||
credentials: 'include',
|
||||
})
|
||||
|
||||
if (response.status === 401 && auth && typeof window !== 'undefined') {
|
||||
window.dispatchEvent(new Event(AUTH_EXPIRED_EVENT))
|
||||
}
|
||||
if (response.status === 401 && auth && typeof window !== 'undefined') {
|
||||
window.dispatchEvent(new Event(AUTH_EXPIRED_EVENT))
|
||||
}
|
||||
|
||||
if (!response.ok) throw await toApiError(response)
|
||||
return await readPayload(response) as T
|
||||
if (!response.ok) throw await toApiError(response)
|
||||
return (await readPayload(response)) as T
|
||||
}
|
||||
|
||||
export function apiRequest<T>(path: string, options: ApiRequestOptions = {}) {
|
||||
return request<T>(path, options)
|
||||
return request<T>(path, options)
|
||||
}
|
||||
|
||||
export function imageUrl(id: string, variant: 'preview' | 'original' = 'preview') {
|
||||
return `${API_URL}/image/${encodeURIComponent(id)}/${variant}`
|
||||
return `${API_URL}/image/${encodeURIComponent(id)}/${variant}`
|
||||
}
|
||||
|
||||
export function toAuthUser(profile: BackendUserProfile): AuthUser {
|
||||
return {
|
||||
id: profile.id,
|
||||
email: profile.email,
|
||||
username: profile.name,
|
||||
avatar_id: profile.avatar_id,
|
||||
role: profile.role,
|
||||
is_disabled: profile.is_disabled,
|
||||
cloud_count: profile.cloud_count,
|
||||
received_like_count: profile.received_like_count,
|
||||
created_at: profile.created_at,
|
||||
}
|
||||
return {
|
||||
id: profile.id,
|
||||
email: profile.email,
|
||||
username: profile.name,
|
||||
image: profile.image,
|
||||
role: profile.role,
|
||||
is_disabled: profile.is_disabled,
|
||||
cloud_count: profile.cloud_count,
|
||||
received_like_count: profile.received_like_count,
|
||||
created_at: profile.created_at,
|
||||
}
|
||||
}
|
||||
|
||||
export function toCloudType(row: BackendCloudType): CloudType {
|
||||
return {
|
||||
id: row.id,
|
||||
name: row.name,
|
||||
genus: row.genus || '',
|
||||
icon_id: row.icon_id,
|
||||
// Compatibility value for the excluded legacy admin view. Migrated pages
|
||||
// display rarity_value directly because API.md defines no semantic mapping.
|
||||
rarity: 'common',
|
||||
rarity_value: row.rarity,
|
||||
description: row.description,
|
||||
created_at: row.created_at,
|
||||
}
|
||||
return {
|
||||
id: row.id,
|
||||
name: row.name,
|
||||
genus: row.genus || '',
|
||||
icon_id: row.icon_id,
|
||||
// Compatibility value for the excluded legacy admin view. Migrated pages
|
||||
// display rarity_value directly because API.md defines no semantic mapping.
|
||||
rarity: 'common',
|
||||
rarity_value: row.rarity,
|
||||
description: row.description,
|
||||
created_at: row.created_at,
|
||||
}
|
||||
}
|
||||
|
||||
export function toApiCloud(row: BackendCloudInfo): ApiCloud {
|
||||
return {
|
||||
id: row.id,
|
||||
user_id: row.owner.id,
|
||||
cloud_type_id: row.type.id,
|
||||
image_url: imageUrl(row.id, 'original'),
|
||||
thumbnail_url: imageUrl(row.id, 'preview'),
|
||||
latitude: row.latitude,
|
||||
longitude: row.longitude,
|
||||
description: row.description,
|
||||
captured_at: row.captured_at,
|
||||
status: row.status,
|
||||
is_hidden: row.is_hidden,
|
||||
created_at: row.uploaded_at,
|
||||
updated_at: row.updated_at,
|
||||
cloud_type: {
|
||||
id: row.type.id,
|
||||
name: row.type.name,
|
||||
rarity: 'common',
|
||||
rarity_value: row.type.rarity,
|
||||
},
|
||||
owner: { id: row.owner.id, username: row.owner.name },
|
||||
cloud_type_name: row.type.name,
|
||||
cloud_type_rarity: 'common',
|
||||
cloud_type_rarity_value: row.type.rarity,
|
||||
username: row.owner.name,
|
||||
received_like_count: row.received_like_count,
|
||||
}
|
||||
return {
|
||||
id: row.id,
|
||||
user_id: row.owner.id,
|
||||
cloud_type_id: row.type.id,
|
||||
image_url: imageUrl(row.id, 'original'),
|
||||
thumbnail_url: imageUrl(row.id, 'preview'),
|
||||
latitude: row.latitude,
|
||||
longitude: row.longitude,
|
||||
description: row.description,
|
||||
captured_at: row.captured_at,
|
||||
status: row.status,
|
||||
is_hidden: row.is_hidden,
|
||||
created_at: row.uploaded_at,
|
||||
updated_at: row.updated_at,
|
||||
cloud_type: {
|
||||
id: row.type.id,
|
||||
name: row.type.name,
|
||||
rarity: 'common',
|
||||
rarity_value: row.type.rarity,
|
||||
},
|
||||
owner: { id: row.owner.id, username: row.owner.name },
|
||||
cloud_type_name: row.type.name,
|
||||
cloud_type_rarity: 'common',
|
||||
cloud_type_rarity_value: row.type.rarity,
|
||||
username: row.owner.name,
|
||||
received_like_count: row.received_like_count,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
export const CLOUD_TYPES = [
|
||||
{ id: 1, name: '积云' },
|
||||
{ id: 2, name: '层云' },
|
||||
{ id: 3, name: '卷云' },
|
||||
{ id: 4, name: '积雨云' },
|
||||
{ id: 5, name: '层积云' },
|
||||
{ id: 6, name: '高积云' },
|
||||
{ id: 7, name: '高层云' },
|
||||
{ id: 8, name: '雨层云' },
|
||||
{ id: 9, name: '卷层云' },
|
||||
{ id: 10, name: '卷积云' },
|
||||
] as const
|
||||
|
||||
export function getCloudTypeName(id: string | string[]) {
|
||||
const cloudTypeId = Number(Array.isArray(id) ? id[0] : id)
|
||||
return CLOUD_TYPES.find(item => item.id === cloudTypeId)?.name ?? '云型详情'
|
||||
}
|
||||
+45
-41
@@ -4,60 +4,64 @@ const defaultTitle = 'OpenCloud'
|
||||
const defaultDescription = 'OpenCloud - 活的天空地图,拍云、识别、收藏'
|
||||
|
||||
function resolveSiteUrl() {
|
||||
return (import.meta.env.VITE_SITE_URL || window.location.origin).replace(/\/$/, '')
|
||||
return (import.meta.env.VITE_SITE_URL || window.location.origin).replace(/\/$/, '')
|
||||
}
|
||||
|
||||
function upsertMeta(name: string, content: string) {
|
||||
let element = document.querySelector<HTMLMetaElement>(`meta[name="${name}"]`)
|
||||
if (!element) {
|
||||
element = document.createElement('meta')
|
||||
element.name = name
|
||||
document.head.appendChild(element)
|
||||
}
|
||||
element.content = content
|
||||
let element = document.querySelector<HTMLMetaElement>(`meta[name="${name}"]`)
|
||||
if (!element) {
|
||||
element = document.createElement('meta')
|
||||
element.name = name
|
||||
document.head.appendChild(element)
|
||||
}
|
||||
element.content = content
|
||||
}
|
||||
|
||||
function upsertPropertyMeta(property: string, content: string) {
|
||||
let element = document.querySelector<HTMLMetaElement>(`meta[property="${property}"]`)
|
||||
if (!element) {
|
||||
element = document.createElement('meta')
|
||||
element.setAttribute('property', property)
|
||||
document.head.appendChild(element)
|
||||
}
|
||||
element.content = content
|
||||
let element = document.querySelector<HTMLMetaElement>(`meta[property="${property}"]`)
|
||||
if (!element) {
|
||||
element = document.createElement('meta')
|
||||
element.setAttribute('property', property)
|
||||
document.head.appendChild(element)
|
||||
}
|
||||
element.content = content
|
||||
}
|
||||
|
||||
function upsertCanonical(href: string) {
|
||||
let element = document.querySelector<HTMLLinkElement>('link[rel="canonical"]')
|
||||
if (!element) {
|
||||
element = document.createElement('link')
|
||||
element.rel = 'canonical'
|
||||
document.head.appendChild(element)
|
||||
}
|
||||
element.href = href
|
||||
let element = document.querySelector<HTMLLinkElement>('link[rel="canonical"]')
|
||||
if (!element) {
|
||||
element = document.createElement('link')
|
||||
element.rel = 'canonical'
|
||||
document.head.appendChild(element)
|
||||
}
|
||||
element.href = href
|
||||
}
|
||||
|
||||
export function applyRouteSeo(route: RouteLocationNormalizedLoaded) {
|
||||
const title = typeof route.meta.title === 'function' ? route.meta.title(route) : route.meta.title
|
||||
const description = typeof route.meta.description === 'function' ? route.meta.description(route) : route.meta.description
|
||||
const robots = route.meta.noindex ? 'noindex, nofollow' : 'index, follow'
|
||||
const canonicalPath = route.meta.canonicalPath || route.path
|
||||
const canonical = `${resolveSiteUrl()}${canonicalPath}`
|
||||
const pageTitle = title ? `${title} | OpenCloud` : defaultTitle
|
||||
const pageDescription = description || defaultDescription
|
||||
const title =
|
||||
typeof route.meta.title === 'function' ? route.meta.title(route) : route.meta.title
|
||||
const description =
|
||||
typeof route.meta.description === 'function'
|
||||
? route.meta.description(route)
|
||||
: route.meta.description
|
||||
const robots = route.meta.noindex ? 'noindex, nofollow' : 'index, follow'
|
||||
const canonicalPath = route.meta.canonicalPath || route.path
|
||||
const canonical = `${resolveSiteUrl()}${canonicalPath}`
|
||||
const pageTitle = title ? `${title} | OpenCloud` : defaultTitle
|
||||
const pageDescription = description || defaultDescription
|
||||
|
||||
document.title = pageTitle
|
||||
upsertMeta('description', pageDescription)
|
||||
upsertMeta('robots', robots)
|
||||
upsertCanonical(canonical)
|
||||
document.title = pageTitle
|
||||
upsertMeta('description', pageDescription)
|
||||
upsertMeta('robots', robots)
|
||||
upsertCanonical(canonical)
|
||||
|
||||
upsertPropertyMeta('og:site_name', 'OpenCloud')
|
||||
upsertPropertyMeta('og:type', 'website')
|
||||
upsertPropertyMeta('og:title', pageTitle)
|
||||
upsertPropertyMeta('og:description', pageDescription)
|
||||
upsertPropertyMeta('og:url', canonical)
|
||||
upsertPropertyMeta('og:site_name', 'OpenCloud')
|
||||
upsertPropertyMeta('og:type', 'website')
|
||||
upsertPropertyMeta('og:title', pageTitle)
|
||||
upsertPropertyMeta('og:description', pageDescription)
|
||||
upsertPropertyMeta('og:url', canonical)
|
||||
|
||||
upsertMeta('twitter:card', 'summary')
|
||||
upsertMeta('twitter:title', pageTitle)
|
||||
upsertMeta('twitter:description', pageDescription)
|
||||
upsertMeta('twitter:card', 'summary')
|
||||
upsertMeta('twitter:title', pageTitle)
|
||||
upsertMeta('twitter:description', pageDescription)
|
||||
}
|
||||
|
||||
+52
-52
@@ -2,57 +2,57 @@ import type { GlobalThemeOverrides } from 'naive-ui'
|
||||
|
||||
/** Keep these values aligned with the semantic tokens in styles/tokens.css. */
|
||||
export const openCloudThemeOverrides: GlobalThemeOverrides = {
|
||||
common: {
|
||||
primaryColor: '#34745d',
|
||||
primaryColorHover: '#2d5f4e',
|
||||
primaryColorPressed: '#274c40',
|
||||
primaryColorSuppl: '#34745d',
|
||||
infoColor: '#0369a1',
|
||||
successColor: '#4d7f3b',
|
||||
successColorHover: '#3f6633',
|
||||
successColorPressed: '#35522c',
|
||||
successColorSuppl: '#4d7f3b',
|
||||
warningColor: '#d97706',
|
||||
errorColor: '#dc2626',
|
||||
borderRadius: '0px',
|
||||
borderRadiusSmall: '0px',
|
||||
fontFamily: '"IBM Plex Sans", "Noto Sans SC", "PingFang SC", sans-serif',
|
||||
fontFamilyMono: '"IBM Plex Mono", "SFMono-Regular", monospace',
|
||||
bodyColor: '#eef4f8',
|
||||
cardColor: '#ffffff',
|
||||
modalColor: '#ffffff',
|
||||
popoverColor: '#ffffff',
|
||||
tableColor: '#ffffff',
|
||||
textColorBase: '#0f172a',
|
||||
textColor1: '#0f172a',
|
||||
textColor2: '#334155',
|
||||
textColor3: '#64748b',
|
||||
textColorDisabled: 'var(--oc-color-text-disabled)',
|
||||
dividerColor: '#d9e3ee',
|
||||
borderColor: '#d9e3ee',
|
||||
inputColor: '#ffffff',
|
||||
},
|
||||
Button: {
|
||||
borderRadiusTiny: '0px',
|
||||
borderRadiusSmall: '0px',
|
||||
borderRadiusMedium: '0px',
|
||||
borderRadiusLarge: '0px',
|
||||
textColorPrimary: '#0f172a',
|
||||
textColorHoverPrimary: '#0f172a',
|
||||
},
|
||||
Card: {
|
||||
borderRadius: '0px',
|
||||
borderRadiusEmbedded: '0px',
|
||||
paddingMedium: '24px',
|
||||
},
|
||||
Input: { borderRadius: '0px' },
|
||||
Select: {
|
||||
peers: {
|
||||
InternalSelection: { borderRadius: '0px' },
|
||||
common: {
|
||||
primaryColor: '#34745d',
|
||||
primaryColorHover: '#2d5f4e',
|
||||
primaryColorPressed: '#274c40',
|
||||
primaryColorSuppl: '#34745d',
|
||||
infoColor: '#0369a1',
|
||||
successColor: '#4d7f3b',
|
||||
successColorHover: '#3f6633',
|
||||
successColorPressed: '#35522c',
|
||||
successColorSuppl: '#4d7f3b',
|
||||
warningColor: '#d97706',
|
||||
errorColor: '#dc2626',
|
||||
borderRadius: '0px',
|
||||
borderRadiusSmall: '0px',
|
||||
fontFamily: '"IBM Plex Sans", "Noto Sans SC", "PingFang SC", sans-serif',
|
||||
fontFamilyMono: '"IBM Plex Mono", "SFMono-Regular", monospace',
|
||||
bodyColor: '#eef4f8',
|
||||
cardColor: '#ffffff',
|
||||
modalColor: '#ffffff',
|
||||
popoverColor: '#ffffff',
|
||||
tableColor: '#ffffff',
|
||||
textColorBase: '#0f172a',
|
||||
textColor1: '#0f172a',
|
||||
textColor2: '#334155',
|
||||
textColor3: '#64748b',
|
||||
textColorDisabled: 'var(--oc-color-text-disabled)',
|
||||
dividerColor: '#d9e3ee',
|
||||
borderColor: '#d9e3ee',
|
||||
inputColor: '#ffffff',
|
||||
},
|
||||
},
|
||||
Tabs: { tabBorderRadius: '0px' },
|
||||
Tag: { borderRadius: '0px' },
|
||||
Alert: { borderRadius: '0px' },
|
||||
Modal: { borderRadius: '0px' },
|
||||
Button: {
|
||||
borderRadiusTiny: '0px',
|
||||
borderRadiusSmall: '0px',
|
||||
borderRadiusMedium: '0px',
|
||||
borderRadiusLarge: '0px',
|
||||
textColorPrimary: '#0f172a',
|
||||
textColorHoverPrimary: '#0f172a',
|
||||
},
|
||||
Card: {
|
||||
borderRadius: '0px',
|
||||
borderRadiusEmbedded: '0px',
|
||||
paddingMedium: '24px',
|
||||
},
|
||||
Input: { borderRadius: '0px' },
|
||||
Select: {
|
||||
peers: {
|
||||
InternalSelection: { borderRadius: '0px' },
|
||||
},
|
||||
},
|
||||
Tabs: { tabBorderRadius: '0px' },
|
||||
Tag: { borderRadius: '0px' },
|
||||
Alert: { borderRadius: '0px' },
|
||||
Modal: { borderRadius: '0px' },
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user