mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-07-24 03:05:45 +00:00
Add Pezkuwi SDK UI - Polkadot.js Apps clone
- Clone Polkadot.js Apps repository - Update package.json with Pezkuwi branding - Add Pezkuwi endpoint to production chains (wss://pezkuwichain.app:9944) - Create comprehensive README for SDK UI - Set up project structure with all packages Next steps: - Apply Kurdistan colors (Kesk, Sor, Zer, Spi + Black) to UI theme - Replace logos with Pezkuwi branding - Test build and deployment
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
// Copyright 2017-2025 @polkadot/react-components authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { isString } from '@polkadot/util';
|
||||
|
||||
import Spinner from '../Spinner.js';
|
||||
|
||||
interface Props {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
empty?: React.ReactNode | false;
|
||||
emptySpinner?: React.ReactNode;
|
||||
isEmpty: boolean;
|
||||
noBodyTag?: boolean;
|
||||
}
|
||||
|
||||
function Body ({ children, className = '', empty, emptySpinner, isEmpty, noBodyTag }: Props): React.ReactElement<Props> {
|
||||
const bodyClassName = `${className} ui--Table-Body`;
|
||||
|
||||
return isEmpty
|
||||
? (
|
||||
<tbody className={bodyClassName}>
|
||||
<tr>
|
||||
<td colSpan={100}>{
|
||||
isString(empty)
|
||||
? <div className='empty'>{empty}</div>
|
||||
: empty || <Spinner label={emptySpinner} />
|
||||
}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
)
|
||||
: noBodyTag
|
||||
? <>{children}</>
|
||||
: <tbody className={bodyClassName}>{children}</tbody>;
|
||||
}
|
||||
|
||||
export default React.memo(Body);
|
||||
@@ -0,0 +1,48 @@
|
||||
// Copyright 2017-2025 @polkadot/react-components authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { BN } from '@polkadot/util';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { FormatBalance } from '@polkadot/react-query';
|
||||
|
||||
export interface Props {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
colSpan?: number;
|
||||
label?: React.ReactNode;
|
||||
labelPost?: React.ReactNode;
|
||||
rowSpan?: number;
|
||||
value?: BN | null;
|
||||
withLoading?: boolean;
|
||||
}
|
||||
|
||||
function Balance ({ children, className = '', colSpan, label, labelPost, rowSpan, value, withLoading }: Props): React.ReactElement<Props> {
|
||||
return (
|
||||
<td
|
||||
className={`${className} ui--Table-Column-Balance number`}
|
||||
colSpan={colSpan}
|
||||
rowSpan={rowSpan}
|
||||
>
|
||||
{value
|
||||
? (
|
||||
<FormatBalance
|
||||
label={label}
|
||||
labelPost={labelPost}
|
||||
value={value}
|
||||
/>
|
||||
)
|
||||
: withLoading && (
|
||||
<FormatBalance
|
||||
className='--tmp'
|
||||
value={1}
|
||||
/>
|
||||
)
|
||||
}
|
||||
{children}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
|
||||
export default React.memo(Balance);
|
||||
@@ -0,0 +1,60 @@
|
||||
// Copyright 2017-2025 @polkadot/react-components authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Icon from '../../Icon.js';
|
||||
import { styled } from '../../styled.js';
|
||||
|
||||
export interface Props {
|
||||
className?: string;
|
||||
colSpan?: number;
|
||||
rowSpan?: number;
|
||||
isExpanded: boolean;
|
||||
toggle: () => void;
|
||||
}
|
||||
|
||||
function Expand ({ className = '', colSpan, isExpanded, rowSpan, toggle }: Props): React.ReactElement<Props> {
|
||||
return (
|
||||
<StyledTd
|
||||
className={`${className} ui--Table-Column-Expand`}
|
||||
colSpan={colSpan}
|
||||
onClick={toggle}
|
||||
rowSpan={rowSpan}
|
||||
>
|
||||
<div>
|
||||
<Icon
|
||||
icon={
|
||||
isExpanded
|
||||
? 'caret-up'
|
||||
: 'caret-down'
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</StyledTd>
|
||||
);
|
||||
}
|
||||
|
||||
const StyledTd = styled.td`
|
||||
&& {
|
||||
box-sizing: content-box;
|
||||
cursor: pointer;
|
||||
min-width: 1.7rem;
|
||||
padding-left: 0;
|
||||
text-align: left;
|
||||
width: 1.7rem;
|
||||
|
||||
> div {
|
||||
align-items: center;
|
||||
border: 1px solid var(--border-table);
|
||||
border-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
height: 1.7rem;
|
||||
justify-content: center;
|
||||
width: 1.7rem;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default React.memo(Expand);
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright 2017-2025 @polkadot/react-components authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import React, { useCallback } from 'react';
|
||||
|
||||
import Icon from '../../Icon.js';
|
||||
import { styled } from '../../styled.js';
|
||||
|
||||
export interface Props {
|
||||
address: string;
|
||||
className?: string;
|
||||
colSpan?: number;
|
||||
isFavorite: boolean;
|
||||
rowSpan?: number;
|
||||
toggle: (address: string) => void;
|
||||
}
|
||||
|
||||
function Favorite ({ address, className = '', colSpan, isFavorite, rowSpan, toggle }: Props): React.ReactElement<Props> {
|
||||
const onClick = useCallback(
|
||||
() => toggle(address),
|
||||
[address, toggle]
|
||||
);
|
||||
|
||||
return (
|
||||
<StyledTd
|
||||
className={`${className} ui--Table-Column-Favorite`}
|
||||
colSpan={colSpan}
|
||||
onClick={onClick}
|
||||
rowSpan={rowSpan}
|
||||
>
|
||||
<Icon
|
||||
color={
|
||||
isFavorite
|
||||
? 'orange'
|
||||
: 'gray'
|
||||
}
|
||||
icon='star'
|
||||
/>
|
||||
</StyledTd>
|
||||
);
|
||||
}
|
||||
|
||||
const StyledTd = styled.td`
|
||||
&& {
|
||||
box-sizing: content-box;
|
||||
cursor: pointer;
|
||||
min-width: 1rem;
|
||||
padding-right: 0.35rem;
|
||||
text-align: right;
|
||||
width: 1rem;
|
||||
}
|
||||
`;
|
||||
|
||||
export default React.memo(Favorite);
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright 2017-2025 @polkadot/react-components authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import type { BN } from '@polkadot/util';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { formatNumber } from '@polkadot/util';
|
||||
|
||||
import { styled } from '../../styled.js';
|
||||
|
||||
export interface Props {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
colSpan?: number;
|
||||
rowSpan?: number;
|
||||
value: BN | number;
|
||||
}
|
||||
|
||||
function Id ({ children, className = '', colSpan, rowSpan, value }: Props): React.ReactElement<Props> {
|
||||
return (
|
||||
<StyledTd
|
||||
className={`${className} ui--Table-Column-Id`}
|
||||
colSpan={colSpan}
|
||||
rowSpan={rowSpan}
|
||||
>
|
||||
<h2 className='--digits'>{formatNumber(value)}</h2>
|
||||
{children}
|
||||
</StyledTd>
|
||||
);
|
||||
}
|
||||
|
||||
// We want 5.5ch (which should be ok-ish for 5 decimals, i.e. 99,999), however
|
||||
// we wrap the display in an h2 with max size text at ~1.3rem, so multiply it out
|
||||
const WIDTH = `${(5.5 * 1.3).toFixed(3)}ch`;
|
||||
|
||||
const StyledTd = styled.td`
|
||||
&& {
|
||||
box-sizing: content-box;
|
||||
min-width: ${WIDTH};
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
width: ${WIDTH};
|
||||
`;
|
||||
|
||||
export default React.memo(Id);
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright 2017-2025 @polkadot/react-components authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import Balance from './Balance.js';
|
||||
import Expand from './Expand.js';
|
||||
import Favorite from './Favorite.js';
|
||||
import Id from './Id.js';
|
||||
|
||||
interface Props {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
function ColumnBase ({ children, className = '' }: Props): React.ReactElement<Props> {
|
||||
return (
|
||||
<td className={`${className} ui--Table-Column`}>
|
||||
{children}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
|
||||
const Column = React.memo(ColumnBase) as unknown as typeof ColumnBase & {
|
||||
Balance: typeof Balance,
|
||||
Expand: typeof Expand,
|
||||
Favorite: typeof Favorite,
|
||||
Id: typeof Id
|
||||
};
|
||||
|
||||
Column.Balance = Balance;
|
||||
Column.Expand = Expand;
|
||||
Column.Favorite = Favorite;
|
||||
Column.Id = Id;
|
||||
|
||||
export default Column;
|
||||
@@ -0,0 +1,42 @@
|
||||
// Copyright 2017-2025 @polkadot/react-components authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { styled } from '../styled.js';
|
||||
|
||||
interface Props {
|
||||
className?: string;
|
||||
footer?: React.ReactNode;
|
||||
isEmpty: boolean;
|
||||
}
|
||||
|
||||
function Foot ({ className = '', footer, isEmpty }: Props): React.ReactElement<Props> | null {
|
||||
if (!footer || isEmpty) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledTfoot className={`${className} ui--Table-Foot`}>
|
||||
{footer}
|
||||
</StyledTfoot>
|
||||
);
|
||||
}
|
||||
|
||||
const StyledTfoot = styled.tfoot`
|
||||
td {
|
||||
color: var(--color-table-foot);
|
||||
font: var(--font-sans);
|
||||
font-weight: var(--font-weight-normal);
|
||||
padding: 0.75rem 1rem 0.25rem;
|
||||
text-align: right;
|
||||
vertical-align: baseline;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
tr {
|
||||
background: var(--bg-page);
|
||||
}
|
||||
`;
|
||||
|
||||
export default React.memo(Foot);
|
||||
@@ -0,0 +1,147 @@
|
||||
// Copyright 2017-2025 @polkadot/react-components authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { styled } from '../styled.js';
|
||||
|
||||
type HeaderDef = [React.ReactNode?, string?, number?, (() => void)?];
|
||||
|
||||
interface Props {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
filter?: React.ReactNode;
|
||||
header?: (false | null | undefined | HeaderDef)[];
|
||||
isEmpty: boolean;
|
||||
}
|
||||
|
||||
function Head ({ children, className = '', filter, header, isEmpty }: Props): React.ReactElement<Props> | null {
|
||||
if (!header?.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledThead className={`${className} ui--Table-Head`}>
|
||||
{filter && (
|
||||
<tr className='filter'>
|
||||
<th colSpan={100}>{filter}</th>
|
||||
</tr>
|
||||
)}
|
||||
<tr>
|
||||
{header.filter((h): h is HeaderDef => !!h).map(([label, className = 'default', colSpan = 1, onClick], index) =>
|
||||
<th
|
||||
className={className}
|
||||
colSpan={colSpan}
|
||||
key={index}
|
||||
onClick={onClick}
|
||||
>
|
||||
{index === 0
|
||||
? <h1>{label}</h1>
|
||||
: !isEmpty && label && <label>{label}</label>
|
||||
}
|
||||
</th>
|
||||
)}
|
||||
</tr>
|
||||
{children}
|
||||
</StyledThead>
|
||||
);
|
||||
}
|
||||
|
||||
const StyledThead = styled.thead`
|
||||
z-index: 1;
|
||||
|
||||
th {
|
||||
background: var(--bg-table);
|
||||
font: var(--font-sans);
|
||||
font-weight: var(--font-weight-normal);
|
||||
padding: 0.375rem 1rem;
|
||||
text-align: right;
|
||||
vertical-align: middle;
|
||||
white-space: nowrap;
|
||||
|
||||
h1 {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
|
||||
.sub {
|
||||
display: inline-block;
|
||||
font-size: var(--font-size-base);
|
||||
font-weight: var(--font-weight-normal);
|
||||
opacity: var(--opacity-light);
|
||||
padding-left: 1.5rem;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
> label {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
&.address {
|
||||
padding-left: 3rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
&.badge {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&.expand,
|
||||
&.number {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&.isClickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.mini {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
&.no-pad-left {
|
||||
padding-left: 0.125rem;
|
||||
}
|
||||
|
||||
&.no-pad-right {
|
||||
padding-right: 0.125rem;
|
||||
}
|
||||
|
||||
&.start {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
&.balances {
|
||||
text-align: right;
|
||||
padding-right: 2.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
tr {
|
||||
text-transform: lowercase;
|
||||
|
||||
&.filter {
|
||||
.ui.input,
|
||||
.ui.selection.dropdown {
|
||||
background: transparent;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
th {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.filter) {
|
||||
th {
|
||||
color: var(--color-table-head);
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default React.memo(Head);
|
||||
@@ -0,0 +1,21 @@
|
||||
// Copyright 2017-2025 @polkadot/react-components authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import React from 'react';
|
||||
|
||||
interface Props {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
function RowBase ({ children, className = '' }: Props): React.ReactElement<Props> {
|
||||
return (
|
||||
<tr className={`${className} ui--Table-Row`}>
|
||||
{children}
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
|
||||
const Row = React.memo(RowBase) as unknown as typeof RowBase;
|
||||
|
||||
export default Row;
|
||||
@@ -0,0 +1,552 @@
|
||||
// Copyright 2017-2025 @polkadot/react-components authors & contributors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { useWindowColumns } from '@polkadot/react-hooks';
|
||||
|
||||
import { styled } from '../styled.js';
|
||||
import Column from './Column/index.js';
|
||||
import Row from './Row/index.js';
|
||||
import Body from './Body.js';
|
||||
import Foot from './Foot.js';
|
||||
import Head from './Head.js';
|
||||
|
||||
interface Props {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
empty?: React.ReactNode | false;
|
||||
emptySpinner?: React.ReactNode;
|
||||
filter?: React.ReactNode;
|
||||
footer?: React.ReactNode;
|
||||
header?: ([React.ReactNode?, string?, number?, (() => void)?] | false | null | undefined)[];
|
||||
headerChildren?: React.ReactNode;
|
||||
isFixed?: boolean;
|
||||
isInline?: boolean;
|
||||
isSplit?: boolean;
|
||||
legend?: React.ReactNode;
|
||||
maxColumns?: 2 | 3;
|
||||
noBodyTag?: boolean;
|
||||
}
|
||||
|
||||
const COLUMN_INDEXES = {
|
||||
2: [0, 1],
|
||||
3: [0, 1, 2]
|
||||
} as const;
|
||||
|
||||
function TableBase ({ children, className = '', empty, emptySpinner, filter, footer, header, headerChildren, isFixed, isInline, isSplit, legend, maxColumns, noBodyTag }: Props): React.ReactElement<Props> {
|
||||
const numColumns = useWindowColumns(maxColumns);
|
||||
const isArray = Array.isArray(children);
|
||||
const isEmpty = !children || (isArray && children.length === 0);
|
||||
|
||||
const headerNode = (
|
||||
<Head
|
||||
filter={filter}
|
||||
header={header}
|
||||
isEmpty={isEmpty}
|
||||
>
|
||||
{headerChildren}
|
||||
</Head>
|
||||
);
|
||||
|
||||
if (isSplit && isArray && !isEmpty && (numColumns !== 1)) {
|
||||
return (
|
||||
<StyledDiv className={`${className} ui--Table isSplit`}>
|
||||
{legend}
|
||||
<table className='noMargin'>
|
||||
{headerNode}
|
||||
</table>
|
||||
<div className='ui--Table-Split'>
|
||||
{COLUMN_INDEXES[numColumns].map((column) => (
|
||||
<div
|
||||
className={`ui--Table-Split-${numColumns}`}
|
||||
key={column}
|
||||
>
|
||||
<table className='noMargin'>
|
||||
<tbody className='ui--Table-Body'>
|
||||
{children.filter((_, i) => (i % numColumns) === column)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</StyledDiv>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledDiv className={`${className} ui--Table`}>
|
||||
{legend}
|
||||
<table className={`${(isFixed && !isEmpty) ? 'isFixed' : 'isNotFixed'} ${isInline ? 'isInline' : ''}`}>
|
||||
{headerNode}
|
||||
<Body
|
||||
empty={empty}
|
||||
emptySpinner={emptySpinner}
|
||||
isEmpty={isEmpty}
|
||||
noBodyTag={noBodyTag}
|
||||
>
|
||||
{children}
|
||||
</Body>
|
||||
<Foot
|
||||
footer={footer}
|
||||
isEmpty={isEmpty}
|
||||
/>
|
||||
</table>
|
||||
</StyledDiv>
|
||||
);
|
||||
}
|
||||
|
||||
const BASE_BORDER = 0.125;
|
||||
const BORDER_SIDE = `${BASE_BORDER * 1}rem solid var(--bg-page)`;
|
||||
const BORDER_TOP = `${BASE_BORDER * 2}rem solid var(--bg-page)`;
|
||||
const BORDER_RADIUS = `${BASE_BORDER * 4}rem`;
|
||||
|
||||
const StyledDiv = styled.div`
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
|
||||
.ui--Table-Split {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
margin-bottom: 1.5rem;
|
||||
|
||||
> .ui--Table-Split-3 {
|
||||
max-width: 33.3%;
|
||||
min-width: 33.3%;
|
||||
}
|
||||
|
||||
> .ui--Table-Split-2 {
|
||||
max-width: 50%;
|
||||
min-width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
*border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
|
||||
&.isFixed {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
&:not(.isInline):not(.noMargin) {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
&.isInline {
|
||||
tbody tr td {
|
||||
border-top-width: 1px;
|
||||
padding: 0.25rem 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
tr {
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
|
||||
td,
|
||||
&:not(.filter) th {
|
||||
&:first-child {
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding-right: 0.75rem;
|
||||
}
|
||||
|
||||
&.all {
|
||||
width: 100%;
|
||||
|
||||
&:not(.overflow) {
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
summary {
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tbody, thead {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
tr {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
tbody {
|
||||
position: relative;
|
||||
|
||||
td {
|
||||
background: var(--bg-table);
|
||||
padding: 0.5rem 1rem;
|
||||
text-align: left;
|
||||
vertical-align: middle;
|
||||
|
||||
> article.mark {
|
||||
margin-left: 0rem;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-left: ${BORDER_SIDE};
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-right: ${BORDER_SIDE};
|
||||
}
|
||||
|
||||
label {
|
||||
display: block !important;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
div.empty {
|
||||
opacity: var(--opacity-light);
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
.ui--Spinner {
|
||||
margin: 0 auto;
|
||||
|
||||
.text {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.actions {
|
||||
padding-left: 0.35rem;
|
||||
width: 1%;
|
||||
|
||||
> div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: flex-end;
|
||||
|
||||
& > * + * {
|
||||
margin-left: 0.35rem;
|
||||
}
|
||||
|
||||
.ui--Button {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.address {
|
||||
max-width: 0;
|
||||
min-width: 15rem;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
&.badge {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
&.balance {
|
||||
min-width: 20rem;
|
||||
padding: 0.5rem 0 0.75rem;
|
||||
}
|
||||
|
||||
&.button {
|
||||
padding: 0.25rem 0.35rem 0.5rem;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
|
||||
> * {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.ui--Toggle {
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
|
||||
label {
|
||||
display: inline-block !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.chart {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&.expand {
|
||||
&:not(.left) {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.ui--Expander + .ui--Expander {
|
||||
margin-top: 0.375rem;
|
||||
}
|
||||
}
|
||||
|
||||
&.hash {
|
||||
// we actually want to use 10ch here, however in the
|
||||
// block expand page gives different sizes to the hashes
|
||||
min-width: 7.5rem;
|
||||
white-space: nowrap;
|
||||
|
||||
> .shortHash {
|
||||
max-width: var(--width-shorthash);
|
||||
min-width: 3em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
width: var(--width-shorthash);
|
||||
}
|
||||
}
|
||||
|
||||
&.links {
|
||||
padding: 0.5rem 0.75rem;
|
||||
text-align: center;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
&.no-pad-left {
|
||||
padding-left: 0.125rem;
|
||||
}
|
||||
|
||||
&.no-pad-right {
|
||||
padding-right: 0.125rem;
|
||||
}
|
||||
|
||||
&.no-pad-top {
|
||||
padding-top: 0.125rem;
|
||||
}
|
||||
|
||||
&.no-pad {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&.number {
|
||||
font-variant-numeric: tabular-nums;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&.relative {
|
||||
position: relative;
|
||||
|
||||
.absolute {
|
||||
position: absolute;
|
||||
right: 0.5rem;
|
||||
// this seems aligned with expander (when zoomed in)
|
||||
top: 0.72rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
&.overflow {
|
||||
max-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: none;
|
||||
}
|
||||
|
||||
&.start {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
&.together {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&.top {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
&.columar {
|
||||
vertical-align: top;
|
||||
|
||||
.ui--Columar .ui--Column {
|
||||
margin: 1rem 0 0.75rem 0;
|
||||
padding: 0;
|
||||
|
||||
* + h5 {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.ui--Chart-Line {
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.middle {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&.mini {
|
||||
padding: 0 !important;
|
||||
width: fit-content;
|
||||
white-space: normal;
|
||||
|
||||
> div {
|
||||
margin-right: 0.75rem;
|
||||
max-width: 3.8rem;
|
||||
min-width: 3.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
&.upper {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.ui--Button-Group .ui--Button:not(.isToplevel) {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
tr {
|
||||
&:not(.isExpanded) {
|
||||
td {
|
||||
border-top: ${BORDER_TOP};
|
||||
|
||||
&:first-child {
|
||||
border-top-left-radius: ${BORDER_RADIUS};
|
||||
border-bottom-left-radius: ${BORDER_RADIUS};
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-top-right-radius: ${BORDER_RADIUS};
|
||||
border-bottom-right-radius: ${BORDER_RADIUS};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.isExpanded {
|
||||
&.isFirst {
|
||||
td {
|
||||
border-top: ${BORDER_TOP};
|
||||
|
||||
&:first-child {
|
||||
border-top-left-radius: ${BORDER_RADIUS};
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-top-right-radius: ${BORDER_RADIUS};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.isLast {
|
||||
td {
|
||||
&:first-child {
|
||||
border-bottom-left-radius: ${BORDER_RADIUS};
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom-right-radius: ${BORDER_RADIUS};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.packedBottom {
|
||||
td {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.packedTop {
|
||||
td {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.packedAll {
|
||||
td {
|
||||
padding-bottom: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.transparent {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&.isCollapsed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ui--Button-Group {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.ui--Button:not(.isIcon):not(:hover) {
|
||||
background: transparent !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
.ui.toggle.checkbox input:checked ~ .box:before,
|
||||
.ui.toggle.checkbox input:checked ~ label:before {
|
||||
background-color: #eee !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
thead {
|
||||
tr {
|
||||
&:first-child {
|
||||
th {
|
||||
border-top: ${BORDER_TOP};
|
||||
|
||||
&:first-child {
|
||||
border-top-left-radius: ${BORDER_RADIUS};
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-top-right-radius: ${BORDER_RADIUS};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
th {
|
||||
padding-top: 1rem;
|
||||
|
||||
&:first-child {
|
||||
border-bottom-left-radius: ${BORDER_RADIUS};
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-bottom-right-radius: ${BORDER_RADIUS};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
th {
|
||||
&:first-child {
|
||||
border-left: ${BORDER_SIDE};
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-right: ${BORDER_SIDE};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const Table = React.memo(TableBase) as unknown as typeof TableBase & {
|
||||
Column: typeof Column,
|
||||
Row: typeof Row
|
||||
};
|
||||
|
||||
Table.Column = Column;
|
||||
Table.Row = Row;
|
||||
|
||||
export default Table;
|
||||
Reference in New Issue
Block a user