왼쪽메뉴에 어드민 메뉴의 트리구조 리스트 api 값을 사용하도록 기능 추가
This commit is contained in:
37
src/_nav.tsx
37
src/_nav.tsx
@@ -1,21 +1,8 @@
|
||||
import React from 'react'
|
||||
import CIcon from '@coreui/icons-react'
|
||||
import {
|
||||
cilBell,
|
||||
cilBrowser,
|
||||
cilBoatAlt,
|
||||
cilCalculator,
|
||||
cilChartPie,
|
||||
cilCursor,
|
||||
cilDescription,
|
||||
cilDrop,
|
||||
cilExternalLink,
|
||||
cilNotes,
|
||||
cilPencil,
|
||||
cilPuzzle,
|
||||
cilSpeedometer,
|
||||
cilStar,
|
||||
cilMenu,
|
||||
} from '@coreui/icons'
|
||||
import { CNavGroup, CNavItem, CNavTitle } from '@coreui/react'
|
||||
|
||||
@@ -32,29 +19,7 @@ const _nav = [
|
||||
},
|
||||
{
|
||||
component: CNavTitle,
|
||||
name: 'Theme',
|
||||
},
|
||||
{
|
||||
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" />,
|
||||
name: 'Menu',
|
||||
},
|
||||
{
|
||||
component: CNavTitle,
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import React from 'react'
|
||||
import React, { useEffect, useState, useMemo } from 'react'
|
||||
import { NavLink } from 'react-router-dom'
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
import { RootState } from 'src/store'
|
||||
|
||||
import {
|
||||
CCloseButton,
|
||||
CNavGroup,
|
||||
CNavItem,
|
||||
CNavTitle,
|
||||
CSidebar,
|
||||
CSidebarBrand,
|
||||
CSidebarFooter,
|
||||
@@ -12,6 +15,8 @@ import {
|
||||
CSidebarToggler,
|
||||
} from '@coreui/react'
|
||||
import CIcon from '@coreui/icons-react'
|
||||
import * as icons from '@coreui/icons'
|
||||
import { cilMinus } from '@coreui/icons'
|
||||
|
||||
import { AppSidebarNav } from 'src/components/AppSidebarNav'
|
||||
|
||||
@@ -20,11 +25,98 @@ import { sygnet } from 'src/assets/brand/sygnet'
|
||||
|
||||
// sidebar nav config
|
||||
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 dispatch = useDispatch()
|
||||
const unfoldable = useSelector((state: RootState) => state.sidebarUnfoldable)
|
||||
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 (
|
||||
<CSidebar
|
||||
@@ -48,7 +140,7 @@ const AppSidebar = () => {
|
||||
onClick={() => dispatch({ type: 'set', sidebarShow: false })}
|
||||
/>
|
||||
</CSidebarHeader>
|
||||
<AppSidebarNav items={navigation} />
|
||||
<AppSidebarNav items={fullNavigation} />
|
||||
<CSidebarFooter className="border-top d-none d-lg-flex">
|
||||
<CSidebarToggler
|
||||
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) => {
|
||||
return (
|
||||
<>
|
||||
{icon
|
||||
? icon
|
||||
: indent && (
|
||||
<span className="nav-icon">
|
||||
<span className="nav-icon-bullet"></span>
|
||||
</span>
|
||||
)}
|
||||
{name && name}
|
||||
{icon && icon}
|
||||
{indent && !icon && <span style={{ marginLeft: '1rem' }} />}
|
||||
<span style={{ whiteSpace: 'nowrap' }}>{name && name}</span>
|
||||
{badge && (
|
||||
<CBadge color={badge.color} className="ms-auto" size="sm">
|
||||
{badge.text}
|
||||
@@ -54,17 +49,13 @@ export const AppSidebarNav = ({ items }: AppSidebarNavProps) => {
|
||||
const Component = component
|
||||
return (
|
||||
<Component as="div" key={index}>
|
||||
{rest.to || rest.href ? (
|
||||
<CNavLink
|
||||
{...(rest.to && { as: NavLink })}
|
||||
{...(rest.href && { target: '_blank', rel: 'noopener noreferrer' })}
|
||||
{...rest}
|
||||
>
|
||||
{navLink(name, icon, badge, indent)}
|
||||
</CNavLink>
|
||||
) : (
|
||||
navLink(name, icon, badge, indent)
|
||||
)}
|
||||
<CNavLink
|
||||
{...(rest.to && { as: NavLink })}
|
||||
{...(rest.href && { target: '_blank', rel: 'noopener noreferrer' })}
|
||||
{...rest}
|
||||
>
|
||||
{navLink(name, icon, badge, indent)}
|
||||
</CNavLink>
|
||||
</Component>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
import React from 'react'
|
||||
|
||||
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 routes = [
|
||||
{ path: '/', exact: true, name: 'Home' },
|
||||
{ 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 },
|
||||
]
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 트리 구조 메뉴 인터페이스
|
||||
export interface AdminMenuTree {
|
||||
adminMenuSeq: number;
|
||||
parentSeq: number;
|
||||
menuOrder: number;
|
||||
menuName: string;
|
||||
iconName: string;
|
||||
menuUrl: string;
|
||||
level: number;
|
||||
childMenuList: AdminMenuTree[] | null;
|
||||
}
|
||||
|
||||
// 페이징 정보 인터페이스
|
||||
export interface PageInfo {
|
||||
pageNum: number;
|
||||
@@ -91,3 +103,9 @@ export const deleteAdminMenu = async (adminMenuSeq: number): Promise<AdminMenuRe
|
||||
const response = await axios.post<AdminMenuResponse>('/admin/menu/delete', { adminMenuSeq });
|
||||
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>
|
||||
|
||||
{/* 추가/수정 모달 */}
|
||||
<CModal visible={modalVisible} onClose={() => { setModalVisible(false); setIconPickerVisible(false); }}>
|
||||
<CModal visible={modalVisible} onClose={() => { setModalVisible(false); setIconPickerVisible(false); }} backdrop="static">
|
||||
<CModalHeader>
|
||||
<CModalTitle>{isEditMode ? '메뉴 수정' : '메뉴 추가'}</CModalTitle>
|
||||
</CModalHeader>
|
||||
@@ -785,7 +785,7 @@ const AdminMenuManagement: React.FC = () => {
|
||||
</CModal>
|
||||
|
||||
{/* 삭제 확인 모달 */}
|
||||
<CModal visible={deleteModalVisible} onClose={() => setDeleteModalVisible(false)}>
|
||||
<CModal visible={deleteModalVisible} onClose={() => setDeleteModalVisible(false)} backdrop="static">
|
||||
<CModalHeader>
|
||||
<CModalTitle>메뉴 삭제</CModalTitle>
|
||||
</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