Compare commits
3 Commits
f5d64fa2b4
...
69e90bd1d3
Author | SHA1 | Date |
---|---|---|
Bill | 69e90bd1d3 | |
Bill | 4e848fd3f5 | |
robbis95 | d416c82741 |
|
@ -1,16 +1,12 @@
|
|||
import { GetRenderer, GetTicker, NitroTicker, RoomPreviewer, TextureUtils } from '@nitrots/nitro-renderer';
|
||||
import { FC, MouseEvent, ReactNode, useEffect, useRef } from 'react';
|
||||
import { FC, MouseEvent, useEffect, useRef } from 'react';
|
||||
|
||||
export interface LayoutRoomPreviewerViewProps
|
||||
{
|
||||
export const LayoutRoomPreviewerView: FC<{
|
||||
roomPreviewer: RoomPreviewer;
|
||||
height?: number;
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
export const LayoutRoomPreviewerView: FC<LayoutRoomPreviewerViewProps> = props =>
|
||||
}> = props =>
|
||||
{
|
||||
const { roomPreviewer = null, height = 0, children = null } = props;
|
||||
const { roomPreviewer = null, height = 0 } = props;
|
||||
const elementRef = useRef<HTMLDivElement>();
|
||||
|
||||
const onClick = (event: MouseEvent<HTMLDivElement>) =>
|
||||
|
@ -80,9 +76,14 @@ export const LayoutRoomPreviewerView: FC<LayoutRoomPreviewerViewProps> = props =
|
|||
}, [ roomPreviewer, elementRef, height ]);
|
||||
|
||||
return (
|
||||
<div className="relative w-full">
|
||||
<div ref={ elementRef } className="rounded-md shadow" style={ { height } } onClick={ onClick } />
|
||||
{ children }
|
||||
</div>
|
||||
<div
|
||||
ref={ elementRef }
|
||||
className="relative w-full rounded-md shadow-room-previewer"
|
||||
style={ {
|
||||
height,
|
||||
minHeight: height,
|
||||
maxHeight: height
|
||||
} }
|
||||
onClick={ onClick } />
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import { GetEventDispatcher, NitroToolbarAnimateIconEvent, TextureUtils, ToolbarIconEnum } from '@nitrots/nitro-renderer';
|
||||
import { GetEventDispatcher, NitroToolbarAnimateIconEvent, RoomPreviewer, TextureUtils, ToolbarIconEnum } from '@nitrots/nitro-renderer';
|
||||
import { FC, useRef } from 'react';
|
||||
import { LayoutRoomPreviewerView, LayoutRoomPreviewerViewProps } from '../../../../common';
|
||||
import { LayoutRoomPreviewerView } from '../../../../common';
|
||||
import { CatalogPurchasedEvent } from '../../../../events';
|
||||
import { useUiEvent } from '../../../../hooks';
|
||||
|
||||
export const CatalogRoomPreviewerView: FC<LayoutRoomPreviewerViewProps> = props =>
|
||||
export const CatalogRoomPreviewerView: FC<{
|
||||
roomPreviewer: RoomPreviewer;
|
||||
height?: number;
|
||||
}> = props =>
|
||||
{
|
||||
const { roomPreviewer = null } = props;
|
||||
const elementRef = useRef<HTMLDivElement>(null);
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { FC, PropsWithChildren } from 'react';
|
||||
import { UnseenItemCategory } from '../../../../api';
|
||||
import { LayoutBadgeImageView, LayoutGridItem } from '../../../../common';
|
||||
import { LayoutBadgeImageView } from '../../../../common';
|
||||
import { useInventoryBadges, useInventoryUnseenTracker } from '../../../../hooks';
|
||||
import { InfiniteGrid } from '../../../../layout';
|
||||
|
||||
export const InventoryBadgeItemView: FC<PropsWithChildren<{ badgeCode: string }>> = props =>
|
||||
{
|
||||
|
@ -11,9 +12,9 @@ export const InventoryBadgeItemView: FC<PropsWithChildren<{ badgeCode: string }>
|
|||
const unseen = isUnseen(UnseenItemCategory.BADGE, getBadgeId(badgeCode));
|
||||
|
||||
return (
|
||||
<LayoutGridItem itemActive={ (selectedBadgeCode === badgeCode) } itemUnseen={ unseen } onDoubleClick={ event => toggleBadge(selectedBadgeCode) } onMouseDown={ event => setSelectedBadgeCode(badgeCode) } { ...rest }>
|
||||
<InfiniteGrid.Item itemActive={ (selectedBadgeCode === badgeCode) } itemUnseen={ unseen } onDoubleClick={ event => toggleBadge(selectedBadgeCode) } onMouseDown={ event => setSelectedBadgeCode(badgeCode) } { ...rest }>
|
||||
<LayoutBadgeImageView badgeCode={ badgeCode } />
|
||||
{ children }
|
||||
</LayoutGridItem>
|
||||
</InfiniteGrid.Item>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { FC, useEffect, useState } from 'react';
|
||||
import { LocalizeBadgeName, LocalizeText, UnseenItemCategory } from '../../../../api';
|
||||
import { AutoGrid, Button, Column, Grid, LayoutBadgeImageView, Text } from '../../../../common';
|
||||
import { LayoutBadgeImageView } from '../../../../common';
|
||||
import { useInventoryBadges, useInventoryUnseenTracker } from '../../../../hooks';
|
||||
import { InfiniteGrid, NitroButton } from '../../../../layout';
|
||||
import { InventoryBadgeItemView } from './InventoryBadgeItemView';
|
||||
|
||||
export const InventoryBadgeView: FC<{}> = props =>
|
||||
|
@ -34,33 +35,36 @@ export const InventoryBadgeView: FC<{}> = props =>
|
|||
}, []);
|
||||
|
||||
return (
|
||||
<Grid>
|
||||
<Column overflow="hidden" size={ 7 }>
|
||||
<AutoGrid columnCount={ 4 }>
|
||||
{ badgeCodes && (badgeCodes.length > 0) && badgeCodes.map((badgeCode, index) =>
|
||||
{
|
||||
if(isWearingBadge(badgeCode)) return null;
|
||||
|
||||
return <InventoryBadgeItemView key={ index } badgeCode={ badgeCode } />
|
||||
}) }
|
||||
</AutoGrid>
|
||||
</Column>
|
||||
<Column className="justify-content-between" overflow="auto" size={ 5 }>
|
||||
<Column gap={ 2 } overflow="hidden">
|
||||
<Text>{ LocalizeText('inventory.badges.activebadges') }</Text>
|
||||
<AutoGrid columnCount={ 3 }>
|
||||
{ activeBadgeCodes && (activeBadgeCodes.length > 0) && activeBadgeCodes.map((badgeCode, index) => <InventoryBadgeItemView key={ index } badgeCode={ badgeCode } />) }
|
||||
</AutoGrid>
|
||||
</Column>
|
||||
<div className="grid h-full grid-cols-12 gap-2">
|
||||
<div className="flex flex-col col-span-7 gap-1 overflow-hidden">
|
||||
<InfiniteGrid<string>
|
||||
columnCount={ 5 }
|
||||
estimateSize={ 50 }
|
||||
itemRender={ item => <InventoryBadgeItemView badgeCode={ item } /> }
|
||||
items={ badgeCodes.filter(code => !isWearingBadge(code)) } />
|
||||
</div>
|
||||
<div className="flex flex-col justify-between col-span-5 overflow-auto">
|
||||
<div className="flex flex-col gap-2 overflow-hidden">
|
||||
<span className="text-sm truncate grow">{ LocalizeText('inventory.badges.activebadges') }</span>
|
||||
<InfiniteGrid<string>
|
||||
columnCount={ 3 }
|
||||
estimateSize={ 50 }
|
||||
itemRender={ item => <InventoryBadgeItemView badgeCode={ item } /> }
|
||||
items={ activeBadgeCodes } />
|
||||
</div>
|
||||
{ !!selectedBadgeCode &&
|
||||
<Column grow gap={ 2 } justifyContent="end">
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="items-center gap-2">
|
||||
<LayoutBadgeImageView shrink badgeCode={ selectedBadgeCode } />
|
||||
<Text>{ LocalizeBadgeName(selectedBadgeCode) }</Text>
|
||||
<span className="text-sm truncate grow">{ LocalizeBadgeName(selectedBadgeCode) }</span>
|
||||
</div>
|
||||
<Button disabled={ !isWearingBadge(selectedBadgeCode) && !canWearBadges() } variant={ (isWearingBadge(selectedBadgeCode) ? 'danger' : 'success') } onClick={ event => toggleBadge(selectedBadgeCode) }>{ LocalizeText(isWearingBadge(selectedBadgeCode) ? 'inventory.badges.clearbadge' : 'inventory.badges.wearbadge') }</Button>
|
||||
</Column> }
|
||||
</Column>
|
||||
</Grid>
|
||||
<NitroButton
|
||||
disabled={ !isWearingBadge(selectedBadgeCode) && !canWearBadges() }
|
||||
onClick={ event => toggleBadge(selectedBadgeCode) }>
|
||||
{ LocalizeText(isWearingBadge(selectedBadgeCode) ? 'inventory.badges.clearbadge' : 'inventory.badges.wearbadge') }
|
||||
</NitroButton>
|
||||
</div> }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import { MouseEventType } from '@nitrots/nitro-renderer';
|
||||
import { FC, MouseEvent, PropsWithChildren, useState } from 'react';
|
||||
import { attemptBotPlacement, IBotItem, UnseenItemCategory } from '../../../../api';
|
||||
import { LayoutAvatarImageView, LayoutGridItem } from '../../../../common';
|
||||
import { IBotItem, UnseenItemCategory, attemptBotPlacement } from '../../../../api';
|
||||
import { LayoutAvatarImageView } from '../../../../common';
|
||||
import { useInventoryBots, useInventoryUnseenTracker } from '../../../../hooks';
|
||||
import { InfiniteGrid } from '../../../../layout';
|
||||
|
||||
export const InventoryBotItemView: FC<PropsWithChildren<{ botItem: IBotItem }>> = props =>
|
||||
export const InventoryBotItemView: FC<PropsWithChildren<{
|
||||
botItem: IBotItem
|
||||
}>> = props =>
|
||||
{
|
||||
const { botItem = null, children = null, ...rest } = props;
|
||||
const [ isMouseDown, setMouseDown ] = useState(false);
|
||||
|
@ -35,9 +38,9 @@ export const InventoryBotItemView: FC<PropsWithChildren<{ botItem: IBotItem }>>
|
|||
}
|
||||
|
||||
return (
|
||||
<LayoutGridItem itemActive={ (selectedBot === botItem) } itemUnseen={ unseen } onDoubleClick={ onMouseEvent } onMouseDown={ onMouseEvent } onMouseOut={ onMouseEvent } onMouseUp={ onMouseEvent } { ...rest }>
|
||||
<InfiniteGrid.Item itemActive={ (selectedBot === botItem) } itemUnseen={ unseen } onDoubleClick={ onMouseEvent } onMouseDown={ onMouseEvent } onMouseOut={ onMouseEvent } onMouseUp={ onMouseEvent } { ...rest } className="*:[background-position-y:-32px]">
|
||||
<LayoutAvatarImageView direction={ 3 } figure={ botItem.botData.figure } headOnly={ true } />
|
||||
{ children }
|
||||
</LayoutGridItem>
|
||||
</InfiniteGrid.Item>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
import { GetRoomEngine, IRoomSession, RoomObjectVariable, RoomPreviewer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { LocalizeText, UnseenItemCategory, attemptBotPlacement } from '../../../../api';
|
||||
import { AutoGrid, Button, Column, Grid, LayoutRoomPreviewerView, Text } from '../../../../common';
|
||||
import { IBotItem, LocalizeText, UnseenItemCategory, attemptBotPlacement } from '../../../../api';
|
||||
import { LayoutRoomPreviewerView } from '../../../../common';
|
||||
import { useInventoryBots, useInventoryUnseenTracker } from '../../../../hooks';
|
||||
import { InfiniteGrid, NitroButton } from '../../../../layout';
|
||||
import { InventoryCategoryEmptyView } from '../InventoryCategoryEmptyView';
|
||||
import { InventoryBotItemView } from './InventoryBotItemView';
|
||||
|
||||
interface InventoryBotViewProps
|
||||
{
|
||||
export const InventoryBotView: FC<{
|
||||
roomSession: IRoomSession;
|
||||
roomPreviewer: RoomPreviewer;
|
||||
}
|
||||
|
||||
export const InventoryBotView: FC<InventoryBotViewProps> = props =>
|
||||
}> = props =>
|
||||
{
|
||||
const { roomSession = null, roomPreviewer = null } = props;
|
||||
const [ isVisible, setIsVisible ] = useState(false);
|
||||
|
@ -67,25 +65,26 @@ export const InventoryBotView: FC<InventoryBotViewProps> = props =>
|
|||
if(!botItems || !botItems.length) return <InventoryCategoryEmptyView desc={ LocalizeText('inventory.empty.bots.desc') } title={ LocalizeText('inventory.empty.bots.title') } />;
|
||||
|
||||
return (
|
||||
<Grid>
|
||||
<Column overflow="hidden" size={ 7 }>
|
||||
<AutoGrid columnCount={ 5 }>
|
||||
{ botItems && (botItems.length > 0) && botItems.map(item => <InventoryBotItemView key={ item.botData.id } botItem={ item } />) }
|
||||
</AutoGrid>
|
||||
</Column>
|
||||
<Column overflow="auto" size={ 5 }>
|
||||
<Column overflow="hidden" position="relative">
|
||||
<div className="grid h-full grid-cols-12 gap-2">
|
||||
<div className="flex flex-col col-span-7 gap-1 overflow-hidden">
|
||||
<InfiniteGrid<IBotItem>
|
||||
columnCount={ 6 }
|
||||
itemRender={ item => <InventoryBotItemView botItem={ item } /> }
|
||||
items={ botItems } />
|
||||
</div>
|
||||
<div className="flex flex-col col-span-5">
|
||||
<div className="relative flex flex-col">
|
||||
<LayoutRoomPreviewerView height={ 140 } roomPreviewer={ roomPreviewer } />
|
||||
</Column>
|
||||
</div>
|
||||
{ selectedBot &&
|
||||
<Column grow gap={ 2 } justifyContent="between">
|
||||
<Text grow truncate>{ selectedBot.botData.name }</Text>
|
||||
<div className="flex flex-col justify-between gap-2 grow">
|
||||
<span className="truncate grow">{ selectedBot.botData.name }</span>
|
||||
{ !!roomSession &&
|
||||
<Button variant="success" onClick={ event => attemptBotPlacement(selectedBot) }>
|
||||
<NitroButton onClick={ event => attemptBotPlacement(selectedBot) }>
|
||||
{ LocalizeText('inventory.furni.placetoroom') }
|
||||
</Button> }
|
||||
</Column> }
|
||||
</Column>
|
||||
</Grid>
|
||||
</NitroButton> }
|
||||
</div> }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,9 @@ import { GroupItem, attemptItemPlacement } from '../../../../api';
|
|||
import { useInventoryFurni } from '../../../../hooks';
|
||||
import { InfiniteGrid, classNames } from '../../../../layout';
|
||||
|
||||
export const InventoryFurnitureItemView: FC<{ groupItem: GroupItem }> = props =>
|
||||
export const InventoryFurnitureItemView: FC<{
|
||||
groupItem: GroupItem
|
||||
}> = props =>
|
||||
{
|
||||
const { groupItem = null, ...rest } = props;
|
||||
const [ isMouseDown, setMouseDown ] = useState(false);
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react';
|
||||
import { FaSearch } from 'react-icons/fa';
|
||||
import { GroupItem, LocalizeText } from '../../../../api';
|
||||
import { Button } from '../../../../common';
|
||||
import { NitroButton, NitroInput } from '../../../../layout';
|
||||
|
||||
export interface InventoryFurnitureSearchViewProps
|
||||
{
|
||||
export const InventoryFurnitureSearchView: FC<{
|
||||
groupItems: GroupItem[];
|
||||
setGroupItems: Dispatch<SetStateAction<GroupItem[]>>;
|
||||
}
|
||||
|
||||
export const InventoryFurnitureSearchView: FC<InventoryFurnitureSearchViewProps> = props =>
|
||||
}> = props =>
|
||||
{
|
||||
const { groupItems = [], setGroupItems = null } = props;
|
||||
const [ searchValue, setSearchValue ] = useState('');
|
||||
|
@ -38,10 +35,13 @@ export const InventoryFurnitureSearchView: FC<InventoryFurnitureSearchViewProps>
|
|||
|
||||
return (
|
||||
<div className="flex gap-1">
|
||||
<input className="form-control form-control-sm" placeholder={ LocalizeText('generic.search') } type="text" value={ searchValue } onChange={ event => setSearchValue(event.target.value) } />
|
||||
<Button variant="primary">
|
||||
<NitroInput
|
||||
placeholder={ LocalizeText('generic.search') }
|
||||
value={ searchValue }
|
||||
onChange={ event => setSearchValue(event.target.value) } />
|
||||
<NitroButton>
|
||||
<FaSearch className="fa-icon" />
|
||||
</Button>
|
||||
</NitroButton>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -2,19 +2,14 @@ import { InfiniteGrid } from '@layout/InfiniteGrid';
|
|||
import { GetRoomEngine, GetSessionDataManager, IRoomSession, RoomObjectVariable, RoomPreviewer, Vector3d } from '@nitrots/nitro-renderer';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { DispatchUiEvent, FurniCategory, GroupItem, LocalizeText, UnseenItemCategory, attemptItemPlacement } from '../../../../api';
|
||||
import { Button, LayoutLimitedEditionCompactPlateView, LayoutRarityLevelView, LayoutRoomPreviewerView } from '../../../../common';
|
||||
import { LayoutLimitedEditionCompactPlateView, LayoutRarityLevelView, LayoutRoomPreviewerView } from '../../../../common';
|
||||
import { CatalogPostMarketplaceOfferEvent } from '../../../../events';
|
||||
import { useInventoryFurni, useInventoryUnseenTracker } from '../../../../hooks';
|
||||
import { NitroButton } from '../../../../layout';
|
||||
import { InventoryCategoryEmptyView } from '../InventoryCategoryEmptyView';
|
||||
import { InventoryFurnitureItemView } from './InventoryFurnitureItemView';
|
||||
import { InventoryFurnitureSearchView } from './InventoryFurnitureSearchView';
|
||||
|
||||
interface InventoryFurnitureViewProps
|
||||
{
|
||||
roomSession: IRoomSession;
|
||||
roomPreviewer: RoomPreviewer;
|
||||
}
|
||||
|
||||
const attemptPlaceMarketplaceOffer = (groupItem: GroupItem) =>
|
||||
{
|
||||
const item = groupItem.getLastItem();
|
||||
|
@ -26,7 +21,10 @@ const attemptPlaceMarketplaceOffer = (groupItem: GroupItem) =>
|
|||
DispatchUiEvent(new CatalogPostMarketplaceOfferEvent(item));
|
||||
}
|
||||
|
||||
export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
|
||||
export const InventoryFurnitureView: FC<{
|
||||
roomSession: IRoomSession;
|
||||
roomPreviewer: RoomPreviewer;
|
||||
}> = props =>
|
||||
{
|
||||
const { roomSession = null, roomPreviewer = null } = props;
|
||||
const [ isVisible, setIsVisible ] = useState(false);
|
||||
|
@ -112,7 +110,7 @@ export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
|
|||
if(!groupItems || !groupItems.length) return <InventoryCategoryEmptyView desc={ LocalizeText('inventory.empty.desc') } title={ LocalizeText('inventory.empty.title') } />;
|
||||
|
||||
return (
|
||||
<div className="grid h-full grid-cols-12 gap-2 overflow-hidden">
|
||||
<div className="grid h-full grid-cols-12 gap-2">
|
||||
<div className="flex flex-col col-span-7 gap-1 overflow-hidden">
|
||||
<InventoryFurnitureSearchView groupItems={ groupItems } setGroupItems={ setFilteredGroupItems } />
|
||||
<InfiniteGrid<GroupItem>
|
||||
|
@ -120,8 +118,8 @@ export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
|
|||
itemRender={ item => <InventoryFurnitureItemView groupItem={ item } /> }
|
||||
items={ filteredGroupItems } />
|
||||
</div>
|
||||
<div className="flex flex-col col-span-5 overflow-hidden">
|
||||
<div className="relative flex flex-col overflow-hidden">
|
||||
<div className="flex flex-col col-span-5">
|
||||
<div className="relative flex flex-col">
|
||||
<LayoutRoomPreviewerView height={ 140 } roomPreviewer={ roomPreviewer } />
|
||||
{ selectedItem && selectedItem.stuffData.isUnique &&
|
||||
<LayoutLimitedEditionCompactPlateView className="top-2 end-2" position="absolute" uniqueNumber={ selectedItem.stuffData.uniqueNumber } uniqueSeries={ selectedItem.stuffData.uniqueSeries } /> }
|
||||
|
@ -130,16 +128,16 @@ export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
|
|||
</div>
|
||||
{ selectedItem &&
|
||||
<div className="flex flex-col justify-between gap-2 grow">
|
||||
<span className="truncate grow">{ selectedItem.name }</span>
|
||||
<span className="text-sm truncate grow">{ selectedItem.name }</span>
|
||||
<div className="flex flex-col gap-1">
|
||||
{ !!roomSession &&
|
||||
<Button variant="success" onClick={ event => attemptItemPlacement(selectedItem) }>
|
||||
<NitroButton onClick={ event => attemptItemPlacement(selectedItem) }>
|
||||
{ LocalizeText('inventory.furni.placetoroom') }
|
||||
</Button> }
|
||||
</NitroButton> }
|
||||
{ (selectedItem && selectedItem.isSellable) &&
|
||||
<Button onClick={ event => attemptPlaceMarketplaceOffer(selectedItem) }>
|
||||
<NitroButton onClick={ event => attemptPlaceMarketplaceOffer(selectedItem) }>
|
||||
{ LocalizeText('inventory.marketplace.sell') }
|
||||
</Button> }
|
||||
</NitroButton> }
|
||||
</div>
|
||||
</div> }
|
||||
</div>
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { MouseEventType } from '@nitrots/nitro-renderer';
|
||||
import { FC, MouseEvent, PropsWithChildren, useState } from 'react';
|
||||
import { attemptPetPlacement, IPetItem, UnseenItemCategory } from '../../../../api';
|
||||
import { LayoutGridItem, LayoutPetImageView } from '../../../../common';
|
||||
import { IPetItem, UnseenItemCategory, attemptPetPlacement } from '../../../../api';
|
||||
import { LayoutPetImageView } from '../../../../common';
|
||||
import { useInventoryPets, useInventoryUnseenTracker } from '../../../../hooks';
|
||||
import { InfiniteGrid } from '../../../../layout';
|
||||
|
||||
export const InventoryPetItemView: FC<PropsWithChildren<{ petItem: IPetItem }>> = props =>
|
||||
{
|
||||
|
@ -35,9 +36,9 @@ export const InventoryPetItemView: FC<PropsWithChildren<{ petItem: IPetItem }>>
|
|||
}
|
||||
|
||||
return (
|
||||
<LayoutGridItem itemActive={ (petItem === selectedPet) } itemUnseen={ unseen } onDoubleClick={ onMouseEvent } onMouseDown={ onMouseEvent } onMouseOut={ onMouseEvent } onMouseUp={ onMouseEvent } { ...rest }>
|
||||
<InfiniteGrid.Item itemActive={ (petItem === selectedPet) } itemUnseen={ unseen } onDoubleClick={ onMouseEvent } onMouseDown={ onMouseEvent } onMouseOut={ onMouseEvent } onMouseUp={ onMouseEvent } { ...rest }>
|
||||
<LayoutPetImageView direction={ 3 } figure={ petItem.petData.figureData.figuredata } headOnly={ true } />
|
||||
{ children }
|
||||
</LayoutGridItem>
|
||||
</InfiniteGrid.Item>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
import { GetRoomEngine, IRoomSession, RoomObjectVariable, RoomPreviewer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { LocalizeText, UnseenItemCategory, attemptPetPlacement } from '../../../../api';
|
||||
import { AutoGrid, Button, Column, Grid, LayoutRoomPreviewerView, Text } from '../../../../common';
|
||||
import { IPetItem, LocalizeText, UnseenItemCategory, attemptPetPlacement } from '../../../../api';
|
||||
import { LayoutRoomPreviewerView } from '../../../../common';
|
||||
import { useInventoryPets, useInventoryUnseenTracker } from '../../../../hooks';
|
||||
import { InfiniteGrid, NitroButton } from '../../../../layout';
|
||||
import { InventoryCategoryEmptyView } from '../InventoryCategoryEmptyView';
|
||||
import { InventoryPetItemView } from './InventoryPetItemView';
|
||||
|
||||
interface InventoryPetViewProps
|
||||
{
|
||||
export const InventoryPetView: FC<{
|
||||
roomSession: IRoomSession;
|
||||
roomPreviewer: RoomPreviewer;
|
||||
}
|
||||
|
||||
export const InventoryPetView: FC<InventoryPetViewProps> = props =>
|
||||
}> = props =>
|
||||
{
|
||||
const { roomSession = null, roomPreviewer = null } = props;
|
||||
const [ isVisible, setIsVisible ] = useState(false);
|
||||
|
@ -66,25 +64,26 @@ export const InventoryPetView: FC<InventoryPetViewProps> = props =>
|
|||
if(!petItems || !petItems.length) return <InventoryCategoryEmptyView desc={ LocalizeText('inventory.empty.pets.desc') } title={ LocalizeText('inventory.empty.pets.title') } />;
|
||||
|
||||
return (
|
||||
<Grid>
|
||||
<Column overflow="hidden" size={ 7 }>
|
||||
<AutoGrid columnCount={ 5 }>
|
||||
{ petItems && (petItems.length > 0) && petItems.map(item => <InventoryPetItemView key={ item.petData.id } petItem={ item } />) }
|
||||
</AutoGrid>
|
||||
</Column>
|
||||
<Column overflow="auto" size={ 5 }>
|
||||
<Column overflow="hidden" position="relative">
|
||||
<div className="grid h-full grid-cols-12 gap-2">
|
||||
<div className="flex flex-col col-span-7 gap-1 overflow-hidden">
|
||||
<InfiniteGrid<IPetItem>
|
||||
columnCount={ 6 }
|
||||
itemRender={ item => <InventoryPetItemView petItem={ item } /> }
|
||||
items={ petItems } />
|
||||
</div>
|
||||
<div className="flex flex-col col-span-5">
|
||||
<div className="relative flex flex-col">
|
||||
<LayoutRoomPreviewerView height={ 140 } roomPreviewer={ roomPreviewer } />
|
||||
</Column>
|
||||
</div>
|
||||
{ selectedPet && selectedPet.petData &&
|
||||
<Column grow gap={ 2 } justifyContent="between">
|
||||
<Text grow truncate>{ selectedPet.petData.name }</Text>
|
||||
<div className="flex flex-col justify-between gap-2 grow">
|
||||
<span className="text-sm truncate grow">{ selectedPet.petData.name }</span>
|
||||
{ !!roomSession &&
|
||||
<Button variant="success" onClick={ event => attemptPetPlacement(selectedPet) }>
|
||||
<NitroButton onClick={ event => attemptPetPlacement(selectedPet) }>
|
||||
{ LocalizeText('inventory.furni.placetoroom') }
|
||||
</Button> }
|
||||
</Column> }
|
||||
</Column>
|
||||
</Grid>
|
||||
</NitroButton> }
|
||||
</div> }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { FC } from 'react';
|
||||
import { Column } from '../../common';
|
||||
|
||||
interface LoadingViewProps
|
||||
{
|
||||
|
@ -8,14 +7,38 @@ interface LoadingViewProps
|
|||
export const LoadingView: FC<LoadingViewProps> = props =>
|
||||
{
|
||||
const {} = props;
|
||||
|
||||
const generateStars = (count, className) =>
|
||||
{
|
||||
return Array.from({ length: count }, () => ({
|
||||
top: `${ Math.random() * 100 }%`,
|
||||
left: `${ Math.random() * 100 }%`
|
||||
})).map((style, index) => (
|
||||
<div key={ index } className={ className } style={ style }>
|
||||
<div className="star-part" />
|
||||
<div className="star-part" />
|
||||
</div>
|
||||
));
|
||||
};
|
||||
|
||||
const smallStars = generateStars(90, 'dot');
|
||||
const mediumStars = generateStars(15, 'star');
|
||||
|
||||
return (
|
||||
<Column fullHeight className="nitro-loading" position="relative">
|
||||
<div className="container h-100">
|
||||
<Column fullHeight alignItems="center" justifyContent="end">
|
||||
<div className="connecting-duck" />
|
||||
</Column>
|
||||
<div className="relative w-screen h-screen z-loading bg-loading">
|
||||
<div className="container flex w-screen h-screen">
|
||||
<div className="flex items-center justify-center w-screen h-screen">
|
||||
{ smallStars }
|
||||
{ mediumStars }
|
||||
</div>
|
||||
</div>
|
||||
</Column>
|
||||
</div>
|
||||
/* <div className="relative w-screen h-screen z-loading bg-card-header">
|
||||
<div className="container flex w-screen h-screen">
|
||||
<div className="flex items-center justify-center w-screen h-screen">
|
||||
<div className="connecting-duck" />
|
||||
</div>
|
||||
</div>
|
||||
</div>*/
|
||||
);
|
||||
}
|
||||
|
|
266
src/index.css
266
src/index.css
|
@ -75,6 +75,123 @@ body {
|
|||
}
|
||||
|
||||
@layer components {
|
||||
@keyframes blink {
|
||||
0%,
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes scale {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.5);
|
||||
}
|
||||
}
|
||||
|
||||
.dot {
|
||||
position: absolute;
|
||||
width: 2px;
|
||||
height: 2px;
|
||||
background-color: white;
|
||||
animation: blink 2s infinite;
|
||||
}
|
||||
|
||||
.star {
|
||||
position: absolute;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
color: #ffffff;
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: currentColor;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
-webkit-animation: blink 1s linear infinite;
|
||||
animation: blink 1s linear infinite;
|
||||
}
|
||||
|
||||
.star-part {
|
||||
position: absolute;
|
||||
background-color: currentColor;
|
||||
|
||||
&:nth-child(1) {
|
||||
top: 0;
|
||||
left: 50%;
|
||||
width: 1px;
|
||||
height: 100%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
top: 50%;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.connecting-duck {
|
||||
@apply absolute inset-0 m-auto;
|
||||
background: url("@/assets/images/loading/connecting-duck-spritesheet.png")
|
||||
no-repeat top left;
|
||||
width: 235px;
|
||||
height: 127px;
|
||||
animation: connecting-duck 1.5s infinite step-end;
|
||||
transform: scale(0.5);
|
||||
}
|
||||
|
||||
@keyframes connecting-duck {
|
||||
0% {
|
||||
background-position: 0 0;
|
||||
width: 235px;
|
||||
height: 127px;
|
||||
}
|
||||
15% {
|
||||
background-position: 0 -132px;
|
||||
width: 280px;
|
||||
height: 151px;
|
||||
}
|
||||
30% {
|
||||
background-position: 0 -288px;
|
||||
width: 326px;
|
||||
height: 174px;
|
||||
}
|
||||
45% {
|
||||
background-position: 0 -467px;
|
||||
width: 235px;
|
||||
height: 127px;
|
||||
}
|
||||
60% {
|
||||
background-position: 0 -599px;
|
||||
width: 280px;
|
||||
height: 151px;
|
||||
}
|
||||
75% {
|
||||
background-position: 0 -755px;
|
||||
width: 326px;
|
||||
height: 174px;
|
||||
}
|
||||
90% {
|
||||
background-position: 0 -934px;
|
||||
width: 190px;
|
||||
height: 104px;
|
||||
}
|
||||
}
|
||||
|
||||
.avatar-image {
|
||||
@apply pointer-events-none relative h-[130px] w-[90px] bg-[center_-8px] bg-no-repeat;
|
||||
}
|
||||
|
@ -277,6 +394,11 @@ body {
|
|||
background-image: url("@/assets/images/chat/styles-icon.png");
|
||||
width: 17px;
|
||||
height: 19px;
|
||||
filter: grayscale(100%);
|
||||
|
||||
&:hover {
|
||||
filter: grayscale(0%);
|
||||
}
|
||||
}
|
||||
|
||||
&.pencil-icon {
|
||||
|
@ -709,3 +831,147 @@ body {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.unique-item {
|
||||
.unique-bg-override {
|
||||
@apply z-[2] bg-center bg-no-repeat;
|
||||
}
|
||||
|
||||
&:before {
|
||||
@apply absolute z-[1] size-full bg-center bg-no-repeat [content:""];
|
||||
background-image: url("@/assets/images/unique/grid-bg.png");
|
||||
}
|
||||
|
||||
&:after {
|
||||
@apply absolute bottom-0 z-[4] size-full bg-center bg-no-repeat [content:""];
|
||||
background-image: url("@/assets/images/unique/grid-bg-glass.png");
|
||||
}
|
||||
|
||||
&.sold-out:after {
|
||||
@apply bg-center bg-no-repeat;
|
||||
background-image: url("@/assets/images/unique/grid-bg-sold-out.png"),
|
||||
url("@/assets/images/unique/grid-bg-glass.png");
|
||||
}
|
||||
|
||||
.unique-item-counter {
|
||||
background-image: url("@/assets/images/unique/grid-count-bg.png");
|
||||
@apply bottom-[1px] z-[3] mx-auto my-0 flex h-[9px] w-full items-center justify-center bg-center bg-no-repeat;
|
||||
}
|
||||
}
|
||||
|
||||
.unique-sold-out-blocker {
|
||||
width: 364px;
|
||||
height: 30px;
|
||||
background: url("@/assets/images/unique/catalog-info-sold-out.png");
|
||||
|
||||
div {
|
||||
float: right;
|
||||
width: 140px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
margin-top: 5px;
|
||||
margin-right: 17px;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
.unique-compact-plate {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
right: 16px;
|
||||
width: 34px;
|
||||
height: 37px;
|
||||
background: url("@/assets/images/unique/inventory-info-amount-bg.png");
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 9.5px;
|
||||
}
|
||||
}
|
||||
|
||||
.unique-complete-plate {
|
||||
width: 170px;
|
||||
height: 29px;
|
||||
background: url("@/assets/images/unique/catalog-info-amount-bg.png")
|
||||
no-repeat center;
|
||||
z-index: 1;
|
||||
padding-top: 3px;
|
||||
|
||||
.plate-container {
|
||||
margin-left: 45px;
|
||||
width: 100px;
|
||||
font-size: 10px;
|
||||
color: black;
|
||||
|
||||
> :first-child {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.limited-edition-number {
|
||||
display: inline-block;
|
||||
outline: 0;
|
||||
height: 5px;
|
||||
margin-right: 1px;
|
||||
background-image: url("@/assets/images/unique/numbers.png");
|
||||
background-repeat: no-repeat;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
&.n-0 {
|
||||
width: 4px;
|
||||
background-position: -1px 0px;
|
||||
}
|
||||
|
||||
&.n-1 {
|
||||
width: 2px;
|
||||
background-position: -6px 0px;
|
||||
}
|
||||
|
||||
&.n-2 {
|
||||
width: 4px;
|
||||
background-position: -9px 0px;
|
||||
}
|
||||
|
||||
&.n-3 {
|
||||
width: 4px;
|
||||
background-position: -14px 0px;
|
||||
}
|
||||
|
||||
&.n-4 {
|
||||
width: 4px;
|
||||
background-position: -19px 0px;
|
||||
}
|
||||
|
||||
&.n-5 {
|
||||
width: 4px;
|
||||
background-position: -24px 0px;
|
||||
}
|
||||
|
||||
&.n-6 {
|
||||
width: 4px;
|
||||
background-position: -29px 0px;
|
||||
}
|
||||
|
||||
&.n-7 {
|
||||
width: 4px;
|
||||
background-position: -34px 0px;
|
||||
}
|
||||
|
||||
&.n-8 {
|
||||
width: 4px;
|
||||
background-position: -39px 0px;
|
||||
}
|
||||
|
||||
&.n-9 {
|
||||
width: 4px;
|
||||
background-position: -44px 0px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { useVirtualizer } from '@tanstack/react-virtual';
|
||||
import { DetailedHTMLProps, Fragment, HTMLAttributes, ReactElement, forwardRef, useEffect, useRef, useState } from 'react';
|
||||
import { classNames } from './classNames';
|
||||
import { NitroLimitedEditionStyledNumberView } from './limited-edition';
|
||||
import { styleNames } from './styleNames';
|
||||
|
||||
type Props<T> = {
|
||||
|
@ -68,9 +69,10 @@ const InfiniteGridRoot = <T,>(props: Props<T>) =>
|
|||
<div
|
||||
key={ virtualRow.key + 'a' }
|
||||
ref={ virtualizer.measureElement }
|
||||
className={ `grid grid-cols-${ columnCount } gap-1 absolute top-0 left-0 h-[45px] last:pb-0 w-full` }
|
||||
className={ `grid grid-cols-${ columnCount } gap-1 absolute top-0 left-0 last:pb-0 w-full` }
|
||||
data-index={ virtualRow.index }
|
||||
style={ {
|
||||
height: virtualRow.size,
|
||||
transform: `translateY(${ virtualRow.start }px)`
|
||||
} }>
|
||||
{ Array.from(Array(columnCount)).map((e,i) =>
|
||||
|
@ -141,8 +143,11 @@ const InfiniteGridItem = forwardRef<HTMLDivElement, {
|
|||
ref={ ref }
|
||||
className={ classNames(
|
||||
'flex flex-col items-center justify-center cursor-pointer overflow-hidden relative bg-center bg-no-repeat w-full rounded-md border-2',
|
||||
(!backgroundImageUrl || !backgroundImageUrl.length) && 'nitro-icon icon-loading',
|
||||
(itemImage && (!backgroundImageUrl || !backgroundImageUrl.length)) && 'nitro-icon icon-loading',
|
||||
itemActive ? 'border-card-grid-item-active bg-card-grid-item-active' : 'border-card-grid-item-border bg-card-grid-item',
|
||||
(itemUniqueSoldout || (itemUniqueNumber > 0)) && 'unique-item',
|
||||
itemUniqueSoldout && 'sold-out',
|
||||
itemUnseen && ' bg-green-500 bg-opacity-40',
|
||||
className
|
||||
) }
|
||||
style={ styleNames(
|
||||
|
@ -152,6 +157,19 @@ const InfiniteGridItem = forwardRef<HTMLDivElement, {
|
|||
style
|
||||
) }
|
||||
{ ...rest }>
|
||||
{ (itemCount > itemCountMinimum) &&
|
||||
<div className="absolute align-middle rounded bg-red-700 bg-opacity-80 text-white border-black border top-[2px] right-[2px] text-[9.5px] p-[2px] z-[1] leading-[8px]">{ itemCount }</div> }
|
||||
{ (itemUniqueNumber > 0) &&
|
||||
<>
|
||||
<div
|
||||
className="size-full unique-bg-override"
|
||||
style={ {
|
||||
backgroundImage: `url(${ backgroundImageUrl })`
|
||||
} } />
|
||||
<div className="absolute bottom-0 unique-item-counter">
|
||||
<NitroLimitedEditionStyledNumberView value={ itemUniqueNumber } />
|
||||
</div>
|
||||
</> }
|
||||
{ children }
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
import { ButtonHTMLAttributes, DetailedHTMLProps, forwardRef, PropsWithChildren } from 'react';
|
||||
import { classNames } from './classNames';
|
||||
|
||||
const classes = {
|
||||
base: 'inline-flex justify-center items-center gap-2 transition-[background-color] duration-300 transform tracking-wide rounded-md',
|
||||
disabled: '',
|
||||
size: {
|
||||
default: 'px-2 py-0.5 text-sm font-medium',
|
||||
lg: 'px-5 py-3 text-base font-medium',
|
||||
xl: 'px-6 py-3.5 text-base font-medium',
|
||||
},
|
||||
outline: {
|
||||
default: 'text-blue-700 hover:text-white border border-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 dark:border-blue-500 dark:text-blue-500 dark:hover:text-white dark:hover:bg-blue-600 dark:focus:ring-blue-800'
|
||||
},
|
||||
color: {
|
||||
default: 'bg-button-gradient-gray border border-gray-500',
|
||||
}
|
||||
}
|
||||
|
||||
export const NitroButton = forwardRef<HTMLButtonElement, PropsWithChildren<{
|
||||
color?: 'default' | 'dark' | 'ghost';
|
||||
size?: 'default' | 'lg' | 'xl';
|
||||
outline?: boolean;
|
||||
}> & DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>>((props, ref) =>
|
||||
{
|
||||
const { color = 'default', size = 'default', outline = false, disabled = false, type = 'button', className = null, ...rest } = props;
|
||||
|
||||
return (
|
||||
<button
|
||||
ref={ ref }
|
||||
className={ classNames(
|
||||
classes.base,
|
||||
classes.size[size],
|
||||
outline ? classes.outline[color] : classes.color[color],
|
||||
disabled && classes.disabled,
|
||||
className
|
||||
) }
|
||||
disabled={ disabled }
|
||||
type={ type }
|
||||
{ ...rest } />
|
||||
);
|
||||
});
|
||||
|
||||
NitroButton.displayName = 'NitroButton';
|
|
@ -13,7 +13,7 @@ const NitroCardRoot = forwardRef<HTMLDivElement, PropsWithChildren<{
|
|||
<div
|
||||
ref={ ref }
|
||||
className={ classNames(
|
||||
'flex flex-col rounded-md shadow border border-card-border overflow-hidden min-w-full min-h-full max-w-full max-h-full',
|
||||
'flex flex-col rounded-md shadow border-2 border-card-border overflow-hidden min-w-full min-h-full max-w-full max-h-full',
|
||||
className
|
||||
) }
|
||||
{ ...rest } />
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
import { DetailedHTMLProps, forwardRef, InputHTMLAttributes, PropsWithChildren } from 'react';
|
||||
import { classNames } from './classNames';
|
||||
|
||||
const classes = {
|
||||
base: 'block w-full placeholder-gray-400 border border-gray-300 shadow-sm appearance-none',
|
||||
disabled: '',
|
||||
size: {
|
||||
default: 'px-2 py-2 text-sm font-medium',
|
||||
},
|
||||
rounded: 'rounded-md',
|
||||
color: {
|
||||
default: 'focus:outline-none focus:ring-indigo-500 focus:border-indigo-500',
|
||||
}
|
||||
}
|
||||
|
||||
export const NitroInput = forwardRef<HTMLInputElement, PropsWithChildren<{
|
||||
color?: 'default' | 'dark' | 'ghost';
|
||||
inputSize?: 'xs' | 'sm' | 'default' | 'lg' | 'xl';
|
||||
rounded?: boolean;
|
||||
}> & DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>>((props, ref) =>
|
||||
{
|
||||
const { color = 'default', inputSize = 'default', rounded = true, disabled = false, type = 'text', autoComplete = 'off', className = null, ...rest } = props;
|
||||
|
||||
return (
|
||||
<input
|
||||
ref={ ref }
|
||||
autoComplete={ autoComplete }
|
||||
className={ classNames(
|
||||
classes.base,
|
||||
classes.size[inputSize],
|
||||
rounded && classes.rounded,
|
||||
classes.color[color],
|
||||
disabled && classes.disabled,
|
||||
className
|
||||
) }
|
||||
disabled={ disabled }
|
||||
type={ type }
|
||||
{ ...rest } />
|
||||
);
|
||||
});
|
||||
|
||||
NitroInput.displayName = 'NitroInput';
|
|
@ -1,5 +1,8 @@
|
|||
export * from './InfiniteGrid';
|
||||
export * from './NitroButton';
|
||||
export * from './NitroCard';
|
||||
export * from './NitroInput';
|
||||
export * from './NitroItemCountBadge';
|
||||
export * from './classNames';
|
||||
export * from './limited-edition';
|
||||
export * from './styleNames';
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import { FC } from 'react';
|
||||
|
||||
export const NitroLimitedEditionStyledNumberView: FC<{
|
||||
value: number;
|
||||
}> = props =>
|
||||
{
|
||||
const { value = 0 } = props;
|
||||
|
||||
return (
|
||||
<>
|
||||
{ value.toString().split('').map((number, index) =>
|
||||
<i
|
||||
key={ index }
|
||||
className={ 'limited-edition-number n-' + number } />
|
||||
) }
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export * from './NitroLimitedEditionStyledNumberView';
|
|
@ -15,10 +15,12 @@ const colors = {
|
|||
'card-grid-item-active': '#ECECEC',
|
||||
'card-grid-item-border': '#B6BEC5',
|
||||
'card-grid-item-border-active': '#FFFFFF',
|
||||
'loading': '#393A85'
|
||||
};
|
||||
|
||||
const boxShadow = {
|
||||
'inner1px': 'inset 0 0 0 1px rgba(255,255,255,.3)'
|
||||
'inner1px': 'inset 0 0 0 1px rgba(255,255,255,.3)',
|
||||
'room-previewer': '-2px -2px rgba(0, 0, 0, 0.4), inset 3px 3px rgba(0, 0, 0, 0.2);'
|
||||
};
|
||||
|
||||
|
||||
|
@ -30,6 +32,9 @@ module.exports = {
|
|||
},
|
||||
colors: generateShades(colors),
|
||||
boxShadow,
|
||||
backgroundImage: {
|
||||
'button-gradient-gray': 'linear-gradient(to bottom, #e2e2e2 50%, #c8c8c8 50%)',
|
||||
},
|
||||
spacing: {
|
||||
'card-header': '33px',
|
||||
'card-tabs': '33px',
|
||||
|
@ -39,8 +44,9 @@ module.exports = {
|
|||
'inventory-h': '320px'
|
||||
},
|
||||
zIndex: {
|
||||
'toolbar': ''
|
||||
}
|
||||
'toolbar': '',
|
||||
'loading': '100'
|
||||
},
|
||||
},
|
||||
},
|
||||
safelist: [
|
||||
|
|
Loading…
Reference in New Issue