왼쪽메뉴에 어드민 메뉴의 트리구조 리스트 api 값을 사용하도록 기능 추가
This commit is contained in:
37
src/_nav.tsx
37
src/_nav.tsx
@@ -1,21 +1,8 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import CIcon from '@coreui/icons-react'
|
import CIcon from '@coreui/icons-react'
|
||||||
import {
|
import {
|
||||||
cilBell,
|
|
||||||
cilBrowser,
|
|
||||||
cilBoatAlt,
|
|
||||||
cilCalculator,
|
|
||||||
cilChartPie,
|
|
||||||
cilCursor,
|
|
||||||
cilDescription,
|
|
||||||
cilDrop,
|
|
||||||
cilExternalLink,
|
|
||||||
cilNotes,
|
|
||||||
cilPencil,
|
|
||||||
cilPuzzle,
|
|
||||||
cilSpeedometer,
|
cilSpeedometer,
|
||||||
cilStar,
|
cilStar,
|
||||||
cilMenu,
|
|
||||||
} from '@coreui/icons'
|
} from '@coreui/icons'
|
||||||
import { CNavGroup, CNavItem, CNavTitle } from '@coreui/react'
|
import { CNavGroup, CNavItem, CNavTitle } from '@coreui/react'
|
||||||
|
|
||||||
@@ -32,29 +19,7 @@ const _nav = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: CNavTitle,
|
component: CNavTitle,
|
||||||
name: 'Theme',
|
name: 'Menu',
|
||||||
},
|
|
||||||
{
|
|
||||||
component: CNavItem,
|
|
||||||
name: 'Colors',
|
|
||||||
to: '/theme/colors',
|
|
||||||
icon: <CIcon icon={cilDrop} customClassName="nav-icon" />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: CNavItem,
|
|
||||||
name: 'Typography',
|
|
||||||
to: '/theme/typography',
|
|
||||||
icon: <CIcon icon={cilPencil} customClassName="nav-icon" />,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: CNavTitle,
|
|
||||||
name: 'Admin',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: CNavItem,
|
|
||||||
name: 'Menu Management',
|
|
||||||
to: '/admin/menu',
|
|
||||||
icon: <CIcon icon={cilMenu} customClassName="nav-icon" />,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: CNavTitle,
|
component: CNavTitle,
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
import React from 'react'
|
import React, { useEffect, useState, useMemo } from 'react'
|
||||||
import { NavLink } from 'react-router-dom'
|
import { NavLink } from 'react-router-dom'
|
||||||
import { useSelector, useDispatch } from 'react-redux'
|
import { useSelector, useDispatch } from 'react-redux'
|
||||||
import { RootState } from 'src/store'
|
import { RootState } from 'src/store'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CCloseButton,
|
CCloseButton,
|
||||||
|
CNavGroup,
|
||||||
|
CNavItem,
|
||||||
|
CNavTitle,
|
||||||
CSidebar,
|
CSidebar,
|
||||||
CSidebarBrand,
|
CSidebarBrand,
|
||||||
CSidebarFooter,
|
CSidebarFooter,
|
||||||
@@ -12,6 +15,8 @@ import {
|
|||||||
CSidebarToggler,
|
CSidebarToggler,
|
||||||
} from '@coreui/react'
|
} from '@coreui/react'
|
||||||
import CIcon from '@coreui/icons-react'
|
import CIcon from '@coreui/icons-react'
|
||||||
|
import * as icons from '@coreui/icons'
|
||||||
|
import { cilMinus } from '@coreui/icons'
|
||||||
|
|
||||||
import { AppSidebarNav } from 'src/components/AppSidebarNav'
|
import { AppSidebarNav } from 'src/components/AppSidebarNav'
|
||||||
|
|
||||||
@@ -20,11 +25,98 @@ import { sygnet } from 'src/assets/brand/sygnet'
|
|||||||
|
|
||||||
// sidebar nav config
|
// sidebar nav config
|
||||||
import navigation from 'src/_nav'
|
import navigation from 'src/_nav'
|
||||||
|
import { getAdminMenuTree, AdminMenuTree } from 'src/services/adminMenuService'
|
||||||
|
|
||||||
|
// 아이콘 이름으로 아이콘 컴포넌트 가져오기 (최상위 메뉴용)
|
||||||
|
const getIconByName = (iconName: string) => {
|
||||||
|
const icon = (icons as Record<string, unknown>)[iconName]
|
||||||
|
if (icon) {
|
||||||
|
return <CIcon icon={icon as string[]} customClassName="nav-icon" />
|
||||||
|
}
|
||||||
|
// 아이콘이 없으면 기본 아이콘 표시
|
||||||
|
return <CIcon icon={cilMinus} customClassName="nav-icon" />
|
||||||
|
}
|
||||||
|
|
||||||
|
// 하위 메뉴용 아이콘 (깊이에 따른 들여쓰기 포함)
|
||||||
|
const getChildIcon = (iconName: string, depth: number) => {
|
||||||
|
const icon = (icons as Record<string, unknown>)[iconName]
|
||||||
|
const iconElement = icon ? (
|
||||||
|
<CIcon icon={icon as string[]} style={{ width: '1.25rem', height: '1.25rem' }} />
|
||||||
|
) : (
|
||||||
|
<CIcon icon={cilMinus} style={{ width: '1.25rem', height: '1.25rem' }} />
|
||||||
|
)
|
||||||
|
// 깊이에 따라 들여쓰기 증가 (2단계: 1rem, 3단계: 2rem, ...)
|
||||||
|
const paddingLeft = `${depth}rem`
|
||||||
|
return (
|
||||||
|
<span className="nav-icon" style={{ paddingLeft }}>
|
||||||
|
{iconElement}
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// API 응답을 CoreUI 네비게이션 형식으로 변환
|
||||||
|
const convertMenuTreeToNav = (menuTree: AdminMenuTree[], depth = 0): any[] => {
|
||||||
|
return menuTree.map((menu) => {
|
||||||
|
// 깊이가 0이면 최상위, 1 이상이면 하위 메뉴
|
||||||
|
const icon = depth === 0 ? getIconByName(menu.iconName) : getChildIcon(menu.iconName, depth)
|
||||||
|
|
||||||
|
if (menu.childMenuList && menu.childMenuList.length > 0) {
|
||||||
|
// 하위 메뉴가 있는 경우 CNavGroup 사용
|
||||||
|
return {
|
||||||
|
component: CNavGroup,
|
||||||
|
name: menu.menuName,
|
||||||
|
icon: icon,
|
||||||
|
items: convertMenuTreeToNav(menu.childMenuList, depth + 1),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 하위 메뉴가 없는 경우 CNavItem 사용
|
||||||
|
const navItem: any = {
|
||||||
|
component: CNavItem,
|
||||||
|
name: menu.menuName,
|
||||||
|
icon: icon,
|
||||||
|
indent: depth > 0,
|
||||||
|
}
|
||||||
|
// URL이 있는 경우에만 to 속성 추가
|
||||||
|
if (menu.menuUrl) {
|
||||||
|
navItem.to = menu.menuUrl
|
||||||
|
}
|
||||||
|
return navItem
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const AppSidebar = () => {
|
const AppSidebar = () => {
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
const unfoldable = useSelector((state: RootState) => state.sidebarUnfoldable)
|
const unfoldable = useSelector((state: RootState) => state.sidebarUnfoldable)
|
||||||
const sidebarShow = useSelector((state: RootState) => state.sidebarShow)
|
const sidebarShow = useSelector((state: RootState) => state.sidebarShow)
|
||||||
|
const [dynamicMenus, setDynamicMenus] = useState<AdminMenuTree[]>([])
|
||||||
|
|
||||||
|
// API에서 메뉴 트리 조회
|
||||||
|
useEffect(() => {
|
||||||
|
const fetchMenuTree = async () => {
|
||||||
|
try {
|
||||||
|
const menuTree = await getAdminMenuTree()
|
||||||
|
setDynamicMenus(menuTree)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('메뉴 트리 조회 실패:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fetchMenuTree()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// 동적 메뉴를 포함한 전체 네비게이션 생성
|
||||||
|
const fullNavigation = useMemo(() => {
|
||||||
|
const navItems = [...navigation]
|
||||||
|
// 'Menu' 타이틀 바로 다음에 동적 메뉴 삽입
|
||||||
|
const menuTitleIndex = navItems.findIndex(
|
||||||
|
(item) => item.name === 'Menu' && item.component === CNavTitle
|
||||||
|
)
|
||||||
|
if (menuTitleIndex !== -1 && dynamicMenus.length > 0) {
|
||||||
|
const dynamicNavItems = convertMenuTreeToNav(dynamicMenus)
|
||||||
|
navItems.splice(menuTitleIndex + 1, 0, ...dynamicNavItems)
|
||||||
|
}
|
||||||
|
return navItems
|
||||||
|
}, [dynamicMenus])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CSidebar
|
<CSidebar
|
||||||
@@ -48,7 +140,7 @@ const AppSidebar = () => {
|
|||||||
onClick={() => dispatch({ type: 'set', sidebarShow: false })}
|
onClick={() => dispatch({ type: 'set', sidebarShow: false })}
|
||||||
/>
|
/>
|
||||||
</CSidebarHeader>
|
</CSidebarHeader>
|
||||||
<AppSidebarNav items={navigation} />
|
<AppSidebarNav items={fullNavigation} />
|
||||||
<CSidebarFooter className="border-top d-none d-lg-flex">
|
<CSidebarFooter className="border-top d-none d-lg-flex">
|
||||||
<CSidebarToggler
|
<CSidebarToggler
|
||||||
onClick={() => dispatch({ type: 'set', sidebarUnfoldable: !unfoldable })}
|
onClick={() => dispatch({ type: 'set', sidebarUnfoldable: !unfoldable })}
|
||||||
|
|||||||
@@ -32,14 +32,9 @@ export const AppSidebarNav = ({ items }: AppSidebarNavProps) => {
|
|||||||
const navLink = (name?: string, icon?: React.ReactNode, badge?: Badge, indent = false) => {
|
const navLink = (name?: string, icon?: React.ReactNode, badge?: Badge, indent = false) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{icon
|
{icon && icon}
|
||||||
? icon
|
{indent && !icon && <span style={{ marginLeft: '1rem' }} />}
|
||||||
: indent && (
|
<span style={{ whiteSpace: 'nowrap' }}>{name && name}</span>
|
||||||
<span className="nav-icon">
|
|
||||||
<span className="nav-icon-bullet"></span>
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
{name && name}
|
|
||||||
{badge && (
|
{badge && (
|
||||||
<CBadge color={badge.color} className="ms-auto" size="sm">
|
<CBadge color={badge.color} className="ms-auto" size="sm">
|
||||||
{badge.text}
|
{badge.text}
|
||||||
@@ -54,7 +49,6 @@ export const AppSidebarNav = ({ items }: AppSidebarNavProps) => {
|
|||||||
const Component = component
|
const Component = component
|
||||||
return (
|
return (
|
||||||
<Component as="div" key={index}>
|
<Component as="div" key={index}>
|
||||||
{rest.to || rest.href ? (
|
|
||||||
<CNavLink
|
<CNavLink
|
||||||
{...(rest.to && { as: NavLink })}
|
{...(rest.to && { as: NavLink })}
|
||||||
{...(rest.href && { target: '_blank', rel: 'noopener noreferrer' })}
|
{...(rest.href && { target: '_blank', rel: 'noopener noreferrer' })}
|
||||||
@@ -62,9 +56,6 @@ export const AppSidebarNav = ({ items }: AppSidebarNavProps) => {
|
|||||||
>
|
>
|
||||||
{navLink(name, icon, badge, indent)}
|
{navLink(name, icon, badge, indent)}
|
||||||
</CNavLink>
|
</CNavLink>
|
||||||
) : (
|
|
||||||
navLink(name, icon, badge, indent)
|
|
||||||
)}
|
|
||||||
</Component>
|
</Component>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,11 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
const Dashboard = React.lazy(() => import('src/views/dashboard/Dashboard'))
|
const Dashboard = React.lazy(() => import('src/views/dashboard/Dashboard'))
|
||||||
const Colors = React.lazy(() => import('src/views/theme/colors/Colors'))
|
|
||||||
const Typography = React.lazy(() => import('src/views/theme/typography/Typography'))
|
|
||||||
const AdminMenuManagement = React.lazy(() => import('src/views/admin/AdminMenuManagement'))
|
const AdminMenuManagement = React.lazy(() => import('src/views/admin/AdminMenuManagement'))
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{ path: '/', exact: true, name: 'Home' },
|
{ path: '/', exact: true, name: 'Home' },
|
||||||
{ path: '/dashboard', name: 'Dashboard', element: Dashboard },
|
{ path: '/dashboard', name: 'Dashboard', element: Dashboard },
|
||||||
{ path: '/theme', name: 'Theme', element: Colors, exact: true },
|
|
||||||
{ path: '/theme/colors', name: 'Colors', element: Colors },
|
|
||||||
{ path: '/theme/typography', name: 'Typography', element: Typography },
|
|
||||||
{ path: '/admin/menu', name: 'Admin Menu Management', element: AdminMenuManagement },
|
{ path: '/admin/menu', name: 'Admin Menu Management', element: AdminMenuManagement },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
42
src/services/adminMemberService.ts
Normal file
42
src/services/adminMemberService.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import axios from 'src/axios/axios';
|
||||||
|
|
||||||
|
// 회원 정보 인터페이스
|
||||||
|
export interface AdminMember {
|
||||||
|
memberId: string;
|
||||||
|
memberName?: string;
|
||||||
|
email?: string;
|
||||||
|
password?: string;
|
||||||
|
// 필요한 경우 추가 필드 정의
|
||||||
|
}
|
||||||
|
|
||||||
|
// API 응답 인터페이스
|
||||||
|
export interface AdminMemberResponse {
|
||||||
|
resultCode: string;
|
||||||
|
resultMessage: string;
|
||||||
|
resultData?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 회원 추가
|
||||||
|
export const addAdminMember = async (member: AdminMember): Promise<AdminMemberResponse> => {
|
||||||
|
const response = await axios.post<AdminMemberResponse>('/admin/member/add', member);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 회원 수정
|
||||||
|
export const updateAdminMember = async (member: AdminMember): Promise<AdminMemberResponse> => {
|
||||||
|
const response = await axios.post<AdminMemberResponse>('/admin/member/update', member);
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 회원 상세 조회
|
||||||
|
export const getAdminMember = async (memberId: string): Promise<AdminMember> => {
|
||||||
|
const response = await axios.get<AdminMemberResponse>(`/admin/member/${memberId}`);
|
||||||
|
return response.data.resultData;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 회원 삭제
|
||||||
|
export const deleteAdminMember = async (memberId: string): Promise<AdminMemberResponse> => {
|
||||||
|
const response = await axios.post<AdminMemberResponse>('/admin/member/delete', { memberId });
|
||||||
|
return response.data;
|
||||||
|
};
|
||||||
|
|
||||||
@@ -11,6 +11,18 @@ export interface AdminMenu {
|
|||||||
level: number;
|
level: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 트리 구조 메뉴 인터페이스
|
||||||
|
export interface AdminMenuTree {
|
||||||
|
adminMenuSeq: number;
|
||||||
|
parentSeq: number;
|
||||||
|
menuOrder: number;
|
||||||
|
menuName: string;
|
||||||
|
iconName: string;
|
||||||
|
menuUrl: string;
|
||||||
|
level: number;
|
||||||
|
childMenuList: AdminMenuTree[] | null;
|
||||||
|
}
|
||||||
|
|
||||||
// 페이징 정보 인터페이스
|
// 페이징 정보 인터페이스
|
||||||
export interface PageInfo {
|
export interface PageInfo {
|
||||||
pageNum: number;
|
pageNum: number;
|
||||||
@@ -91,3 +103,9 @@ export const deleteAdminMenu = async (adminMenuSeq: number): Promise<AdminMenuRe
|
|||||||
const response = await axios.post<AdminMenuResponse>('/admin/menu/delete', { adminMenuSeq });
|
const response = await axios.post<AdminMenuResponse>('/admin/menu/delete', { adminMenuSeq });
|
||||||
return response.data;
|
return response.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 어드민 메뉴 트리 조회 (로그인 회원 레벨 기준)
|
||||||
|
export const getAdminMenuTree = async (): Promise<AdminMenuTree[]> => {
|
||||||
|
const response = await axios.get<AdminMenuResponse>('/admin/menu/tree');
|
||||||
|
return response.data.resultData || [];
|
||||||
|
};
|
||||||
|
|||||||
@@ -642,7 +642,7 @@ const AdminMenuManagement: React.FC = () => {
|
|||||||
</CCard>
|
</CCard>
|
||||||
|
|
||||||
{/* 추가/수정 모달 */}
|
{/* 추가/수정 모달 */}
|
||||||
<CModal visible={modalVisible} onClose={() => { setModalVisible(false); setIconPickerVisible(false); }}>
|
<CModal visible={modalVisible} onClose={() => { setModalVisible(false); setIconPickerVisible(false); }} backdrop="static">
|
||||||
<CModalHeader>
|
<CModalHeader>
|
||||||
<CModalTitle>{isEditMode ? '메뉴 수정' : '메뉴 추가'}</CModalTitle>
|
<CModalTitle>{isEditMode ? '메뉴 수정' : '메뉴 추가'}</CModalTitle>
|
||||||
</CModalHeader>
|
</CModalHeader>
|
||||||
@@ -785,7 +785,7 @@ const AdminMenuManagement: React.FC = () => {
|
|||||||
</CModal>
|
</CModal>
|
||||||
|
|
||||||
{/* 삭제 확인 모달 */}
|
{/* 삭제 확인 모달 */}
|
||||||
<CModal visible={deleteModalVisible} onClose={() => setDeleteModalVisible(false)}>
|
<CModal visible={deleteModalVisible} onClose={() => setDeleteModalVisible(false)} backdrop="static">
|
||||||
<CModalHeader>
|
<CModalHeader>
|
||||||
<CModalTitle>메뉴 삭제</CModalTitle>
|
<CModalTitle>메뉴 삭제</CModalTitle>
|
||||||
</CModalHeader>
|
</CModalHeader>
|
||||||
|
|||||||
@@ -1,91 +0,0 @@
|
|||||||
import React, { useEffect, useState, createRef } from 'react'
|
|
||||||
import PropTypes from 'prop-types'
|
|
||||||
import classNames from 'classnames'
|
|
||||||
import { CRow, CCol, CCard, CCardHeader, CCardBody } from '@coreui/react'
|
|
||||||
import { rgbToHex } from '@coreui/utils'
|
|
||||||
import { DocsLink } from 'src/components'
|
|
||||||
|
|
||||||
const ThemeView = () => {
|
|
||||||
const [color, setColor] = useState('rgb(255, 255, 255)')
|
|
||||||
const ref = createRef()
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const el = ref.current.parentNode.firstChild
|
|
||||||
const varColor = window.getComputedStyle(el).getPropertyValue('background-color')
|
|
||||||
setColor(varColor)
|
|
||||||
}, [ref])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<table className="table w-100" ref={ref}>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td className="text-body-secondary">HEX:</td>
|
|
||||||
<td className="font-weight-bold">{rgbToHex(color)}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td className="text-body-secondary">RGB:</td>
|
|
||||||
<td className="font-weight-bold">{color}</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const ThemeColor = ({ className, children }) => {
|
|
||||||
const classes = classNames(className, 'theme-color w-75 rounded mb-3')
|
|
||||||
return (
|
|
||||||
<CCol xs={12} sm={6} md={4} xl={2} className="mb-4">
|
|
||||||
<div className={classes} style={{ paddingTop: '75%' }}></div>
|
|
||||||
{children}
|
|
||||||
<ThemeView />
|
|
||||||
</CCol>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
ThemeColor.propTypes = {
|
|
||||||
children: PropTypes.node,
|
|
||||||
className: PropTypes.string,
|
|
||||||
}
|
|
||||||
|
|
||||||
const Colors = () => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<CCard className="mb-4">
|
|
||||||
<CCardHeader>
|
|
||||||
Theme colors
|
|
||||||
<DocsLink href="https://coreui.io/docs/utilities/colors/" />
|
|
||||||
</CCardHeader>
|
|
||||||
<CCardBody>
|
|
||||||
<CRow>
|
|
||||||
<ThemeColor className="bg-primary">
|
|
||||||
<h6>Brand Primary Color</h6>
|
|
||||||
</ThemeColor>
|
|
||||||
<ThemeColor className="bg-secondary">
|
|
||||||
<h6>Brand Secondary Color</h6>
|
|
||||||
</ThemeColor>
|
|
||||||
<ThemeColor className="bg-success">
|
|
||||||
<h6>Brand Success Color</h6>
|
|
||||||
</ThemeColor>
|
|
||||||
<ThemeColor className="bg-danger">
|
|
||||||
<h6>Brand Danger Color</h6>
|
|
||||||
</ThemeColor>
|
|
||||||
<ThemeColor className="bg-warning">
|
|
||||||
<h6>Brand Warning Color</h6>
|
|
||||||
</ThemeColor>
|
|
||||||
<ThemeColor className="bg-info">
|
|
||||||
<h6>Brand Info Color</h6>
|
|
||||||
</ThemeColor>
|
|
||||||
<ThemeColor className="bg-light">
|
|
||||||
<h6>Brand Light Color</h6>
|
|
||||||
</ThemeColor>
|
|
||||||
<ThemeColor className="bg-dark">
|
|
||||||
<h6>Brand Dark Color</h6>
|
|
||||||
</ThemeColor>
|
|
||||||
</CRow>
|
|
||||||
</CCardBody>
|
|
||||||
</CCard>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Colors
|
|
||||||
@@ -1,229 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import { CCard, CCardHeader, CCardBody } from '@coreui/react'
|
|
||||||
import { DocsLink } from 'src/components'
|
|
||||||
|
|
||||||
const Typography = () => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<CCard className="mb-4">
|
|
||||||
<CCardHeader>
|
|
||||||
Headings
|
|
||||||
<DocsLink href="https://coreui.io/docs/content/typography/" />
|
|
||||||
</CCardHeader>
|
|
||||||
<CCardBody>
|
|
||||||
<p>
|
|
||||||
Documentation and examples for Bootstrap typography, including global settings,
|
|
||||||
headings, body text, lists, and more.
|
|
||||||
</p>
|
|
||||||
<table className="table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Heading</th>
|
|
||||||
<th>Example</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<p>
|
|
||||||
<code className="highlighter-rouge"><h1></h1></code>
|
|
||||||
</p>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span className="h1">h1. Bootstrap heading</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<p>
|
|
||||||
<code className="highlighter-rouge"><h2></h2></code>
|
|
||||||
</p>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span className="h2">h2. Bootstrap heading</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<p>
|
|
||||||
<code className="highlighter-rouge"><h3></h3></code>
|
|
||||||
</p>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span className="h3">h3. Bootstrap heading</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<p>
|
|
||||||
<code className="highlighter-rouge"><h4></h4></code>
|
|
||||||
</p>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span className="h4">h4. Bootstrap heading</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<p>
|
|
||||||
<code className="highlighter-rouge"><h5></h5></code>
|
|
||||||
</p>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span className="h5">h5. Bootstrap heading</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<p>
|
|
||||||
<code className="highlighter-rouge"><h6></h6></code>
|
|
||||||
</p>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<span className="h6">h6. Bootstrap heading</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</CCardBody>
|
|
||||||
</CCard>
|
|
||||||
<CCard className="mb-4">
|
|
||||||
<CCardHeader>Headings</CCardHeader>
|
|
||||||
<CCardBody>
|
|
||||||
<p>
|
|
||||||
<code className="highlighter-rouge">.h1</code> through
|
|
||||||
<code className="highlighter-rouge">.h6</code>
|
|
||||||
classes are also available, for when you want to match the font styling of a heading but
|
|
||||||
cannot use the associated HTML element.
|
|
||||||
</p>
|
|
||||||
<div className="bd-example">
|
|
||||||
<p className="h1">h1. Bootstrap heading</p>
|
|
||||||
<p className="h2">h2. Bootstrap heading</p>
|
|
||||||
<p className="h3">h3. Bootstrap heading</p>
|
|
||||||
<p className="h4">h4. Bootstrap heading</p>
|
|
||||||
<p className="h5">h5. Bootstrap heading</p>
|
|
||||||
<p className="h6">h6. Bootstrap heading</p>
|
|
||||||
</div>
|
|
||||||
</CCardBody>
|
|
||||||
</CCard>
|
|
||||||
<CCard className="mb-4">
|
|
||||||
<div className="card-header">Display headings</div>
|
|
||||||
<div className="card-body">
|
|
||||||
<p>
|
|
||||||
Traditional heading elements are designed to work best in the meat of your page content.
|
|
||||||
When you need a heading to stand out, consider using a <strong>display heading</strong>
|
|
||||||
—a larger, slightly more opinionated heading style.
|
|
||||||
</p>
|
|
||||||
<div className="bd-example bd-example-type">
|
|
||||||
<table className="table">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span className="display-1">Display 1</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span className="display-2">Display 2</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span className="display-3">Display 3</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<span className="display-4">Display 4</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</CCard>
|
|
||||||
<CCard className="mb-4">
|
|
||||||
<CCardHeader>Inline text elements</CCardHeader>
|
|
||||||
<CCardBody>
|
|
||||||
<p>
|
|
||||||
Traditional heading elements are designed to work best in the meat of your page content.
|
|
||||||
When you need a heading to stand out, consider using a <strong>display heading</strong>
|
|
||||||
—a larger, slightly more opinionated heading style.
|
|
||||||
</p>
|
|
||||||
<div className="bd-example">
|
|
||||||
<p>
|
|
||||||
You can use the mark tag to <mark>highlight</mark> text.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<del>This line of text is meant to be treated as deleted text.</del>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<s>This line of text is meant to be treated as no longer accurate.</s>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<ins>This line of text is meant to be treated as an addition to the document.</ins>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<u>This line of text will render as underlined</u>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<small>This line of text is meant to be treated as fine print.</small>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<strong>This line rendered as bold text.</strong>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<em>This line rendered as italicized text.</em>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</CCardBody>
|
|
||||||
</CCard>
|
|
||||||
<CCard className="mb-4">
|
|
||||||
<CCardHeader>Description list alignment</CCardHeader>
|
|
||||||
<CCardBody>
|
|
||||||
<p>
|
|
||||||
Align terms and descriptions horizontally by using our grid system’s predefined classes
|
|
||||||
(or semantic mixins). For longer terms, you can optionally add a{' '}
|
|
||||||
<code className="highlighter-rouge">.text-truncate</code> class to truncate the text
|
|
||||||
with an ellipsis.
|
|
||||||
</p>
|
|
||||||
<div className="bd-example">
|
|
||||||
<dl className="row">
|
|
||||||
<dt className="col-sm-3">Description lists</dt>
|
|
||||||
<dd className="col-sm-9">A description list is perfect for defining terms.</dd>
|
|
||||||
|
|
||||||
<dt className="col-sm-3">Euismod</dt>
|
|
||||||
<dd className="col-sm-9">
|
|
||||||
<p>
|
|
||||||
Vestibulum id ligula porta felis euismod semper eget lacinia odio sem nec elit.
|
|
||||||
</p>
|
|
||||||
<p>Donec id elit non mi porta gravida at eget metus.</p>
|
|
||||||
</dd>
|
|
||||||
|
|
||||||
<dt className="col-sm-3">Malesuada porta</dt>
|
|
||||||
<dd className="col-sm-9">Etiam porta sem malesuada magna mollis euismod.</dd>
|
|
||||||
|
|
||||||
<dt className="col-sm-3 text-truncate">Truncated term is truncated</dt>
|
|
||||||
<dd className="col-sm-9">
|
|
||||||
Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut
|
|
||||||
fermentum massa justo sit amet risus.
|
|
||||||
</dd>
|
|
||||||
|
|
||||||
<dt className="col-sm-3">Nesting</dt>
|
|
||||||
<dd className="col-sm-9">
|
|
||||||
<dl className="row">
|
|
||||||
<dt className="col-sm-4">Nested definition list</dt>
|
|
||||||
<dd className="col-sm-8">
|
|
||||||
Aenean posuere, tortor sed cursus feugiat, nunc augue blandit nunc.
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
</div>
|
|
||||||
</CCardBody>
|
|
||||||
</CCard>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Typography
|
|
||||||
Reference in New Issue
Block a user