feat: initial Pezkuwi Apps rebrand from polkadot-apps

Rebranded terminology:
- Polkadot → Pezkuwi
- Kusama → Dicle
- Westend → Zagros
- Rococo → PezkuwiChain
- Substrate → Bizinikiwi
- parachain → teyrchain

Custom logos with Kurdistan brand colors (#e6007a → #86e62a):
- bizinikiwi-hexagon.svg
- sora-bizinikiwi.svg
- hezscanner.svg
- heztreasury.svg
- pezkuwiscan.svg
- pezkuwistats.svg
- pezkuwiassembly.svg
- pezkuwiholic.svg
This commit is contained in:
2026-01-07 13:05:27 +03:00
commit d21bfb1320
5867 changed files with 329019 additions and 0 deletions
@@ -0,0 +1,53 @@
// Copyright 2017-2025 @pezkuwi/react-components authors & contributors
// SPDX-License-Identifier: Apache-2.0
import React from 'react';
import { styled } from '../styled.js';
interface Props {
children?: React.ReactNode;
className?: string;
isCentered?: boolean;
}
function ButtonGroup ({ children, className = '', isCentered }: Props): React.ReactElement<Props> {
return (
<StyledDiv className={`${className} ui--Button-Group ${isCentered ? 'isCentered' : ''}`}>
{children}
<div className='clear' />
</StyledDiv>
);
}
const StyledDiv = styled.div`
margin: 1rem 0;
text-align: right;
& .clear {
clear: both;
}
&.isCentered {
margin-bottom: 0.5rem;
text-align: center;
}
&+.ui--Table {
margin-top: 1.5rem;
}
.ui--Button {
margin: 0 0.25rem;
}
.ui--CopyButton {
display: inline-block;
}
.ui--ToggleGroup, .ui--Dropdown {
float: left;
}
`;
export default React.memo(ButtonGroup);
@@ -0,0 +1,173 @@
// Copyright 2017-2025 @pezkuwi/react-components authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { ButtonProps as Props } from './types.js';
import React, { useCallback, useEffect } from 'react';
import Icon from '../Icon.js';
import Spinner from '../Spinner.js';
import { styled } from '../styled.js';
import Group from './Group.js';
function ButtonBase ({ activeOnEnter, children, className = '', dataTestId = '', icon, isBasic, isBusy, isCircular, isDisabled, isFull, isIcon, isSelected, isToplevel, label, onClick, isReadOnly = !onClick, onMouseEnter, onMouseLeave, tabIndex, withoutLink }: Props): React.ReactElement<Props> {
const _onClick = useCallback(
(): void => {
!(isBusy || isDisabled) && onClick && Promise
.resolve(onClick())
.catch(console.error);
},
[isBusy, isDisabled, onClick]
);
const _onMouseEnter = useCallback((): void => {
onMouseEnter && Promise
.resolve(onMouseEnter())
.catch(console.error);
}, [onMouseEnter]);
const _onMouseLeave = useCallback((): void => {
onMouseLeave && Promise
.resolve(onMouseLeave())
.catch(console.error);
}, [onMouseLeave]);
const listenKeyboard = useCallback((event: KeyboardEvent): void => {
if (!isBusy && !isDisabled && event.key === 'Enter') {
onClick && Promise
.resolve(onClick())
.catch(console.error);
}
}, [isBusy, isDisabled, onClick]);
useEffect(() => {
if (activeOnEnter) {
window.addEventListener('keydown', listenKeyboard, true);
}
return () => {
if (activeOnEnter) {
window.removeEventListener('keydown', listenKeyboard, true);
}
};
}, [activeOnEnter, listenKeyboard]);
return (
<StyledButton
className={`${className} ui--Button ${label ? 'hasLabel' : ''} ${isBasic ? 'isBasic' : ''} ${isCircular ? 'isCircular' : ''} ${isFull ? 'isFull' : ''} ${isIcon ? 'isIcon' : ''} ${(isBusy || isDisabled) ? 'isDisabled' : ''} ${isBusy ? 'isBusy' : ''} ${isReadOnly ? 'isReadOnly' : ''}${isSelected ? 'isSelected' : ''} ${isToplevel ? 'isToplevel' : ''} ${withoutLink ? 'withoutLink' : ''}`}
data-testid={dataTestId}
onClick={_onClick}
onMouseEnter={_onMouseEnter}
onMouseLeave={_onMouseLeave}
tabIndex={tabIndex}
>
{icon && <Icon icon={icon} />}
{label}
{children}
{isBusy && (
<Spinner
className='ui--Button-spinner'
variant='cover'
/>
)}
</StyledButton>
);
}
const ICON_PADDING = 0.5;
const StyledButton = styled.button`
background: transparent;
border: none;
color: inherit;
cursor: pointer;
line-height: 1;
margin: 0;
outline: none;
position: relative;
vertical-align: middle;
text-align: center;
&:not(.hasLabel) {
padding: 0.7em;
.ui--Icon {
padding: 0.6rem;
margin: -0.6rem;
}
}
&:not(.isCircular) {
border-radius: 0.25rem;
}
&:focus {
outline:0;
}
&.hasLabel {
padding: 0.7rem 1.1rem 0.7rem ${1.1 - ICON_PADDING}rem;
.ui--Icon {
margin-right: 0.425rem !important;
}
}
&.isBasic {
background: var(--bg-table);
}
&.isCircular {
border-radius: 10rem;
}
&.isDisabled, &.isReadOnly {
background: none;
box-shadow: none;
cursor: not-allowed;
}
&.isBusy {
cursor: wait;
}
&.isFull {
display: block;
width: 100%;
}
&.isIcon {
background: transparent;
}
.ui--Button-overlay {
background: rgba(253, 252, 251, 0.75);
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
visibility: hidden;
}
.ui--Icon {
border-radius: 50%;
box-sizing: content-box;
height: 1rem;
margin: -${ICON_PADDING}rem 0;
padding: ${ICON_PADDING}rem;
width: 1rem;
}
&.isDisabled {
color: #bcbbba;
}
`;
const Button = React.memo(ButtonBase) as unknown as typeof ButtonBase & {
Group: typeof Group
};
Button.Group = Group;
export default Button;
@@ -0,0 +1,31 @@
// Copyright 2017-2025 @pezkuwi/react-components authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { IconName } from '@fortawesome/fontawesome-svg-core';
import type React from 'react';
export type Button$Callback = () => void | Promise<void>;
export interface ButtonProps {
activeOnEnter?: boolean;
children?: React.ReactNode;
className?: string;
dataTestId?: string;
icon?: IconName;
isBasic?: boolean;
isBusy?: boolean;
isCircular?: boolean;
isDisabled?: boolean;
isFull?: boolean;
isIcon?: boolean;
isReadOnly?: boolean;
isSelected?: boolean;
isToplevel?: boolean;
label?: React.ReactNode;
onClick?: Button$Callback;
onMouseEnter?: Button$Callback;
onMouseLeave?: Button$Callback;
tabIndex?: number;
tooltip?: React.ReactNode;
withoutLink?: boolean;
}