oddsgate-ds 1.0.214 → 1.0.216
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.
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/organisms/Glossary/Glossary.component.d.ts +0 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/organisms/Glossary/Glossary.component.d.ts +0 -1
- package/dist/types.d.ts +0 -1
- package/package.json +1 -1
- package/src/components/molecules/CategoriesWrapper/CategoriesWrapper.component.tsx +4 -4
- package/src/components/molecules/CategoriesWrapper/CategoriesWrapper.theme.ts +1 -1
- package/src/components/molecules/CategoryIndex/CategoryIndex.component.tsx +3 -2
- package/src/components/organisms/Glossary/Glossary.component.tsx +6 -3
- package/src/components/organisms/Glossary/Glossary.stories.tsx +65 -231
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -24,9 +24,9 @@ const CategoriesWrapper: React.FC<CategoriesWrapperProps> = ({
|
|
|
24
24
|
<StyledCategoryContent>
|
|
25
25
|
{categoryItems.map((item, index) => (
|
|
26
26
|
<StyledCategoryItem key={index}>
|
|
27
|
-
<
|
|
28
|
-
{item.title}
|
|
29
|
-
</
|
|
27
|
+
<a href={item.slug}>
|
|
28
|
+
<Button variant="text">{item.title}</Button>
|
|
29
|
+
</a>
|
|
30
30
|
</StyledCategoryItem>
|
|
31
31
|
))}
|
|
32
32
|
</StyledCategoryContent>
|
|
@@ -36,4 +36,4 @@ const CategoriesWrapper: React.FC<CategoriesWrapperProps> = ({
|
|
|
36
36
|
)
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
export default CategoriesWrapper
|
|
39
|
+
export default CategoriesWrapper;
|
|
@@ -10,14 +10,15 @@ const CategoryIndex: React.FC<CategoryIndexProps> = ({
|
|
|
10
10
|
onChange,
|
|
11
11
|
selectedCategory
|
|
12
12
|
}) => {
|
|
13
|
-
|
|
14
13
|
return (
|
|
15
14
|
<StyledGlossaryCategoryIndex>
|
|
16
15
|
{categories.map(category => (
|
|
17
16
|
<StyledGlossaryCategoryIndexItem
|
|
18
17
|
onClick={() => onChange(category)}
|
|
19
18
|
isSelected={
|
|
20
|
-
|
|
19
|
+
category === '#'
|
|
20
|
+
? selectedCategory === '84'
|
|
21
|
+
: selectedCategory === category
|
|
21
22
|
}
|
|
22
23
|
key={`category-${category}`}
|
|
23
24
|
>
|
|
@@ -21,7 +21,6 @@ type GlossaryProps = {
|
|
|
21
21
|
setSelectedCategory: (cat: string | null) => void
|
|
22
22
|
categoryData: Record<string, { title: string; slug: string }[]>
|
|
23
23
|
placeholder?: string
|
|
24
|
-
noResults?: boolean
|
|
25
24
|
backToTopButton?: boolean
|
|
26
25
|
noResultsText?: string
|
|
27
26
|
tryAnotherLetterText?: string
|
|
@@ -34,13 +33,17 @@ export const Glossary: React.FC<GlossaryProps> = ({
|
|
|
34
33
|
setSelectedCategory,
|
|
35
34
|
categoryData,
|
|
36
35
|
placeholder,
|
|
37
|
-
noResults,
|
|
38
36
|
backToTopButton,
|
|
39
37
|
noResultsText,
|
|
40
38
|
tryAnotherLetterText
|
|
41
39
|
}) => {
|
|
40
|
+
|
|
42
41
|
const categoryNames = Object.keys(categoryData)
|
|
43
|
-
|
|
42
|
+
|
|
43
|
+
const noResults = categoryNames.every(
|
|
44
|
+
category => !categoryData[category] || categoryData[category].length === 0
|
|
45
|
+
)
|
|
46
|
+
|
|
44
47
|
return (
|
|
45
48
|
<StyledGlossary>
|
|
46
49
|
<SearchBar
|
|
@@ -1,262 +1,96 @@
|
|
|
1
1
|
import React, { useState } from 'react'
|
|
2
|
+
import { Meta, StoryObj } from '@storybook/react'
|
|
2
3
|
import Glossary from './Glossary.component'
|
|
3
|
-
interface GlossaryItem {
|
|
4
|
-
slug: string
|
|
5
|
-
name: string
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
interface GlossaryCategory {
|
|
9
|
-
name: string
|
|
10
|
-
items: GlossaryItem[]
|
|
11
|
-
}
|
|
12
4
|
|
|
13
|
-
const categories
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
name: 'B',
|
|
31
|
-
items: [
|
|
32
|
-
{ slug: 'buff', name: 'Buff' },
|
|
33
|
-
{ slug: 'boss', name: 'Boss' },
|
|
34
|
-
{ slug: 'build', name: 'Build' },
|
|
35
|
-
{ slug: 'ban', name: 'Ban' },
|
|
36
|
-
{ slug: 'beta', name: 'Beta' },
|
|
37
|
-
{ slug: 'blind', name: 'Blind' },
|
|
38
|
-
{ slug: 'block', name: 'Block' },
|
|
39
|
-
{ slug: 'bot', name: 'Bot' },
|
|
40
|
-
{ slug: 'bracket', name: 'Bracket' },
|
|
41
|
-
{ slug: 'burst', name: 'Burst' }
|
|
42
|
-
]
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
name: 'C',
|
|
46
|
-
items: [
|
|
47
|
-
{ slug: 'camp', name: 'Camp' },
|
|
48
|
-
{ slug: 'carry', name: 'Carry' },
|
|
49
|
-
{ slug: 'cc', name: 'Crowd Control' },
|
|
50
|
-
{ slug: 'cd', name: 'Cooldown' },
|
|
51
|
-
{ slug: 'cheese', name: 'Cheese' },
|
|
52
|
-
{ slug: 'clan', name: 'Clan' },
|
|
53
|
-
{ slug: 'combo', name: 'Combo' },
|
|
54
|
-
{ slug: 'crit', name: 'Critical Hit' },
|
|
55
|
-
{ slug: 'crafting', name: 'Crafting' },
|
|
56
|
-
{ slug: 'creep', name: 'Creep' }
|
|
57
|
-
]
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
name: 'D',
|
|
61
|
-
items: [
|
|
62
|
-
{ slug: 'debuff', name: 'Debuff' },
|
|
63
|
-
{ slug: 'dps', name: 'DPS' },
|
|
64
|
-
{ slug: 'drop', name: 'Drop' },
|
|
65
|
-
{ slug: 'duo', name: 'Duo' },
|
|
66
|
-
{ slug: 'dungeon', name: 'Dungeon' },
|
|
67
|
-
{ slug: 'draft', name: 'Draft' },
|
|
68
|
-
{ slug: 'dot', name: 'Damage Over Time' },
|
|
69
|
-
{ slug: 'disconnect', name: 'Disconnect' },
|
|
70
|
-
{ slug: 'drain', name: 'Drain' },
|
|
71
|
-
{ slug: 'drop-rate', name: 'Drop Rate' }
|
|
72
|
-
]
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
name: 'E',
|
|
76
|
-
items: [
|
|
77
|
-
{ slug: 'emote', name: 'Emote' },
|
|
78
|
-
{ slug: 'endgame', name: 'Endgame' },
|
|
79
|
-
{ slug: 'enemy', name: 'Enemy' },
|
|
80
|
-
{ slug: 'equip', name: 'Equip' },
|
|
81
|
-
{ slug: 'event', name: 'Event' },
|
|
82
|
-
{ slug: 'exploit', name: 'Exploit' },
|
|
83
|
-
{ slug: 'experience', name: 'Experience' },
|
|
84
|
-
{ slug: 'ez', name: 'EZ' },
|
|
85
|
-
{ slug: 'elite', name: 'Elite' },
|
|
86
|
-
{ slug: 'escape', name: 'Escape' }
|
|
87
|
-
]
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
name: 'F',
|
|
91
|
-
items: [
|
|
92
|
-
{ slug: 'farm', name: 'Farm' },
|
|
93
|
-
{ slug: 'feed', name: 'Feed' },
|
|
94
|
-
{ slug: 'flank', name: 'Flank' },
|
|
95
|
-
{ slug: 'frag', name: 'Frag' },
|
|
96
|
-
{ slug: 'fps', name: 'FPS' },
|
|
97
|
-
{ slug: 'friendly-fire', name: 'Friendly Fire' },
|
|
98
|
-
{ slug: 'faction', name: 'Faction' },
|
|
99
|
-
{ slug: 'fov', name: 'Field of View' },
|
|
100
|
-
{ slug: 'freeze', name: 'Freeze' },
|
|
101
|
-
{ slug: 'full-party', name: 'Full Party' }
|
|
102
|
-
]
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
name: 'G',
|
|
106
|
-
items: [
|
|
107
|
-
{ slug: 'gg', name: 'GG' },
|
|
108
|
-
{ slug: 'gank', name: 'Gank' },
|
|
109
|
-
{ slug: 'gear', name: 'Gear' },
|
|
110
|
-
{ slug: 'grind', name: 'Grind' },
|
|
111
|
-
{ slug: 'guild', name: 'Guild' },
|
|
112
|
-
{ slug: 'glitch', name: 'Glitch' },
|
|
113
|
-
{ slug: 'gold', name: 'Gold' },
|
|
114
|
-
{ slug: 'group', name: 'Group' },
|
|
115
|
-
{ slug: 'grenade', name: 'Grenade' },
|
|
116
|
-
{ slug: 'global', name: 'Global' }
|
|
117
|
-
]
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
name: 'H',
|
|
121
|
-
items: [
|
|
122
|
-
{ slug: 'heal', name: 'Heal' },
|
|
123
|
-
{ slug: 'headshot', name: 'Headshot' },
|
|
124
|
-
{ slug: 'hp', name: 'HP' },
|
|
125
|
-
{ slug: 'hud', name: 'HUD' },
|
|
126
|
-
{ slug: 'hardcore', name: 'Hardcore' },
|
|
127
|
-
{ slug: 'hero', name: 'Hero' },
|
|
128
|
-
{ slug: 'hitbox', name: 'Hitbox' },
|
|
129
|
-
{ slug: 'host', name: 'Host' },
|
|
130
|
-
{ slug: 'hotkey', name: 'Hotkey' },
|
|
131
|
-
{ slug: 'hunter', name: 'Hunter' }
|
|
132
|
-
]
|
|
133
|
-
}
|
|
5
|
+
const categories = [
|
|
6
|
+
{
|
|
7
|
+
name: 'A',
|
|
8
|
+
items: [
|
|
9
|
+
{ name: 'Apple', slug: 'apple' },
|
|
10
|
+
{ name: 'Apricot', slug: 'apricot' }
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
name: 'B',
|
|
15
|
+
items: [
|
|
16
|
+
{ name: 'Banana', slug: 'banana' },
|
|
17
|
+
{ name: 'Blueberry', slug: 'blueberry' }
|
|
18
|
+
]
|
|
19
|
+
}
|
|
134
20
|
]
|
|
135
21
|
|
|
136
|
-
// Helper to build categoryData from categories
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
items: BuildCategoryDataItem[]
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
interface CategoryDataItem {
|
|
148
|
-
title: string
|
|
149
|
-
slug: string
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
interface CategoryData {
|
|
153
|
-
[categoryName: string]: CategoryDataItem[]
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function buildCategoryData(
|
|
157
|
-
categories: BuildCategoryDataCategory[],
|
|
158
|
-
items: BuildCategoryDataItem[]
|
|
159
|
-
): CategoryData {
|
|
160
|
-
const data: CategoryData = {}
|
|
161
|
-
categories.forEach((cat: BuildCategoryDataCategory) => {
|
|
162
|
-
data[cat.name] = cat.items.map((item: BuildCategoryDataItem) => ({
|
|
163
|
-
title: item.name,
|
|
164
|
-
slug: item.slug
|
|
165
|
-
}))
|
|
166
|
-
})
|
|
167
|
-
return data
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Helper to filter items by searchTerm and selectedCategory
|
|
171
|
-
function getDisplayedCategories(
|
|
172
|
-
categories: any[],
|
|
173
|
-
items: never[],
|
|
174
|
-
searchTerm: string,
|
|
175
|
-
selectedCategory: string | null
|
|
176
|
-
) {
|
|
177
|
-
const filtered: Record<string | number, any[]> = {}
|
|
178
|
-
categories.forEach((cat: { items: any[]; name: string | number }) => {
|
|
179
|
-
const catItems = cat.items
|
|
180
|
-
.map((item: { name: any }) => item.name)
|
|
181
|
-
.filter(
|
|
182
|
-
( name: string) =>
|
|
183
|
-
(!searchTerm ||
|
|
184
|
-
name.toLowerCase().includes(searchTerm.toLowerCase())) &&
|
|
185
|
-
(!selectedCategory || cat.name === selectedCategory)
|
|
186
|
-
)
|
|
187
|
-
if (catItems.length > 0) filtered[cat.name] = catItems
|
|
22
|
+
// Helper to build categoryData from categories
|
|
23
|
+
function buildCategoryData(categories: any) {
|
|
24
|
+
const data: Record<string, { title: string; slug: string }[]> = {}
|
|
25
|
+
categories.forEach((cat: any) => {
|
|
26
|
+
data[cat.name] = cat.items.map((item: any) => ({
|
|
27
|
+
title: item.name,
|
|
28
|
+
slug: item.slug
|
|
29
|
+
}))
|
|
188
30
|
})
|
|
189
|
-
return
|
|
31
|
+
return data
|
|
190
32
|
}
|
|
191
33
|
|
|
34
|
+
const categoryData = buildCategoryData(categories)
|
|
192
35
|
|
|
193
|
-
|
|
194
|
-
const categoryData = buildCategoryData(categories, [])
|
|
195
|
-
|
|
196
|
-
export default {
|
|
36
|
+
const meta: Meta<typeof Glossary> = {
|
|
197
37
|
title: 'Organisms/Glossary',
|
|
198
|
-
component: Glossary
|
|
38
|
+
component: Glossary,
|
|
39
|
+
parameters: {
|
|
40
|
+
backgrounds: {
|
|
41
|
+
default: 'glossary-bg',
|
|
42
|
+
values: [{ name: 'glossary-bg', value: '#33052F' }]
|
|
43
|
+
}
|
|
44
|
+
}
|
|
199
45
|
}
|
|
46
|
+
export default meta
|
|
200
47
|
|
|
201
|
-
|
|
48
|
+
const Template = (args: any) => {
|
|
202
49
|
const [searchTerm, setSearchTerm] = useState('')
|
|
203
50
|
const [selectedCategory, setSelectedCategory] = useState<string | null>(null)
|
|
204
51
|
|
|
205
|
-
//
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
selectedCategory
|
|
211
|
-
)
|
|
52
|
+
// Filter items by searchTerm
|
|
53
|
+
const filterItems = (items: { title: string; slug: string }[]) =>
|
|
54
|
+
items.filter(item =>
|
|
55
|
+
item.title.toLowerCase().includes(searchTerm.toLowerCase())
|
|
56
|
+
)
|
|
212
57
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
searchTerm={searchTerm}
|
|
216
|
-
setSearchTerm={setSearchTerm}
|
|
217
|
-
selectedCategory={selectedCategory}
|
|
218
|
-
setSelectedCategory={setSelectedCategory}
|
|
219
|
-
categoryData={categoryData}
|
|
220
|
-
displayedCategories={displayedCategories}
|
|
221
|
-
placeholder="What are you looking for?"
|
|
222
|
-
/>
|
|
223
|
-
)
|
|
224
|
-
}
|
|
58
|
+
// Filter categoryData by selectedCategory and searchTerm
|
|
59
|
+
let filteredCategoryData: Partial<typeof categoryData> = {}
|
|
225
60
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
61
|
+
if (selectedCategory && categoryData[selectedCategory]) {
|
|
62
|
+
const filteredItems = filterItems(categoryData[selectedCategory as string])
|
|
63
|
+
if (filteredItems.length > 0) {
|
|
64
|
+
filteredCategoryData[selectedCategory] = filteredItems
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
Object.entries(categoryData).forEach(([cat, items]) => {
|
|
68
|
+
const filteredItems = filterItems(items)
|
|
69
|
+
if (filteredItems.length > 0) {
|
|
70
|
+
filteredCategoryData[cat] = filteredItems
|
|
71
|
+
}
|
|
72
|
+
})
|
|
230
73
|
}
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
export const NoResults = () => {
|
|
234
|
-
const [searchTerm, setSearchTerm] = useState('zzzz') // unlikely to match anything
|
|
235
|
-
const [selectedCategory, setSelectedCategory] = useState<string | null>(null)
|
|
236
|
-
|
|
237
|
-
const displayedCategories = getDisplayedCategories(
|
|
238
|
-
categories,
|
|
239
|
-
[],
|
|
240
|
-
searchTerm,
|
|
241
|
-
selectedCategory
|
|
242
|
-
)
|
|
243
74
|
|
|
244
75
|
return (
|
|
245
76
|
<Glossary
|
|
77
|
+
{...args}
|
|
246
78
|
searchTerm={searchTerm}
|
|
247
79
|
setSearchTerm={setSearchTerm}
|
|
248
80
|
selectedCategory={selectedCategory}
|
|
249
81
|
setSelectedCategory={setSelectedCategory}
|
|
250
|
-
categoryData={
|
|
251
|
-
displayedCategories={displayedCategories}
|
|
252
|
-
placeholder="What are you looking for?"
|
|
82
|
+
categoryData={filteredCategoryData}
|
|
253
83
|
/>
|
|
254
84
|
)
|
|
255
85
|
}
|
|
256
86
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
87
|
+
export const Default: StoryObj = {
|
|
88
|
+
render: Template,
|
|
89
|
+
args: {
|
|
90
|
+
placeholder: 'Search glossary...',
|
|
91
|
+
backToTopButton: 'Back to top',
|
|
92
|
+
noResultsText: 'No results found',
|
|
93
|
+
tryAnotherLetterText: 'Try another letter'
|
|
261
94
|
}
|
|
262
95
|
}
|
|
96
|
+
|