@syscore/ui-library 1.7.8 → 1.9.0
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/client/components/ui/accordion.tsx +501 -45
- package/client/components/ui/label.tsx +1 -1
- package/client/components/ui/tag.tsx +41 -14
- package/client/components/ui/toggle.tsx +16 -24
- package/client/global.css +31 -5
- package/client/lib/utils.ts +6 -0
- package/client/ui/Accordion.stories.tsx +430 -0
- package/client/ui/PageHeader.stories.tsx +6 -4
- package/client/ui/Panel.stories.tsx +513 -436
- package/client/ui/Tag.stories.tsx +153 -46
- package/dist/index.cjs.js +1 -1
- package/dist/index.d.ts +30 -30
- package/dist/index.es.js +415 -466
- package/package.json +1 -1
- package/client/components/ui/code-badge.tsx +0 -22
- package/client/components/ui/standard-table.tsx +0 -554
- package/client/ui/Accordion/Accordion.stories.tsx +0 -74
- package/client/ui/CodeBadge.stories.tsx +0 -76
- package/client/ui/StandardTable.stories.tsx +0 -311
|
@@ -3,26 +3,23 @@ import { cva, type VariantProps } from "class-variance-authority";
|
|
|
3
3
|
import { cn } from "../../lib/utils";
|
|
4
4
|
import { useSegmentedControl } from "../../hooks/use-segmented-control";
|
|
5
5
|
|
|
6
|
-
const toggleVariants = cva(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
default: "toggle--default",
|
|
12
|
-
outline: "toggle--outline",
|
|
13
|
-
},
|
|
14
|
-
size: {
|
|
15
|
-
default: "toggle--size-default",
|
|
16
|
-
sm: "toggle--size-sm",
|
|
17
|
-
lg: "toggle--size-lg",
|
|
18
|
-
},
|
|
6
|
+
const toggleVariants = cva("toggle", {
|
|
7
|
+
variants: {
|
|
8
|
+
variant: {
|
|
9
|
+
default: "toggle--default",
|
|
10
|
+
outline: "toggle--outline",
|
|
19
11
|
},
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
12
|
+
size: {
|
|
13
|
+
default: "toggle--size-default",
|
|
14
|
+
sm: "toggle--size-sm",
|
|
15
|
+
lg: "toggle--size-lg",
|
|
23
16
|
},
|
|
24
17
|
},
|
|
25
|
-
|
|
18
|
+
defaultVariants: {
|
|
19
|
+
variant: "default",
|
|
20
|
+
size: "default",
|
|
21
|
+
},
|
|
22
|
+
});
|
|
26
23
|
|
|
27
24
|
// Segmented Control Component
|
|
28
25
|
export interface SegmentedControlProps<T extends string = string>
|
|
@@ -51,14 +48,13 @@ const SegmentedControlInner = React.forwardRef<
|
|
|
51
48
|
return (
|
|
52
49
|
<div ref={ref} className={cn("segmented-control", className)} {...props}>
|
|
53
50
|
{options.map((option) => {
|
|
54
|
-
const isReactElement = React.isValidElement(option.label);
|
|
55
51
|
const isActive = selectedValue === option.value;
|
|
56
52
|
|
|
57
53
|
return (
|
|
58
54
|
<button
|
|
59
55
|
key={option.value}
|
|
60
56
|
className={cn(
|
|
61
|
-
"segmented-control-button",
|
|
57
|
+
"segmented-control-button body-small",
|
|
62
58
|
isActive
|
|
63
59
|
? "segmented-control-button--active"
|
|
64
60
|
: "segmented-control-button--inactive",
|
|
@@ -67,11 +63,7 @@ const SegmentedControlInner = React.forwardRef<
|
|
|
67
63
|
type="button"
|
|
68
64
|
data-active={isActive}
|
|
69
65
|
>
|
|
70
|
-
{
|
|
71
|
-
option.label
|
|
72
|
-
) : (
|
|
73
|
-
<span className="body-small font-medium">{option.label}</span>
|
|
74
|
-
)}
|
|
66
|
+
{option.label}
|
|
75
67
|
</button>
|
|
76
68
|
);
|
|
77
69
|
})}
|
package/client/global.css
CHANGED
|
@@ -1763,6 +1763,7 @@ body {
|
|
|
1763
1763
|
.tag-general--active {
|
|
1764
1764
|
background-color: var(--color-cyan-800, #0f748a);
|
|
1765
1765
|
color: var(--color-white, #fff);
|
|
1766
|
+
font-weight: 600;
|
|
1766
1767
|
}
|
|
1767
1768
|
|
|
1768
1769
|
.tag-general--active:hover {
|
|
@@ -1772,11 +1773,39 @@ body {
|
|
|
1772
1773
|
.tag-general--inactive {
|
|
1773
1774
|
background-color: var(--color-blue-100, #eff5fb);
|
|
1774
1775
|
color: var(--color-blue-700, #286495);
|
|
1776
|
+
font-weight: 500;
|
|
1775
1777
|
}
|
|
1776
1778
|
|
|
1777
1779
|
.tag-general--inactive:hover {
|
|
1778
|
-
background-color: var(--color-
|
|
1779
|
-
|
|
1780
|
+
background-color: var(--color-blue-200, #cbe0f1);
|
|
1781
|
+
}
|
|
1782
|
+
|
|
1783
|
+
/* Tag Code Variant - for code badges like "C1", "A3" */
|
|
1784
|
+
.tag-code {
|
|
1785
|
+
display: flex;
|
|
1786
|
+
align-items: center;
|
|
1787
|
+
justify-content: center;
|
|
1788
|
+
height: 2rem;
|
|
1789
|
+
width: 3rem;
|
|
1790
|
+
border-radius: calc(var(--radius-sm, 6px));
|
|
1791
|
+
flex-shrink: 0;
|
|
1792
|
+
border: 1.5px solid currentColor;
|
|
1793
|
+
padding-left: 1px;
|
|
1794
|
+
padding-right: 1px;
|
|
1795
|
+
background: transparent;
|
|
1796
|
+
cursor: pointer;
|
|
1797
|
+
}
|
|
1798
|
+
|
|
1799
|
+
.tag-code:focus-visible {
|
|
1800
|
+
outline: none;
|
|
1801
|
+
box-shadow:
|
|
1802
|
+
0 0 0 2px hsl(var(--ring)),
|
|
1803
|
+
0 0 0 4px var(--color-white, #fff);
|
|
1804
|
+
}
|
|
1805
|
+
|
|
1806
|
+
.tag-code:disabled {
|
|
1807
|
+
opacity: 0.5;
|
|
1808
|
+
cursor: not-allowed;
|
|
1780
1809
|
}
|
|
1781
1810
|
|
|
1782
1811
|
/* Toggle/Segmented Control Styles */
|
|
@@ -6625,7 +6654,6 @@ body {
|
|
|
6625
6654
|
.body-large {
|
|
6626
6655
|
font-size: 18px;
|
|
6627
6656
|
font-style: normal;
|
|
6628
|
-
font-weight: 400;
|
|
6629
6657
|
line-height: 25.2px;
|
|
6630
6658
|
}
|
|
6631
6659
|
|
|
@@ -6644,7 +6672,6 @@ body {
|
|
|
6644
6672
|
.body-base {
|
|
6645
6673
|
font-size: 16px;
|
|
6646
6674
|
font-style: normal;
|
|
6647
|
-
font-weight: 400;
|
|
6648
6675
|
line-height: 22.4px;
|
|
6649
6676
|
}
|
|
6650
6677
|
|
|
@@ -6663,7 +6690,6 @@ body {
|
|
|
6663
6690
|
.body-small {
|
|
6664
6691
|
font-size: 14px;
|
|
6665
6692
|
font-style: normal;
|
|
6666
|
-
font-weight: 400;
|
|
6667
6693
|
line-height: 19.6px;
|
|
6668
6694
|
}
|
|
6669
6695
|
|
package/client/lib/utils.ts
CHANGED
|
@@ -4,3 +4,9 @@ import { twMerge } from "tailwind-merge";
|
|
|
4
4
|
export function cn(...inputs: ClassValue[]) {
|
|
5
5
|
return twMerge(clsx(inputs));
|
|
6
6
|
}
|
|
7
|
+
|
|
8
|
+
/** Capitalize the first letter of a string */
|
|
9
|
+
export function capitalize(str: string): string {
|
|
10
|
+
if (!str) return str;
|
|
11
|
+
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
|
|
12
|
+
}
|
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import {
|
|
3
|
+
Accordion,
|
|
4
|
+
AccordionItem,
|
|
5
|
+
AccordionContent,
|
|
6
|
+
AccordionContainer,
|
|
7
|
+
AccordionSectionHeader,
|
|
8
|
+
AccordionHeader,
|
|
9
|
+
AccordionTrigger,
|
|
10
|
+
AccordionListRow,
|
|
11
|
+
} from "@/components/ui/accordion";
|
|
12
|
+
import { Tag } from "@/components/ui/tag";
|
|
13
|
+
import { useState } from "react";
|
|
14
|
+
import { concepts } from "@/lib/concepts-mock-data";
|
|
15
|
+
import { getConceptColor } from "@/lib/concept-colors";
|
|
16
|
+
import { CONCEPT_ICONS } from "@/lib/concept-icons";
|
|
17
|
+
import { Text } from "@/components/ui/typography";
|
|
18
|
+
|
|
19
|
+
const meta = {
|
|
20
|
+
title: "Review/Accordion",
|
|
21
|
+
component: Accordion,
|
|
22
|
+
tags: ["autodocs"],
|
|
23
|
+
parameters: {
|
|
24
|
+
layout: "fullscreen",
|
|
25
|
+
},
|
|
26
|
+
} satisfies Meta<typeof Accordion>;
|
|
27
|
+
|
|
28
|
+
export default meta;
|
|
29
|
+
|
|
30
|
+
type Story = StoryObj<typeof meta>;
|
|
31
|
+
|
|
32
|
+
// Generic unstyled example
|
|
33
|
+
export const Default: Story = {
|
|
34
|
+
render: () => {
|
|
35
|
+
const [expanded, setExpanded] = useState<Set<string>>(new Set());
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<div className="p-8 max-w-2xl">
|
|
39
|
+
<Accordion
|
|
40
|
+
allowMultiple={false}
|
|
41
|
+
expandedValues={expanded}
|
|
42
|
+
onExpandedChange={setExpanded}
|
|
43
|
+
className="border rounded-lg overflow-hidden"
|
|
44
|
+
>
|
|
45
|
+
<AccordionItem value="item-1" className="border-b last:border-b-0">
|
|
46
|
+
<AccordionHeader className="flex items-center justify-between p-4 cursor-pointer hover:bg-gray-50">
|
|
47
|
+
<span className="font-medium">Is it accessible?</span>
|
|
48
|
+
<AccordionTrigger />
|
|
49
|
+
</AccordionHeader>
|
|
50
|
+
<AccordionContent className="overflow-hidden">
|
|
51
|
+
<div className="p-4 pt-0">
|
|
52
|
+
Yes. It adheres to the WAI-ARIA design pattern and includes
|
|
53
|
+
smooth animations powered by Motion.
|
|
54
|
+
</div>
|
|
55
|
+
</AccordionContent>
|
|
56
|
+
</AccordionItem>
|
|
57
|
+
|
|
58
|
+
<AccordionItem value="item-2" className="border-b last:border-b-0">
|
|
59
|
+
<AccordionHeader className="flex items-center justify-between p-4 cursor-pointer hover:bg-gray-50">
|
|
60
|
+
<span className="font-medium">Is it animated?</span>
|
|
61
|
+
<AccordionTrigger />
|
|
62
|
+
</AccordionHeader>
|
|
63
|
+
<AccordionContent className="overflow-hidden">
|
|
64
|
+
<div className="p-4 pt-0">
|
|
65
|
+
Yes. It uses Motion/React for smooth height and opacity
|
|
66
|
+
animations.
|
|
67
|
+
</div>
|
|
68
|
+
</AccordionContent>
|
|
69
|
+
</AccordionItem>
|
|
70
|
+
|
|
71
|
+
<AccordionItem value="item-3" className="border-b last:border-b-0">
|
|
72
|
+
<AccordionHeader className="flex items-center justify-between p-4 cursor-pointer hover:bg-gray-50">
|
|
73
|
+
<span className="font-medium">Can multiple items be open?</span>
|
|
74
|
+
<AccordionTrigger />
|
|
75
|
+
</AccordionHeader>
|
|
76
|
+
<AccordionContent className="overflow-hidden">
|
|
77
|
+
<div className="p-4 pt-0">
|
|
78
|
+
Yes. Set <code>allowMultiple=true</code> to allow multiple items
|
|
79
|
+
to be expanded at once.
|
|
80
|
+
</div>
|
|
81
|
+
</AccordionContent>
|
|
82
|
+
</AccordionItem>
|
|
83
|
+
</Accordion>
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// Multiple selection example
|
|
90
|
+
export const MultipleSelection: Story = {
|
|
91
|
+
render: () => {
|
|
92
|
+
const [expanded, setExpanded] = useState<Set<string>>(new Set());
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<div className="p-8 max-w-2xl">
|
|
96
|
+
<Accordion
|
|
97
|
+
allowMultiple={true}
|
|
98
|
+
expandedValues={expanded}
|
|
99
|
+
onExpandedChange={setExpanded}
|
|
100
|
+
className="border rounded-lg overflow-hidden"
|
|
101
|
+
>
|
|
102
|
+
<AccordionItem value="item-1" className="border-b last:border-b-0">
|
|
103
|
+
<AccordionHeader className="flex items-center justify-between p-4 cursor-pointer hover:bg-gray-50">
|
|
104
|
+
<span className="font-medium">Section One</span>
|
|
105
|
+
<AccordionTrigger />
|
|
106
|
+
</AccordionHeader>
|
|
107
|
+
<AccordionContent className="overflow-hidden">
|
|
108
|
+
<div className="p-4 pt-0">
|
|
109
|
+
Content for section one. Multiple sections can be open
|
|
110
|
+
simultaneously.
|
|
111
|
+
</div>
|
|
112
|
+
</AccordionContent>
|
|
113
|
+
</AccordionItem>
|
|
114
|
+
|
|
115
|
+
<AccordionItem value="item-2" className="border-b last:border-b-0">
|
|
116
|
+
<AccordionHeader className="flex items-center justify-between p-4 cursor-pointer hover:bg-gray-50">
|
|
117
|
+
<span className="font-medium">Section Two</span>
|
|
118
|
+
<AccordionTrigger />
|
|
119
|
+
</AccordionHeader>
|
|
120
|
+
<AccordionContent className="overflow-hidden">
|
|
121
|
+
<div className="p-4 pt-0">
|
|
122
|
+
Content for section two. Try opening multiple sections at once.
|
|
123
|
+
</div>
|
|
124
|
+
</AccordionContent>
|
|
125
|
+
</AccordionItem>
|
|
126
|
+
|
|
127
|
+
<AccordionItem value="item-3" className="border-b last:border-b-0">
|
|
128
|
+
<AccordionHeader className="flex items-center justify-between p-4 cursor-pointer hover:bg-gray-50">
|
|
129
|
+
<span className="font-medium">Section Three</span>
|
|
130
|
+
<AccordionTrigger />
|
|
131
|
+
</AccordionHeader>
|
|
132
|
+
<AccordionContent className="overflow-hidden">
|
|
133
|
+
<div className="p-4 pt-0">
|
|
134
|
+
Content for section three. All three can be expanded together.
|
|
135
|
+
</div>
|
|
136
|
+
</AccordionContent>
|
|
137
|
+
</AccordionItem>
|
|
138
|
+
</Accordion>
|
|
139
|
+
</div>
|
|
140
|
+
);
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// IWBI Standard Table styled variant
|
|
145
|
+
export const IWBIConceptsTable: Story = {
|
|
146
|
+
render: () => {
|
|
147
|
+
const [expandedConcepts, setExpandedConcepts] = useState<Set<string>>(
|
|
148
|
+
new Set(),
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
const hasAnyExpanded = expandedConcepts.size > 0;
|
|
152
|
+
|
|
153
|
+
const toggleAllConcepts = () => {
|
|
154
|
+
if (hasAnyExpanded) {
|
|
155
|
+
setExpandedConcepts(new Set());
|
|
156
|
+
} else {
|
|
157
|
+
setExpandedConcepts(new Set(concepts.map((c) => c.id)));
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const navigateTo = (path: string) => {
|
|
162
|
+
console.log(path);
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
function getSlugFromName(name: string) {
|
|
166
|
+
return name.toLowerCase().replace(/\s+/g, "-");
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return (
|
|
170
|
+
<AccordionContainer className="standard-table-container">
|
|
171
|
+
<AccordionSectionHeader
|
|
172
|
+
title="CONCEPTS"
|
|
173
|
+
hasExpanded={hasAnyExpanded}
|
|
174
|
+
onToggleAll={toggleAllConcepts}
|
|
175
|
+
className="standard-table-header"
|
|
176
|
+
/>
|
|
177
|
+
|
|
178
|
+
<Accordion
|
|
179
|
+
allowMultiple={true}
|
|
180
|
+
expandedValues={expandedConcepts}
|
|
181
|
+
onExpandedChange={setExpandedConcepts}
|
|
182
|
+
className="border border-blue-200 rounded-xl overflow-hidden"
|
|
183
|
+
>
|
|
184
|
+
{[...concepts].map((concept) => {
|
|
185
|
+
const slug = getSlugFromName(concept.name);
|
|
186
|
+
const Icon = CONCEPT_ICONS[slug];
|
|
187
|
+
const color = getConceptColor(slug);
|
|
188
|
+
|
|
189
|
+
return (
|
|
190
|
+
<AccordionItem
|
|
191
|
+
key={concept.id}
|
|
192
|
+
value={concept.id}
|
|
193
|
+
className="standard-table-row"
|
|
194
|
+
>
|
|
195
|
+
<AccordionHeader
|
|
196
|
+
onClick={() => navigateTo("/")}
|
|
197
|
+
className="standard-table-row-header"
|
|
198
|
+
>
|
|
199
|
+
<Icon active={true} className="size-12 shrink-0" />
|
|
200
|
+
<span className="overline-large flex-1">{concept.name}</span>
|
|
201
|
+
<AccordionTrigger className="standard-table-trigger" />
|
|
202
|
+
</AccordionHeader>
|
|
203
|
+
|
|
204
|
+
<AccordionContent className="standard-table-content">
|
|
205
|
+
<div className="standard-table-content__inner">
|
|
206
|
+
{concept.themes.map((theme) => (
|
|
207
|
+
<AccordionListRow
|
|
208
|
+
key={theme.id}
|
|
209
|
+
badge={
|
|
210
|
+
<Tag
|
|
211
|
+
variant="code"
|
|
212
|
+
style={{
|
|
213
|
+
backgroundColor: color.contrast || color.solid,
|
|
214
|
+
borderColor: color.border,
|
|
215
|
+
color: "white",
|
|
216
|
+
}}
|
|
217
|
+
>
|
|
218
|
+
{theme.code}
|
|
219
|
+
</Tag>
|
|
220
|
+
}
|
|
221
|
+
title={theme.name}
|
|
222
|
+
titleClassName="standard-table-list-row__title body-large"
|
|
223
|
+
className="standard-table-list-row standard-table-list-row--nested"
|
|
224
|
+
onClick={() => navigateTo("/")}
|
|
225
|
+
/>
|
|
226
|
+
))}
|
|
227
|
+
</div>
|
|
228
|
+
</AccordionContent>
|
|
229
|
+
</AccordionItem>
|
|
230
|
+
);
|
|
231
|
+
})}
|
|
232
|
+
</Accordion>
|
|
233
|
+
</AccordionContainer>
|
|
234
|
+
);
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
export const IWBIThemesTable: Story = {
|
|
239
|
+
render: () => {
|
|
240
|
+
const conceptSlug = "community";
|
|
241
|
+
|
|
242
|
+
const [expandedThemes, setExpandedThemes] = useState<Set<string>>(
|
|
243
|
+
new Set(),
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
const hasAnyExpanded = expandedThemes.size > 0;
|
|
247
|
+
|
|
248
|
+
const toggleAllThemes = () => {
|
|
249
|
+
if (hasAnyExpanded) {
|
|
250
|
+
setExpandedThemes(new Set());
|
|
251
|
+
} else {
|
|
252
|
+
setExpandedThemes(new Set(conceptData?.themes.map((t) => t.id) || []));
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
const navigateTo = (path: string) => {
|
|
257
|
+
console.log(path);
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
const conceptData = concepts.find(
|
|
261
|
+
(c) => c.name.toLowerCase() === conceptSlug.toLowerCase(),
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
const conceptColor = getConceptColor(conceptSlug);
|
|
265
|
+
|
|
266
|
+
return (
|
|
267
|
+
<AccordionContainer className="standard-table-container">
|
|
268
|
+
<AccordionSectionHeader
|
|
269
|
+
title="THEMES"
|
|
270
|
+
hasExpanded={hasAnyExpanded}
|
|
271
|
+
onToggleAll={toggleAllThemes}
|
|
272
|
+
className="standard-table-header"
|
|
273
|
+
/>
|
|
274
|
+
|
|
275
|
+
<Accordion
|
|
276
|
+
allowMultiple={true}
|
|
277
|
+
expandedValues={expandedThemes}
|
|
278
|
+
onExpandedChange={setExpandedThemes}
|
|
279
|
+
className="border border-blue-200 rounded-xl overflow-hidden"
|
|
280
|
+
>
|
|
281
|
+
{conceptData?.themes.map((theme) => {
|
|
282
|
+
return (
|
|
283
|
+
<AccordionItem
|
|
284
|
+
key={theme.id}
|
|
285
|
+
value={theme.id}
|
|
286
|
+
className="standard-table-row"
|
|
287
|
+
>
|
|
288
|
+
<AccordionHeader
|
|
289
|
+
onClick={() => navigateTo("/")}
|
|
290
|
+
className="standard-table-row-header"
|
|
291
|
+
>
|
|
292
|
+
<Tag
|
|
293
|
+
variant="code"
|
|
294
|
+
style={{
|
|
295
|
+
backgroundColor:
|
|
296
|
+
conceptColor.contrast || conceptColor.solid,
|
|
297
|
+
borderColor: conceptColor.border,
|
|
298
|
+
color: "white",
|
|
299
|
+
}}
|
|
300
|
+
>
|
|
301
|
+
{theme.code}
|
|
302
|
+
</Tag>
|
|
303
|
+
<Text as="p" variant="body-large" className="flex-1">
|
|
304
|
+
{theme.name}
|
|
305
|
+
</Text>
|
|
306
|
+
<AccordionTrigger className="standard-table-trigger" />
|
|
307
|
+
</AccordionHeader>
|
|
308
|
+
|
|
309
|
+
<AccordionContent className="standard-table-content">
|
|
310
|
+
<div className="standard-table-content__inner">
|
|
311
|
+
{theme.strategies.map((strategy) => (
|
|
312
|
+
<AccordionListRow
|
|
313
|
+
key={strategy.id}
|
|
314
|
+
badge={
|
|
315
|
+
<Tag
|
|
316
|
+
variant="code"
|
|
317
|
+
style={{
|
|
318
|
+
backgroundColor: conceptColor.light,
|
|
319
|
+
borderColor: conceptColor.border,
|
|
320
|
+
color:
|
|
321
|
+
conceptColor.contrast || conceptColor.solid,
|
|
322
|
+
}}
|
|
323
|
+
>
|
|
324
|
+
{strategy.code}
|
|
325
|
+
</Tag>
|
|
326
|
+
}
|
|
327
|
+
title={strategy.name}
|
|
328
|
+
titleClassName="standard-table-list-row__title body-large"
|
|
329
|
+
className="standard-table-list-row standard-table-list-row--nested"
|
|
330
|
+
onClick={() => navigateTo("/")}
|
|
331
|
+
rightContent={
|
|
332
|
+
<span className="flex justify-center items-center number-large font-semibold">
|
|
333
|
+
{strategy.points}{" "}
|
|
334
|
+
<span className="overline-medium ml-1">
|
|
335
|
+
PT
|
|
336
|
+
<span
|
|
337
|
+
className={
|
|
338
|
+
strategy.points === "1"
|
|
339
|
+
? "opacity-0"
|
|
340
|
+
: "opacity-100"
|
|
341
|
+
}
|
|
342
|
+
>
|
|
343
|
+
S
|
|
344
|
+
</span>
|
|
345
|
+
</span>
|
|
346
|
+
</span>
|
|
347
|
+
}
|
|
348
|
+
/>
|
|
349
|
+
))}
|
|
350
|
+
</div>
|
|
351
|
+
</AccordionContent>
|
|
352
|
+
</AccordionItem>
|
|
353
|
+
);
|
|
354
|
+
})}
|
|
355
|
+
</Accordion>
|
|
356
|
+
</AccordionContainer>
|
|
357
|
+
);
|
|
358
|
+
},
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
export const IWBIStrategiesTable: Story = {
|
|
362
|
+
render: () => {
|
|
363
|
+
const conceptSlug = "community";
|
|
364
|
+
const themeCode = "C8";
|
|
365
|
+
|
|
366
|
+
const navigateTo = (path: string) => {
|
|
367
|
+
console.log(path);
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
const conceptData = concepts.find(
|
|
371
|
+
(c) => c.name.toLowerCase() === conceptSlug.toLowerCase(),
|
|
372
|
+
);
|
|
373
|
+
const themeData = conceptData?.themes.find((t) => t.code === themeCode);
|
|
374
|
+
|
|
375
|
+
const conceptColor = getConceptColor(conceptSlug);
|
|
376
|
+
|
|
377
|
+
return (
|
|
378
|
+
<AccordionContainer className="standard-table-container">
|
|
379
|
+
<AccordionSectionHeader
|
|
380
|
+
title="STRATEGIES"
|
|
381
|
+
className="standard-table-header"
|
|
382
|
+
/>
|
|
383
|
+
|
|
384
|
+
<Accordion className="border border-blue-200 rounded-xl overflow-hidden">
|
|
385
|
+
{themeData?.strategies.map((strategy) => {
|
|
386
|
+
return (
|
|
387
|
+
<AccordionItem
|
|
388
|
+
key={strategy.id}
|
|
389
|
+
value={strategy.id}
|
|
390
|
+
className="standard-table-row"
|
|
391
|
+
>
|
|
392
|
+
<AccordionHeader
|
|
393
|
+
onClick={() => navigateTo("/")}
|
|
394
|
+
className="standard-table-row-header"
|
|
395
|
+
>
|
|
396
|
+
<Tag
|
|
397
|
+
variant="code"
|
|
398
|
+
style={{
|
|
399
|
+
backgroundColor: conceptColor.light,
|
|
400
|
+
borderColor: conceptColor.border,
|
|
401
|
+
color: conceptColor.contrast || conceptColor.solid,
|
|
402
|
+
}}
|
|
403
|
+
>
|
|
404
|
+
{strategy.code}
|
|
405
|
+
</Tag>
|
|
406
|
+
<Text as="p" variant="body-large" className="flex-1">
|
|
407
|
+
{strategy.name}
|
|
408
|
+
</Text>
|
|
409
|
+
<span className="flex justify-center items-center number-large font-semibold">
|
|
410
|
+
{strategy.points}{" "}
|
|
411
|
+
<span className="overline-medium ml-1">
|
|
412
|
+
PT
|
|
413
|
+
<span
|
|
414
|
+
className={
|
|
415
|
+
strategy.points === "1" ? "opacity-0" : "opacity-100"
|
|
416
|
+
}
|
|
417
|
+
>
|
|
418
|
+
S
|
|
419
|
+
</span>
|
|
420
|
+
</span>
|
|
421
|
+
</span>
|
|
422
|
+
</AccordionHeader>
|
|
423
|
+
</AccordionItem>
|
|
424
|
+
);
|
|
425
|
+
})}
|
|
426
|
+
</Accordion>
|
|
427
|
+
</AccordionContainer>
|
|
428
|
+
);
|
|
429
|
+
},
|
|
430
|
+
};
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
PageHeaderDescription,
|
|
9
9
|
} from "../components/ui/page-header";
|
|
10
10
|
import { BadgeCertificationBronze } from "../components/icons/AchievementBadges";
|
|
11
|
-
import {
|
|
11
|
+
import { Tag } from "../components/ui/tag";
|
|
12
12
|
import {
|
|
13
13
|
Tooltip,
|
|
14
14
|
TooltipTrigger,
|
|
@@ -96,14 +96,16 @@ export const ThemeHeader: Story = {
|
|
|
96
96
|
<PageHeader>
|
|
97
97
|
<PageHeaderTopSection className="mb-4">
|
|
98
98
|
<PageHeaderLeftContent>
|
|
99
|
-
<
|
|
100
|
-
code
|
|
99
|
+
<Tag
|
|
100
|
+
variant="code"
|
|
101
101
|
style={{
|
|
102
102
|
backgroundColor: conceptColor.contrast || conceptColor.solid,
|
|
103
103
|
borderColor: conceptColor.border,
|
|
104
104
|
color: "white",
|
|
105
105
|
}}
|
|
106
|
-
|
|
106
|
+
>
|
|
107
|
+
{themeCode}
|
|
108
|
+
</Tag>
|
|
107
109
|
<Tooltip trigger="click">
|
|
108
110
|
<TooltipTrigger>
|
|
109
111
|
<span className="body-base text-gray-600 underline-dotted cursor-pointer">
|