Skip to content

Commit

Permalink
Merge pull request #853 from acelaya-forks/feature/shlink-web-component
Browse files Browse the repository at this point in the history
Split reusable content into separated components
  • Loading branch information
acelaya authored Aug 7, 2023
2 parents deca5b3 + a2f3673 commit a6134c6
Show file tree
Hide file tree
Showing 429 changed files with 2,934 additions and 2,594 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"license": "MIT",
"scripts": {
"lint": "npm run lint:css && npm run lint:js",
"lint:css": "stylelint src/*.scss src/**/*.scss",
"lint:js": "eslint --ext .js,.ts,.tsx src test",
"lint:css": "stylelint src/*.scss src/**/*.scss shlink-web-component/*.scss shlink-web-component/**/*.scss shlink-frontend-kit/*.scss shlink-frontend-kit/**/*.scss",
"lint:js": "eslint --ext .js,.ts,.tsx src shlink-web-component shlink-frontend-kit test",
"lint:fix": "npm run lint:css:fix && npm run lint:js:fix",
"lint:css:fix": "npm run lint:css -- --fix",
"lint:js:fix": "npm run lint:js -- --fix",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import type { ReactNode } from 'react';
import type { CardProps } from 'reactstrap';
import { Card, CardBody, CardHeader } from 'reactstrap';

interface SimpleCardProps extends Omit<CardProps, 'title'> {
export type SimpleCardProps = Omit<CardProps, 'title'> & {
title?: ReactNode;
bodyClassName?: string;
}
};

export const SimpleCard = ({ title, children, bodyClassName, ...rest }: SimpleCardProps) => (
<Card {...rest}>
Expand Down
3 changes: 3 additions & 0 deletions shlink-frontend-kit/src/block/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './Message';
export * from './Result';
export * from './SimpleCard';
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import classNames from 'classnames';
import { identity } from 'ramda';
import type { ChangeEvent, FC, PropsWithChildren } from 'react';
import { useDomId } from './helpers/hooks';
import { useDomId } from '../hooks';

export type BooleanControlProps = PropsWithChildren<{
checked?: boolean;
Expand All @@ -10,9 +10,9 @@ export type BooleanControlProps = PropsWithChildren<{
inline?: boolean;
}>;

interface BooleanControlWithTypeProps extends BooleanControlProps {
type BooleanControlWithTypeProps = BooleanControlProps & {
type: 'switch' | 'checkbox';
}
};

export const BooleanControl: FC<BooleanControlWithTypeProps> = (
{ checked = false, onChange = identity, className, children, type, inline = false },
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { FC, PropsWithChildren } from 'react';
import type { InputType } from 'reactstrap/types/lib/Input';
import { useDomId } from '../helpers/hooks';
import { useDomId } from '../hooks';
import { LabeledFormGroup } from './LabeledFormGroup';

export type InputFormGroupProps = PropsWithChildren<{
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import '../utils/mixins/vertical-align';
@import '../../../shlink-web-component/src/utils/mixins/vertical-align';

.search-field {
position: relative;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import './SearchField.scss';
const DEFAULT_SEARCH_INTERVAL = 500;
let timer: NodeJS.Timeout | null;

interface SearchFieldProps {
type SearchFieldProps = {
onChange: (value: string) => void;
className?: string;
large?: boolean;
noBorder?: boolean;
initialValue?: string;
}
};

export const SearchField = ({ onChange, className, large = true, noBorder = false, initialValue = '' }: SearchFieldProps) => {
const [searchTerm, setSearchTerm] = useState(initialValue);
Expand Down
File renamed without changes.
5 changes: 5 additions & 0 deletions shlink-frontend-kit/src/form/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from './Checkbox';
export * from './ToggleSwitch';
export * from './InputFormGroup';
export * from './LabeledFormGroup';
export * from './SearchField';
16 changes: 16 additions & 0 deletions shlink-frontend-kit/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useRef, useState } from 'react';
import { v4 as uuid } from 'uuid';

type ToggleResult = [boolean, () => void, () => void, () => void];

export const useToggle = (initialValue = false): ToggleResult => {
const [flag, setFlag] = useState<boolean>(initialValue);
return [flag, () => setFlag(!flag), () => setFlag(true), () => setFlag(false)];
};

export const useDomId = (): string => {
const { current: id } = useRef(`dom-${uuid()}`);
return id;
};

export const useElementRef = <T>() => useRef<T | null>(null);
219 changes: 219 additions & 0 deletions shlink-frontend-kit/src/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
@import './utils/ResponsiveTable';
@import './theme/theme';

/* stylelint-disable no-descending-specificity */

a,
.btn-link {
text-decoration: none;
}

/* stylelint-disable-next-line selector-max-pseudo-class */
a:not(.nav-link):not(.navbar-brand):not(.page-link):not(.highlight-card):not(.btn):not(.dropdown-item):hover,
.btn-link:hover {
text-decoration: underline;
}

.bg-main {
background-color: $mainColor !important;
}

.bg-warning {
color: $lightTextColor;
}

.card-body,
.card-header,
.list-group-item {
background-color: transparent;
}

.card-footer {
background-color: var(--primary-color-alfa);
}

.card {
box-shadow: 0 .125rem .25rem rgb(0 0 0 / .075);
background-color: var(--primary-color);
border-color: var(--border-color);
}

.list-group {
background-color: var(--primary-color);
}

.modal-content,
.page-link,
.page-item.disabled .page-link,
.dropdown-menu {
background-color: var(--primary-color);
}

.modal-header,
.modal-footer,
.card-header,
.card-footer,
.table thead th,
.table th,
.table td,
.page-link,
.page-link:hover,
.page-item.disabled .page-link,
.dropdown-divider,
.dropdown-menu,
.list-group-item,
.modal-content,
hr {
border-color: var(--border-color);
}

.table-bordered,
.table-bordered thead th,
.table-bordered thead td {
border-color: var(--table-border-color);
}

.page-link:hover,
.page-link:focus {
background-color: var(--secondary-color);
}

.page-item.active .page-link {
background-color: var(--brand-color);
border-color: var(--brand-color);
}

.pagination .page-link {
cursor: pointer;
}

.container-xl {
@media (min-width: $xlgMin) {
max-width: 1320px;
}

@media (max-width: $smMax) {
padding-right: 0;
padding-left: 0;
}
}

/* Deprecated. Brought from bootstrap 4 */
.btn-block {
display: block;
width: 100%;
}

.btn-primary,
.btn-primary:hover,
.btn-primary:active,
.btn-primary.active,
.btn-outline-primary:hover,
.btn-outline-primary:active,
.btn-outline-primary.active, {
color: #ffffff;
}

.dropdown-item,
.dropdown-item-text {
color: var(--text-color);
}

.dropdown-item:not(:disabled) {
cursor: pointer;
}

.dropdown-item:focus:not(:disabled),
.dropdown-item:hover:not(:disabled),
.dropdown-item.active:not(:disabled),
.dropdown-item:active:not(:disabled) {
background-color: var(--active-color) !important;
color: var(--text-color) !important;
}

.dropdown-item--danger.dropdown-item--danger {
color: $dangerColor;

&:hover,
&:active,
&.active {
color: $dangerColor !important;
}
}

.badge-main {
color: #ffffff;
background-color: var(--brand-color);
}

.close,
.close:hover,
.table,
.table-hover > tbody > tr:hover > *,
.table-hover > tbody > tr > * {
color: var(--text-color);
}

.btn-close {
filter: var(--btn-close-filter);
}

.table-hover tbody tr:hover {
background-color: var(--secondary-color);
}

.form-control,
.form-control:focus {
background-color: var(--primary-color);
border-color: var(--input-border-color);
color: var(--input-text-color);
}

.form-control.disabled,
.form-control:disabled {
background-color: var(--input-disabled-color);
cursor: not-allowed;
}

.card .form-control:not(:disabled),
.card .form-control:not(:disabled):hover {
background-color: var(--input-color);
}

.table-active,
.table-active > th,
.table-active > td {
background-color: var(--table-highlight-color) !important;
}

.navbar-brand {
@media (max-width: $smMax) {
margin: 0 auto !important;
}
}

.indivisible {
white-space: nowrap;
}

.pointer {
cursor: pointer;
}

.progress-bar {
background-color: $mainColor;
}

.btn-xs-block {
@media (max-width: $xsMax) {
width: 100%;
display: block;
}
}

.btn-md-block {
@media (max-width: $mdMax) {
width: 100%;
display: block;
}
}
7 changes: 7 additions & 0 deletions shlink-frontend-kit/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export * from './block';
export * from './form';
export * from './hooks';
export * from './navigation';
export * from './ordering';
export * from './theme';
export * from './utils';
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* stylelint-disable no-descending-specificity */

@import '../utils/mixins/vertical-align';
@import '../../../shlink-web-component/src/utils/mixins/vertical-align';

.dropdown-btn__toggle.dropdown-btn__toggle {
text-align: left;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import classNames from 'classnames';
import type { FC, PropsWithChildren, ReactNode } from 'react';
import { Dropdown, DropdownMenu, DropdownToggle } from 'reactstrap';
import type { DropdownToggleProps } from 'reactstrap/types/lib/DropdownToggle';
import { useToggle } from './helpers/hooks';
import { useToggle } from '../hooks';
import './DropdownBtn.scss';

export type DropdownBtnProps = PropsWithChildren<Omit<DropdownToggleProps, 'caret' | 'size' | 'outline'> & {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import './base';
@import '../base';

.nav-pills__nav {
position: sticky !important;
Expand Down
File renamed without changes.
File renamed without changes.
3 changes: 3 additions & 0 deletions shlink-frontend-kit/src/navigation/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './DropdownBtn';
export * from './RowDropdownBtn';
export * from './NavPills';
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import classNames from 'classnames';
import { toPairs } from 'ramda';
import { DropdownItem, DropdownMenu, DropdownToggle, UncontrolledDropdown } from 'reactstrap';
import type { Order, OrderDir } from './helpers/ordering';
import { determineOrderDir } from './helpers/ordering';
import type { Order, OrderDir } from './ordering';
import { determineOrderDir } from './ordering';
import './OrderingDropdown.scss';

export interface OrderingDropdownProps<T extends string = string> {
export type OrderingDropdownProps<T extends string = string> = {
items: Record<T, string>;
order: Order<T>;
onChange: (orderField?: T, orderDir?: OrderDir) => void;
isButton?: boolean;
right?: boolean;
prefixed?: boolean;
}
};

export function OrderingDropdown<T extends string = string>(
{ items, order, onChange, isButton = true, right = false, prefixed = true }: OrderingDropdownProps<T>,
Expand Down
2 changes: 2 additions & 0 deletions shlink-frontend-kit/src/ordering/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './ordering';
export * from './OrderingDropdown';
Loading

0 comments on commit a6134c6

Please sign in to comment.