@rpg-engine/long-bow 0.7.97 → 0.7.99

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/components/DPad/JoystickDPad.d.ts +21 -0
  2. package/dist/components/InformationCenter/InformationCenter.d.ts +29 -0
  3. package/dist/components/InformationCenter/InformationCenterCell.d.ts +14 -0
  4. package/dist/components/InformationCenter/InformationCenterTabView.d.ts +19 -0
  5. package/dist/components/InformationCenter/InformationCenterTypes.d.ts +79 -0
  6. package/dist/components/InformationCenter/sections/bestiary/BestiarySection.d.ts +12 -0
  7. package/dist/components/InformationCenter/sections/bestiary/InformationCenterNPCDetails.d.ts +12 -0
  8. package/dist/components/InformationCenter/sections/bestiary/InformationCenterNPCTooltip.d.ts +9 -0
  9. package/dist/components/InformationCenter/sections/faq/FaqSection.d.ts +8 -0
  10. package/dist/components/InformationCenter/sections/items/InformationCenterItemDetails.d.ts +11 -0
  11. package/dist/components/InformationCenter/sections/items/InformationCenterItemTooltip.d.ts +7 -0
  12. package/dist/components/InformationCenter/sections/items/ItemsSection.d.ts +11 -0
  13. package/dist/components/InformationCenter/sections/tutorials/TutorialsSection.d.ts +8 -0
  14. package/dist/components/InformationCenter/shared/BaseInformationDetails.d.ts +10 -0
  15. package/dist/components/shared/BaseTooltip.d.ts +12 -0
  16. package/dist/components/shared/Collapsible/Collapsible.d.ts +9 -0
  17. package/dist/components/shared/Portal/Portal.d.ts +6 -0
  18. package/dist/index.d.ts +1 -0
  19. package/dist/long-bow.cjs.development.js +271 -5
  20. package/dist/long-bow.cjs.development.js.map +1 -1
  21. package/dist/long-bow.cjs.production.min.js +1 -1
  22. package/dist/long-bow.cjs.production.min.js.map +1 -1
  23. package/dist/long-bow.esm.js +273 -8
  24. package/dist/long-bow.esm.js.map +1 -1
  25. package/dist/mocks/informationCenter.mocks.d.ts +6 -0
  26. package/dist/stories/Features/craftbook/CraftBook.stories.d.ts +2 -0
  27. package/dist/stories/UI/info/InformationCenter.stories.d.ts +7 -0
  28. package/dist/stories/UI/joystick/JoystickDPad.stories.d.ts +6 -0
  29. package/package.json +1 -1
  30. package/src/components/CraftBook/CraftBook.tsx +70 -31
  31. package/src/components/DPad/JoystickDPad.tsx +417 -0
  32. package/src/components/InformationCenter/InformationCenter.tsx +155 -0
  33. package/src/components/InformationCenter/InformationCenterCell.tsx +96 -0
  34. package/src/components/InformationCenter/InformationCenterTabView.tsx +121 -0
  35. package/src/components/InformationCenter/InformationCenterTypes.ts +87 -0
  36. package/src/components/InformationCenter/sections/bestiary/BestiarySection.tsx +170 -0
  37. package/src/components/InformationCenter/sections/bestiary/InformationCenterNPCDetails.tsx +366 -0
  38. package/src/components/InformationCenter/sections/bestiary/InformationCenterNPCTooltip.tsx +204 -0
  39. package/src/components/InformationCenter/sections/faq/FaqSection.tsx +71 -0
  40. package/src/components/InformationCenter/sections/items/InformationCenterItemDetails.tsx +323 -0
  41. package/src/components/InformationCenter/sections/items/InformationCenterItemTooltip.tsx +88 -0
  42. package/src/components/InformationCenter/sections/items/ItemsSection.tsx +180 -0
  43. package/src/components/InformationCenter/sections/tutorials/TutorialsSection.tsx +144 -0
  44. package/src/components/InformationCenter/shared/BaseInformationDetails.tsx +162 -0
  45. package/src/components/InternalTabs/InternalTabs.tsx +1 -3
  46. package/src/components/shared/BaseTooltip.tsx +60 -0
  47. package/src/components/shared/Collapsible/Collapsible.tsx +70 -0
  48. package/src/components/shared/Portal/Portal.tsx +19 -0
  49. package/src/index.tsx +1 -0
  50. package/src/mocks/informationCenter.mocks.ts +562 -0
  51. package/src/stories/Features/craftbook/CraftBook.stories.tsx +15 -1
  52. package/src/stories/UI/info/InformationCenter.stories.tsx +58 -0
  53. package/src/stories/UI/joystick/JoystickDPad.stories.tsx +52 -0
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ interface IDPadOptions {
3
+ /** Opacity of the entire component (0-1) */
4
+ opacity?: number;
5
+ /** Show the silver background behind the controller (default: false) */
6
+ showBackground?: boolean;
7
+ /** Size in pixels (default: 100) */
8
+ size?: number;
9
+ /** Interval in ms for continuous press events (default: 500) */
10
+ pressInterval?: number;
11
+ }
12
+ interface IDPadProps {
13
+ /** Callback fired when a direction is pressed */
14
+ onDirectionPress?: (direction: 'up' | 'down' | 'left' | 'right') => void;
15
+ /** Whether the component is disabled */
16
+ disabled?: boolean;
17
+ /** Additional options for customizing the D-pad */
18
+ options?: IDPadOptions;
19
+ }
20
+ export declare const JoystickDPad: React.MemoExoticComponent<({ onDirectionPress, disabled, options, }: IDPadProps) => JSX.Element>;
21
+ export {};
@@ -0,0 +1,29 @@
1
+ import React from 'react';
2
+ import { IInformationCenterItem, IInformationCenterNPC } from './InformationCenterTypes';
3
+ export interface IFaqItem {
4
+ id: string;
5
+ question: string;
6
+ answer: string;
7
+ }
8
+ export interface IVideoGuide {
9
+ id: string;
10
+ title: string;
11
+ description: string;
12
+ thumbnailUrl: string;
13
+ videoUrl: string;
14
+ category: 'Combat' | 'Crafting' | 'Exploration' | 'General';
15
+ }
16
+ export interface IInformationCenterProps {
17
+ itemsAtlasJSON: Record<string, any>;
18
+ itemsAtlasIMG: string;
19
+ entitiesAtlasJSON: Record<string, any>;
20
+ entitiesAtlasIMG: string;
21
+ faqItems?: IFaqItem[];
22
+ bestiaryItems?: IInformationCenterNPC[];
23
+ videoGuides?: IVideoGuide[];
24
+ items?: IInformationCenterItem[];
25
+ loading?: boolean;
26
+ error?: string;
27
+ initialSearchQuery?: string;
28
+ }
29
+ export declare const InformationCenter: React.FC<IInformationCenterProps>;
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ interface IInformationCenterCellProps {
3
+ name: string;
4
+ spriteKey: string;
5
+ atlasJSON: any;
6
+ atlasIMG: string;
7
+ onClick?: () => void;
8
+ onMouseEnter?: (e: React.MouseEvent) => void;
9
+ onMouseLeave?: () => void;
10
+ onMouseMove?: (e: React.MouseEvent) => void;
11
+ onTouchStart?: (e: React.TouchEvent) => void;
12
+ }
13
+ export declare const InformationCenterCell: React.FC<IInformationCenterCellProps>;
14
+ export {};
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { IOptionsProps } from '../Dropdown';
3
+ interface IInformationCenterTabViewProps<T> {
4
+ items: T[];
5
+ searchQuery: string;
6
+ onSearchChange: (query: string) => void;
7
+ filterItems: (items: T[]) => T[];
8
+ renderContent: (items: T[]) => React.ReactNode;
9
+ searchPlaceholder: string;
10
+ filterOptions?: {
11
+ options: IOptionsProps[];
12
+ selectedOption: string;
13
+ onOptionChange: (value: string) => void;
14
+ };
15
+ emptyMessage?: string;
16
+ dependencies?: any[];
17
+ }
18
+ export declare function InformationCenterTabView<T>({ items, searchQuery, onSearchChange, filterItems, renderContent, searchPlaceholder, filterOptions, emptyMessage, dependencies, }: IInformationCenterTabViewProps<T>): React.ReactElement;
19
+ export {};
@@ -0,0 +1,79 @@
1
+ import { EntityAttackType, ICharacterPermanentBuff, IEquippableItemBlueprint, INPCLoot, ItemRarities, NPCAlignment, NPCSubtype, RangeTypes } from '@rpg-engine/shared';
2
+ export declare enum MovementSpeed {
3
+ ExtraSlow = 1.5,
4
+ Slow = 2.25,
5
+ Standard = 2.6,
6
+ Fast = 3,
7
+ ExtraFast = 3.5
8
+ }
9
+ export declare enum EntityEffectBlueprint {
10
+ Poison = "poison",
11
+ Bleeding = "bleeding",
12
+ Freezing = "freezing",
13
+ Burning = "burning",
14
+ Corruption = "corruption",
15
+ VineGrasp = "vine-grasp",
16
+ Curse = "curse",
17
+ Drain = "drain",
18
+ Shadow = "shadow",
19
+ Stun = "stun",
20
+ Knockback = "knockback",
21
+ Rage = "rage",
22
+ Weakness = "weakness",
23
+ Cripple = "cripple",
24
+ Regeneration = "regeneration"
25
+ }
26
+ export declare enum LootProbability {
27
+ VeryRare = 0.5,
28
+ Rare = 1,
29
+ Uncommon = 10,
30
+ SemiCommon = 15,
31
+ Common = 20,
32
+ VeryCommon = 35
33
+ }
34
+ interface INPCBlueprintSpellArea {
35
+ spellKey: string;
36
+ probability: number;
37
+ power: string;
38
+ }
39
+ export interface IInformationCenterNPC {
40
+ id: string;
41
+ name: string;
42
+ key: string;
43
+ subType: NPCSubtype;
44
+ alignment: NPCAlignment;
45
+ attackType: EntityAttackType;
46
+ maxRangeAttack: RangeTypes;
47
+ speed: MovementSpeed;
48
+ baseHealth: number;
49
+ skills: {
50
+ level: number;
51
+ strength?: {
52
+ level: number;
53
+ };
54
+ dexterity?: {
55
+ level: number;
56
+ };
57
+ resistance?: {
58
+ level: number;
59
+ };
60
+ };
61
+ fleeOnLowHealth: boolean;
62
+ entityEffects: EntityEffectBlueprint[];
63
+ areaSpells: INPCBlueprintSpellArea[];
64
+ loots: INPCLoot[];
65
+ }
66
+ export interface IInformationCenterItem extends IEquippableItemBlueprint {
67
+ tier: number;
68
+ rarity: ItemRarities;
69
+ rangeType?: EntityAttackType;
70
+ basePrice: number;
71
+ canSell: boolean;
72
+ maxStackSize: number;
73
+ usableEffectDescription?: string;
74
+ entityEffects?: [EntityEffectBlueprint];
75
+ entityEffectChance?: number;
76
+ equippedBuff?: ICharacterPermanentBuff[];
77
+ equippedBuffDescription?: string;
78
+ }
79
+ export {};
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { IInformationCenterNPC } from '../../InformationCenterTypes';
3
+ interface IBestiarySectionProps {
4
+ bestiaryItems: IInformationCenterNPC[];
5
+ itemsAtlasJSON: Record<string, any>;
6
+ itemsAtlasIMG: string;
7
+ entitiesAtlasJSON: Record<string, any>;
8
+ entitiesAtlasIMG: string;
9
+ initialSearchQuery: string;
10
+ }
11
+ export declare const BestiarySection: React.FC<IBestiarySectionProps>;
12
+ export {};
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { IInformationCenterNPC } from '../../InformationCenterTypes';
3
+ interface INPCDetailsProps {
4
+ npc: IInformationCenterNPC;
5
+ itemsAtlasJSON: Record<string, any>;
6
+ itemsAtlasIMG: string;
7
+ entitiesAtlasJSON: Record<string, any>;
8
+ entitiesAtlasIMG: string;
9
+ onBack: () => void;
10
+ }
11
+ export declare const InformationCenterNPCDetails: React.FC<INPCDetailsProps>;
12
+ export {};
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { IInformationCenterNPC } from '../../InformationCenterTypes';
3
+ interface INPCTooltipProps {
4
+ npc: IInformationCenterNPC;
5
+ itemsAtlasJSON: any;
6
+ itemsAtlasIMG: string;
7
+ }
8
+ export declare const InformationCenterNPCTooltip: React.FC<INPCTooltipProps>;
9
+ export {};
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { IFaqItem } from '../../InformationCenter';
3
+ interface IFaqSectionProps {
4
+ faqItems: IFaqItem[];
5
+ initialSearchQuery: string;
6
+ }
7
+ export declare const FaqSection: React.FC<IFaqSectionProps>;
8
+ export {};
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { IInformationCenterItem, IInformationCenterNPC } from '../../InformationCenterTypes';
3
+ interface IInformationCenterItemDetailsProps {
4
+ item: IInformationCenterItem;
5
+ itemsAtlasJSON: Record<string, any>;
6
+ itemsAtlasIMG: string;
7
+ droppedBy: IInformationCenterNPC[];
8
+ onBack: () => void;
9
+ }
10
+ export declare const InformationCenterItemDetails: React.FC<IInformationCenterItemDetailsProps>;
11
+ export {};
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import { IInformationCenterItem } from '../../InformationCenterTypes';
3
+ interface IItemTooltipProps {
4
+ item: IInformationCenterItem;
5
+ }
6
+ export declare const InformationCenterItemTooltip: React.FC<IItemTooltipProps>;
7
+ export {};
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { IInformationCenterItem, IInformationCenterNPC } from '../../InformationCenterTypes';
3
+ interface IItemsSectionProps {
4
+ items: IInformationCenterItem[];
5
+ bestiaryItems: IInformationCenterNPC[];
6
+ itemsAtlasJSON: Record<string, any>;
7
+ itemsAtlasIMG: string;
8
+ initialSearchQuery: string;
9
+ }
10
+ export declare const ItemsSection: React.FC<IItemsSectionProps>;
11
+ export {};
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { IVideoGuide } from '../../InformationCenter';
3
+ interface ITutorialsSectionProps {
4
+ videoGuides: IVideoGuide[];
5
+ initialSearchQuery: string;
6
+ }
7
+ export declare const TutorialsSection: React.FC<ITutorialsSectionProps>;
8
+ export {};
@@ -0,0 +1,10 @@
1
+ import React, { ReactNode } from 'react';
2
+ export interface IBaseInformationDetailsProps {
3
+ name: string;
4
+ spriteKey: string;
5
+ atlasJSON: Record<string, any>;
6
+ atlasIMG: string;
7
+ onBack: () => void;
8
+ children?: ReactNode;
9
+ }
10
+ export declare const BaseInformationDetails: React.FC<IBaseInformationDetailsProps>;
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ interface IBaseTooltipProps {
3
+ children: React.ReactNode;
4
+ width?: string;
5
+ }
6
+ export declare const TooltipTitle: import("styled-components").StyledComponent<"div", any, {}, never>;
7
+ export declare const Section: import("styled-components").StyledComponent<"div", any, {}, never>;
8
+ export declare const SectionTitle: import("styled-components").StyledComponent<"div", any, {}, never>;
9
+ export declare const StatsContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
10
+ export declare const StatItem: import("styled-components").StyledComponent<"div", any, {}, never>;
11
+ export declare const BaseTooltip: React.FC<IBaseTooltipProps>;
12
+ export default BaseTooltip;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ interface ICollapsibleProps {
3
+ title: string;
4
+ children: React.ReactNode;
5
+ defaultOpen?: boolean;
6
+ className?: string;
7
+ }
8
+ export declare const Collapsible: React.FC<ICollapsibleProps>;
9
+ export {};
@@ -0,0 +1,6 @@
1
+ /// <reference types="react" />
2
+ interface IPortalProps {
3
+ children: React.ReactNode;
4
+ }
5
+ export declare const Portal: React.FC<IPortalProps>;
6
+ export {};
package/dist/index.d.ts CHANGED
@@ -9,6 +9,7 @@ export * from './components/CheckButton';
9
9
  export * from './components/CheckItem';
10
10
  export * from './components/CircularController/CircularController';
11
11
  export * from './components/CraftBook/CraftBook';
12
+ export * from './components/DPad/JoystickDPad';
12
13
  export * from './components/DraggableContainer';
13
14
  export * from './components/Dropdown';
14
15
  export * from './components/DropdownSelectorContainer';
@@ -28942,7 +28942,7 @@ var CraftBook = function CraftBook(_ref) {
28942
28942
  return setSearchTerm(e.target.value);
28943
28943
  },
28944
28944
  autoFocus: true
28945
- })), React__default.createElement(ContentContainer, null, React__default.createElement(RadioInputScroller, {
28945
+ })), React__default.createElement(ContentContainer, null, paginatedItems.length > 0 ? React__default.createElement(RadioInputScroller, {
28946
28946
  className: "inputRadioCraftBook"
28947
28947
  }, paginatedItems == null ? void 0 : paginatedItems.map(function (item) {
28948
28948
  return React__default.createElement(CraftingRecipeWrapper, {
@@ -28967,7 +28967,9 @@ var CraftBook = function CraftBook(_ref) {
28967
28967
  inventory: inventory,
28968
28968
  skills: skills
28969
28969
  }));
28970
- }))), totalPages > 1 && React__default.createElement(PaginationContainer, null, React__default.createElement(PaginationButton, {
28970
+ })) : React__default.createElement(EmptyState, null, React__default.createElement(fa.FaBoxOpen, {
28971
+ size: 48
28972
+ }), React__default.createElement("p", null, "No craftable items found"))), totalPages > 1 && React__default.createElement(PaginationContainer, null, React__default.createElement(PaginationButton, {
28971
28973
  onClick: function onClick() {
28972
28974
  return setCurrentPage(function (prev) {
28973
28975
  return Math.max(1, prev - 1);
@@ -29036,11 +29038,11 @@ var SearchContainer$1 = /*#__PURE__*/styled__default.div.withConfig({
29036
29038
  var ContentContainer = /*#__PURE__*/styled__default.div.withConfig({
29037
29039
  displayName: "CraftBook__ContentContainer",
29038
29040
  componentId: "sc-19q95ue-7"
29039
- })(["flex:1;min-height:0;padding:16px;padding-right:0;padding-bottom:0;overflow:hidden;width:100%;"]);
29041
+ })(["flex:1;display:flex;flex-direction:column;padding:16px;padding-right:0;padding-bottom:0;width:100%;position:relative;min-height:300px;overflow:hidden;"]);
29040
29042
  var RadioInputScroller = /*#__PURE__*/styled__default.div.withConfig({
29041
29043
  displayName: "CraftBook__RadioInputScroller",
29042
29044
  componentId: "sc-19q95ue-8"
29043
- })(["height:100%;overflow-y:scroll;overflow-x:hidden;padding:8px 16px;padding-right:24px;width:100%;box-sizing:border-box;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;align-content:start;@media (max-width:", "){grid-template-columns:1fr;}"], MOBILE_WIDTH);
29045
+ })(["height:100%;min-height:300px;overflow-y:auto;overflow-x:hidden;padding:8px 16px;padding-right:24px;width:100%;box-sizing:border-box;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;align-content:start;@media (max-width:", "){grid-template-columns:1fr;}"], MOBILE_WIDTH);
29044
29046
  var CraftingRecipeWrapper = /*#__PURE__*/styled__default.div.withConfig({
29045
29047
  displayName: "CraftBook__CraftingRecipeWrapper",
29046
29048
  componentId: "sc-19q95ue-9"
@@ -29077,6 +29079,269 @@ var PageInfo = /*#__PURE__*/styled__default.div.withConfig({
29077
29079
  displayName: "CraftBook__PageInfo",
29078
29080
  componentId: "sc-19q95ue-14"
29079
29081
  })(["color:", ";font-size:0.8rem;font-family:'Press Start 2P',cursive;"], uiColors.lightGray);
29082
+ var EmptyState = /*#__PURE__*/styled__default.div.withConfig({
29083
+ displayName: "CraftBook__EmptyState",
29084
+ componentId: "sc-19q95ue-15"
29085
+ })(["position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;color:", ";width:100%;padding:2rem;svg{font-size:3rem;margin-bottom:1rem;opacity:0.7;}p{font-family:'Press Start 2P',cursive;font-size:0.9rem;margin:0;}"], uiColors.lightGray);
29086
+
29087
+ // Memoize the styled components since they don't depend on props that change frequently
29088
+ var DPadButton = /*#__PURE__*/React.memo( /*#__PURE__*/styled__default.div.withConfig({
29089
+ displayName: "JoystickDPad__DPadButton",
29090
+ componentId: "sc-q1e3gk-0"
29091
+ })(["position:absolute;background:", ";box-shadow:", ";cursor:", ";user-select:none;transition:all 0.08s cubic-bezier(0.4,0,0.2,1);touch-action:none;-webkit-tap-highlight-color:transparent;transform-origin:center center;&:hover:not(:active){@media (hover:hover){filter:", ";}}&::after{content:'';position:absolute;width:0;height:0;border:", "px solid transparent;pointer-events:none;opacity:", ";transition:all 0.08s cubic-bezier(0.4,0,0.2,1);}&.up,&.down{width:", "px;height:", "px;left:50%;transform:translateX(-50%) scale(", ");}&.left,&.right{width:", "px;height:", "px;top:50%;transform:translateY(-50%) scale(", ");}&.up{top:0;border-radius:5px 5px 0 0;&::after{border-bottom-color:#2a2a2a;top:45%;left:50%;transform:translate(-50%,-50%);}}&.down{bottom:0;border-radius:0 0 5px 5px;&::after{border-top-color:#2a2a2a;bottom:45%;left:50%;transform:translate(-50%,50%);}}&.left{left:0;border-radius:5px 0 0 5px;&::after{border-right-color:#2a2a2a;left:45%;top:50%;transform:translate(-50%,-50%);}}&.right{right:0;border-radius:0 5px 5px 0;&::after{border-left-color:#2a2a2a;right:45%;top:50%;transform:translate(50%,-50%);}}"], function (props) {
29092
+ return props.isPressed ? '#363636' : '#424242';
29093
+ }, function (props) {
29094
+ return props.isPressed ? 'inset 0 0 12px rgba(0, 0, 0, 0.8), 0 0 2px rgba(0, 0, 0, 0.3)' : 'inset 0 0 5px rgba(0, 0, 0, 0.5), 0 2px 4px rgba(0, 0, 0, 0.2)';
29095
+ }, function (props) {
29096
+ return props.disabled ? 'not-allowed' : 'pointer';
29097
+ }, function (props) {
29098
+ return !props.disabled && !props.isPressed ? 'brightness(1.1)' : 'none';
29099
+ }, function (props) {
29100
+ var _props$size;
29101
+ return ((_props$size = props.size) != null ? _props$size : 100) * 0.05;
29102
+ }, function (props) {
29103
+ return props.isPressed ? 0.7 : 1;
29104
+ }, function (props) {
29105
+ var _props$size2;
29106
+ return ((_props$size2 = props.size) != null ? _props$size2 : 100) * 0.3;
29107
+ }, function (props) {
29108
+ var _props$size3;
29109
+ return ((_props$size3 = props.size) != null ? _props$size3 : 100) * 0.4;
29110
+ }, function (props) {
29111
+ return props.isPressed ? 0.95 : 1;
29112
+ }, function (props) {
29113
+ var _props$size4;
29114
+ return ((_props$size4 = props.size) != null ? _props$size4 : 100) * 0.4;
29115
+ }, function (props) {
29116
+ var _props$size5;
29117
+ return ((_props$size5 = props.size) != null ? _props$size5 : 100) * 0.3;
29118
+ }, function (props) {
29119
+ return props.isPressed ? 0.95 : 1;
29120
+ }));
29121
+ var DPadCenter = /*#__PURE__*/React.memo( /*#__PURE__*/styled__default.div.withConfig({
29122
+ displayName: "JoystickDPad__DPadCenter",
29123
+ componentId: "sc-q1e3gk-1"
29124
+ })(["position:absolute;width:", "px;height:", "px;background:#424242;top:50%;left:50%;transform:translate(-50%,-50%);box-shadow:inset 0 0 8px rgba(0,0,0,0.6);border-radius:50%;user-select:none;cursor:", ";touch-action:none;-webkit-tap-highlight-color:transparent;&::after{content:'';position:absolute;width:", "px;height:", "px;background:#2a2a2a;border-radius:50%;top:50%;left:50%;transform:translate(-50%,-50%);pointer-events:none;box-shadow:inset 0 0 2px rgba(0,0,0,0.8);}"], function (props) {
29125
+ var _props$size6;
29126
+ return ((_props$size6 = props.size) != null ? _props$size6 : 100) * 0.3;
29127
+ }, function (props) {
29128
+ var _props$size7;
29129
+ return ((_props$size7 = props.size) != null ? _props$size7 : 100) * 0.3;
29130
+ }, function (props) {
29131
+ return props.disabled ? 'not-allowed' : 'default';
29132
+ }, function (props) {
29133
+ var _props$size8;
29134
+ return ((_props$size8 = props.size) != null ? _props$size8 : 100) * 0.08;
29135
+ }, function (props) {
29136
+ var _props$size9;
29137
+ return ((_props$size9 = props.size) != null ? _props$size9 : 100) * 0.08;
29138
+ }));
29139
+ var DPadContainer = /*#__PURE__*/React.memo( /*#__PURE__*/styled__default.div.withConfig({
29140
+ displayName: "JoystickDPad__DPadContainer",
29141
+ componentId: "sc-q1e3gk-2"
29142
+ })(["width:", "px;height:", "px;position:relative;background:", ";border-radius:50%;box-shadow:", ";opacity:", ";user-select:none;cursor:", ";transition:opacity 0.2s ease;touch-action:none;-webkit-tap-highlight-color:transparent;"], function (props) {
29143
+ var _props$size10;
29144
+ return (_props$size10 = props.size) != null ? _props$size10 : 100;
29145
+ }, function (props) {
29146
+ var _props$size11;
29147
+ return (_props$size11 = props.size) != null ? _props$size11 : 100;
29148
+ }, function (props) {
29149
+ return props.showBackground ? '#b8b8b8' : 'transparent';
29150
+ }, function (props) {
29151
+ return props.showBackground ? 'inset 0 0 10px rgba(0, 0, 0, 0.3), 0 4px 8px rgba(0, 0, 0, 0.3), 0 2px 4px rgba(0, 0, 0, 0.2)' : 'none';
29152
+ }, function (props) {
29153
+ var _props$opacity;
29154
+ return props.disabled ? 0.5 : (_props$opacity = props.opacity) != null ? _props$opacity : 1;
29155
+ }, function (props) {
29156
+ return props.disabled ? 'not-allowed' : 'default';
29157
+ }));
29158
+ var JoystickDPad = /*#__PURE__*/React.memo(function (_ref) {
29159
+ var onDirectionPress = _ref.onDirectionPress,
29160
+ _ref$disabled = _ref.disabled,
29161
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled,
29162
+ _ref$options = _ref.options,
29163
+ options = _ref$options === void 0 ? {} : _ref$options;
29164
+ var _options$opacity = options.opacity,
29165
+ opacity = _options$opacity === void 0 ? 1 : _options$opacity,
29166
+ _options$showBackgrou = options.showBackground,
29167
+ showBackground = _options$showBackgrou === void 0 ? false : _options$showBackgrou,
29168
+ _options$size = options.size,
29169
+ size = _options$size === void 0 ? 100 : _options$size,
29170
+ _options$pressInterva = options.pressInterval,
29171
+ pressInterval = _options$pressInterva === void 0 ? 500 : _options$pressInterva;
29172
+ // Use refs for values that don't need to trigger re-renders
29173
+ var _useState = React.useState(new Set()),
29174
+ pressedButtons = _useState[0],
29175
+ setPressedButtons = _useState[1];
29176
+ var intervalRef = React.useRef(null);
29177
+ var activeDirectionRef = React.useRef(null);
29178
+ var touchStartRef = React.useRef(null);
29179
+ var isPressedRef = React.useRef(false);
29180
+ var clearPressInterval = React.useCallback(function () {
29181
+ if (intervalRef.current !== null) {
29182
+ window.clearInterval(intervalRef.current);
29183
+ intervalRef.current = null;
29184
+ }
29185
+ activeDirectionRef.current = null;
29186
+ }, []);
29187
+ var clearAllPresses = React.useCallback(function () {
29188
+ clearPressInterval();
29189
+ setPressedButtons(new Set());
29190
+ activeDirectionRef.current = null;
29191
+ isPressedRef.current = false;
29192
+ }, [clearPressInterval]);
29193
+ var handleDirectionPress = React.useCallback(function (direction) {
29194
+ if (disabled) return;
29195
+ // Clear any existing presses first
29196
+ clearAllPresses();
29197
+ // Set new direction
29198
+ activeDirectionRef.current = direction;
29199
+ isPressedRef.current = true;
29200
+ setPressedButtons(new Set([direction]));
29201
+ onDirectionPress == null ? void 0 : onDirectionPress(direction);
29202
+ intervalRef.current = window.setInterval(function () {
29203
+ if (activeDirectionRef.current === direction) {
29204
+ onDirectionPress == null ? void 0 : onDirectionPress(direction);
29205
+ } else {
29206
+ clearPressInterval();
29207
+ }
29208
+ }, pressInterval);
29209
+ }, [disabled, onDirectionPress, pressInterval, clearPressInterval, clearAllPresses]);
29210
+ var handleDirectionRelease = React.useCallback(function (direction) {
29211
+ if (activeDirectionRef.current === direction) {
29212
+ clearAllPresses();
29213
+ }
29214
+ }, [clearAllPresses]);
29215
+ var handleTouchStart = React.useCallback(function (e, direction) {
29216
+ var touch = e.touches[0];
29217
+ if (touch) {
29218
+ touchStartRef.current = {
29219
+ x: touch.clientX,
29220
+ y: touch.clientY
29221
+ };
29222
+ handleDirectionPress(direction);
29223
+ }
29224
+ }, [handleDirectionPress]);
29225
+ var handleTouchMove = React.useCallback(function (e) {
29226
+ var touch = e.touches[0];
29227
+ if (!touch || !touchStartRef.current) return;
29228
+ var _touchStartRef$curren = touchStartRef.current,
29229
+ startX = _touchStartRef$curren.x,
29230
+ startY = _touchStartRef$curren.y;
29231
+ var deltaX = touch.clientX - startX;
29232
+ var deltaY = touch.clientY - startY;
29233
+ // Calculate angle and distance
29234
+ var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
29235
+ var angle = Math.atan2(deltaY, deltaX) * (180 / Math.PI);
29236
+ // Only trigger if we've moved enough
29237
+ var threshold = size * 0.15; // Adaptive threshold based on d-pad size
29238
+ if (distance < threshold) return;
29239
+ var newDirection = null;
29240
+ // Determine direction based on angle
29241
+ if (angle > -45 && angle <= 45) newDirection = 'right';else if (angle > 45 && angle <= 135) newDirection = 'down';else if (angle > 135 || angle <= -135) newDirection = 'left';else if (angle > -135 && angle <= -45) newDirection = 'up';
29242
+ if (newDirection && newDirection !== activeDirectionRef.current) {
29243
+ handleDirectionPress(newDirection);
29244
+ // Update touch start to current position to prevent jitter
29245
+ touchStartRef.current = {
29246
+ x: touch.clientX,
29247
+ y: touch.clientY
29248
+ };
29249
+ }
29250
+ }, [handleDirectionPress, size]);
29251
+ // Add a new cleanup function for touch events
29252
+ var cleanupTouchEvents = React.useCallback(function () {
29253
+ touchStartRef.current = null;
29254
+ if (activeDirectionRef.current) {
29255
+ handleDirectionRelease(activeDirectionRef.current);
29256
+ }
29257
+ }, [handleDirectionRelease]);
29258
+ // Enhance the touch end handler
29259
+ var handleTouchEnd = React.useCallback(function () {
29260
+ cleanupTouchEvents();
29261
+ }, [cleanupTouchEvents]);
29262
+ // Add touch cancel handler
29263
+ var handleTouchCancel = React.useCallback(function () {
29264
+ cleanupTouchEvents();
29265
+ }, [cleanupTouchEvents]);
29266
+ // Enhance cleanup effect
29267
+ React.useEffect(function () {
29268
+ if (disabled) {
29269
+ clearAllPresses();
29270
+ }
29271
+ var handleBlur = function handleBlur() {
29272
+ clearAllPresses();
29273
+ };
29274
+ var handleVisibilityChange = function handleVisibilityChange() {
29275
+ if (document.hidden) {
29276
+ clearAllPresses();
29277
+ }
29278
+ };
29279
+ var handlePointerUp = function handlePointerUp() {
29280
+ // Global pointer up as fallback for stuck buttons
29281
+ if (isPressedRef.current) {
29282
+ clearAllPresses();
29283
+ }
29284
+ };
29285
+ window.addEventListener('blur', handleBlur);
29286
+ window.addEventListener('pointerup', handlePointerUp);
29287
+ document.addEventListener('visibilitychange', handleVisibilityChange);
29288
+ return function () {
29289
+ clearAllPresses();
29290
+ window.removeEventListener('blur', handleBlur);
29291
+ window.removeEventListener('pointerup', handlePointerUp);
29292
+ document.removeEventListener('visibilitychange', handleVisibilityChange);
29293
+ };
29294
+ }, [disabled, clearAllPresses]);
29295
+ // Memoize the preventDefault handler
29296
+ var preventDefault = React.useCallback(function (e) {
29297
+ e.preventDefault();
29298
+ e.stopPropagation();
29299
+ }, []);
29300
+ // Memoize button props to prevent unnecessary re-renders
29301
+ var buttonProps = React.useCallback(function (direction) {
29302
+ return {
29303
+ onMouseDown: function onMouseDown() {
29304
+ return handleDirectionPress(direction);
29305
+ },
29306
+ onMouseUp: function onMouseUp() {
29307
+ return handleDirectionRelease(direction);
29308
+ },
29309
+ onMouseLeave: function onMouseLeave() {
29310
+ return handleDirectionRelease(direction);
29311
+ },
29312
+ onTouchStart: function onTouchStart(e) {
29313
+ return handleTouchStart(e, direction);
29314
+ },
29315
+ onTouchMove: handleTouchMove,
29316
+ onTouchEnd: handleTouchEnd,
29317
+ onContextMenu: preventDefault,
29318
+ size: size,
29319
+ isPressed: pressedButtons.has(direction),
29320
+ disabled: disabled
29321
+ };
29322
+ }, [handleDirectionPress, handleDirectionRelease, handleTouchStart, handleTouchMove, handleTouchEnd, preventDefault, size, pressedButtons, disabled]);
29323
+ return React__default.createElement(DPadContainer, {
29324
+ opacity: opacity,
29325
+ showBackground: showBackground,
29326
+ size: size,
29327
+ disabled: disabled,
29328
+ onContextMenu: preventDefault,
29329
+ onTouchCancel: handleTouchCancel
29330
+ }, React__default.createElement(DPadButton, Object.assign({
29331
+ className: "up"
29332
+ }, buttonProps('up'))), React__default.createElement(DPadButton, Object.assign({
29333
+ className: "right"
29334
+ }, buttonProps('right'))), React__default.createElement(DPadButton, Object.assign({
29335
+ className: "down"
29336
+ }, buttonProps('down'))), React__default.createElement(DPadButton, Object.assign({
29337
+ className: "left"
29338
+ }, buttonProps('left'))), React__default.createElement(DPadCenter, {
29339
+ size: size,
29340
+ disabled: disabled,
29341
+ onContextMenu: preventDefault
29342
+ }));
29343
+ });
29344
+ JoystickDPad.displayName = 'JoystickDPad';
29080
29345
 
29081
29346
  var DropdownSelectorContainer = function DropdownSelectorContainer(_ref) {
29082
29347
  var title = _ref.title,
@@ -30455,7 +30720,7 @@ var TabButton = /*#__PURE__*/styled__default.button.withConfig({
30455
30720
  var ContentWrapper = /*#__PURE__*/styled__default.div.withConfig({
30456
30721
  displayName: "InternalTabs__ContentWrapper",
30457
30722
  componentId: "sc-ldufv0-3"
30458
- })(["padding:1rem;"]);
30723
+ })([""]);
30459
30724
 
30460
30725
  var SlotsContainer = function SlotsContainer(_ref) {
30461
30726
  var children = _ref.children,
@@ -34333,6 +34598,7 @@ exports.ItemContainer = ItemContainer$1;
34333
34598
  exports.ItemQuantitySelectorModal = ItemQuantitySelectorModal;
34334
34599
  exports.ItemSelector = ItemSelector;
34335
34600
  exports.ItemSlot = ItemSlot;
34601
+ exports.JoystickDPad = JoystickDPad;
34336
34602
  exports.Leaderboard = Leaderboard;
34337
34603
  exports.ListMenu = ListMenu;
34338
34604
  exports.Marketplace = Marketplace;