@syscore/ui-library 1.3.7 → 1.4.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.
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Centralized concept icon mapping
3
+ *
4
+ * Maps concept slugs to their icon components.
5
+ * Used when fetching concept data from API - the API returns string IDs,
6
+ * and this map resolves them to actual React components.
7
+ */
8
+
9
+ import {
10
+ IconConceptMind,
11
+ IconConceptCommunity,
12
+ IconConceptMovement,
13
+ IconConceptWater,
14
+ IconConceptAir,
15
+ IconConceptLight,
16
+ IconConceptThermalComfort,
17
+ IconConceptNourishment,
18
+ IconConceptSound,
19
+ IconConceptMaterials,
20
+ IconConceptInnovation,
21
+ } from "@/components/icons/ConceptIcons";
22
+ import { type ConceptSlug } from "@/lib/mock-data/explore-data";
23
+
24
+ export interface ConceptIconProps {
25
+ className?: string;
26
+ active?: boolean;
27
+ outlined?: boolean;
28
+ }
29
+
30
+ export const CONCEPT_ICONS: Record<
31
+ ConceptSlug,
32
+ React.ComponentType<ConceptIconProps>
33
+ > = {
34
+ air: IconConceptAir,
35
+ water: IconConceptWater,
36
+ nourishment: IconConceptNourishment,
37
+ light: IconConceptLight,
38
+ movement: IconConceptMovement,
39
+ "thermal-comfort": IconConceptThermalComfort,
40
+ sound: IconConceptSound,
41
+ materials: IconConceptMaterials,
42
+ community: IconConceptCommunity,
43
+ mind: IconConceptMind,
44
+ innovation: IconConceptInnovation,
45
+ };
@@ -210,103 +210,6 @@ export const FiltersPanel: Story = {
210
210
  // },
211
211
  // };
212
212
 
213
-
214
- export const NavigatorPanel: Story = {
215
- render: () => {
216
- const [activeConcept, setActiveConcept] = useState<string>("community");
217
- const [activeTheme, setActiveTheme] = useState<string>("C7");
218
- const [activeStrategy, setActiveStrategy] = useState<string>("C7.4");
219
-
220
- const concepts = [
221
- { id: "mind", Icon: IconConceptMind },
222
- { id: "community", Icon: IconConceptCommunity },
223
- { id: "movement", Icon: IconConceptMovement },
224
- { id: "water", Icon: IconConceptWater },
225
- { id: "air", Icon: IconConceptAir },
226
- { id: "light", Icon: IconConceptLight },
227
- { id: "thermal", Icon: IconConceptThermalComfort },
228
- { id: "nourishment", Icon: IconConceptNourishment },
229
- { id: "sound", Icon: IconConceptSound },
230
- { id: "materials", Icon: IconConceptMaterials },
231
- ];
232
-
233
- const themes = Array.from({ length: 9 }, (_, i) => `C${9 - i}`).reverse();
234
- const strategies = ["C7.1", "C7.2", "C7.3", "C7.4"];
235
-
236
- return (
237
- <Card className="w-[344px] bg-cyan-50 border-gray-100 rounded-xl p-6 shadow-none flex flex-col gap-6">
238
- {/* Concepts */}
239
- <div className="flex flex-col gap-3">
240
- <Label className="text-gray-600">Concept</Label>
241
- <div className="flex flex-wrap gap-2">
242
- {concepts.map(({ id, Icon }) => (
243
- <button
244
- key={id}
245
- onClick={() => setActiveConcept(id)}
246
- className="rounded-full transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:ring-offset-2"
247
- >
248
- <Icon active={activeConcept === id} className="size-12" />
249
- </button>
250
- ))}
251
- </div>
252
- </div>
253
-
254
- {/* Theme */}
255
- <div className="flex flex-col gap-3">
256
- <Label className="text-gray-600">Theme</Label>
257
- <div className="flex flex-wrap gap-2">
258
- {themes.map((theme) => (
259
- <button
260
- key={theme}
261
- onClick={() => setActiveTheme(theme)}
262
- className={`w-12 h-8 rounded-[6px] flex items-center justify-center transition-colors ${activeTheme === theme
263
- ? "bg-cyan-800 text-white"
264
- : "bg-blue-100 text-blue-600 hover:bg-blue-200"
265
- }`}
266
- >
267
- <span className="body-small font-semibold">{theme}</span>
268
- </button>
269
- ))}
270
- </div>
271
- </div>
272
-
273
- {/* Strategy */}
274
- <div className="flex flex-col gap-3">
275
- <Label className="text-gray-600">Strategy</Label>
276
- <div className="flex flex-wrap gap-2">
277
- {strategies.map((strategy) => (
278
- <button
279
- key={strategy}
280
- onClick={() => setActiveStrategy(strategy)}
281
- className={`w-12 h-8 rounded-[6px] flex items-center justify-center transition-colors ${activeStrategy === strategy
282
- ? "bg-[#0F748A]/10 border border-[#0F748A]/20 text-cyan-900"
283
- : "bg-blue-100 text-blue-600 hover:bg-blue-200"
284
- }`}
285
- >
286
- <span className="body-small font-semibold">{strategy}</span>
287
- </button>
288
- ))}
289
- </div>
290
- </div>
291
-
292
- {/* Scope */}
293
- <div className="flex flex-col gap-3">
294
- <Label className="text-gray-600">Scope</Label>
295
- <Toggle
296
- className="w-full h-8 border border-gray-100 bg-white rounded-full p-0 [&>button]:flex-1"
297
- options={[
298
- { label: "Non-core", value: "non-core" },
299
- { label: "Core", value: "core" },
300
- ]}
301
- defaultValue="non-core"
302
- />
303
- </div>
304
- </Card>
305
- );
306
- },
307
- };
308
-
309
-
310
213
  export const ConceptCard: Story = {
311
214
  parameters: {
312
215
  docs: {
@@ -431,4 +334,5 @@ export const ConceptCard: Story = {
431
334
  </div>
432
335
  );
433
336
  },
434
- };
337
+ };
338
+
@@ -0,0 +1,72 @@
1
+
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+ import { Button } from "../components/ui/button";
4
+ import { HeroSection } from "../components/ui/hero-section";
5
+ import { motion } from "motion/react";
6
+
7
+ const meta = {
8
+ title: "Review/Hero",
9
+ component: HeroSection,
10
+ tags: ["autodocs"],
11
+ parameters: {
12
+ layout: "fullscreen",
13
+ },
14
+ } satisfies Meta<typeof HeroSection>;
15
+
16
+ export default meta;
17
+
18
+ type Story = StoryObj<typeof meta>;
19
+
20
+ export const Default: Story = {
21
+ render: () => (
22
+ <HeroSection backgroundSlot={
23
+ <motion.div
24
+ className="absolute bottom-0 flex items-center justify-center max-w-[1303px] mx-auto hidden sm:block"
25
+ initial={{ opacity: 0, scale: 1 }}
26
+ animate={{ opacity: 1, scale: 1.05 }}
27
+ transition={{ duration: 1, ease: [0.25, 0.46, 0.45, 0.94] }}
28
+ style={{ willChange: "transform, opacity" }}
29
+ >
30
+ <motion.div
31
+ animate={{
32
+ y: [0, -15, 0],
33
+ scale: [1, 1.02, 1],
34
+ }}
35
+ transition={{
36
+ duration: 8,
37
+ ease: "easeInOut",
38
+ repeat: Infinity,
39
+ repeatType: "loop",
40
+ }}
41
+ style={{ willChange: "transform" }}
42
+ >
43
+ <img
44
+ src="/img/half-sphere.png"
45
+ alt="WELL Standard Sphere"
46
+ width={900}
47
+ height={900}
48
+ className="w-auto object-bottom object-contain select-none pointer-events-none "
49
+ />
50
+ </motion.div>
51
+ </motion.div>
52
+ } contentSlot={
53
+ <motion.div
54
+ className="flex flex-wrap justify-center gap-4"
55
+ initial={{ opacity: 0, y: 20 }}
56
+ animate={{ opacity: 1, y: 0 }}
57
+ transition={{ duration: 0.6, delay: 0.5 }}
58
+ >
59
+ <Button variant="secondary-light" size="xlarge" className="shadow-2xl ">
60
+ Explore the standard
61
+ </Button>
62
+ <Button
63
+ size="xlarge"
64
+ variant="clear"
65
+ className="shadow-2xl bg-none bg-[#282A3133] px-15 text-white hover:bg-[#282a3166] "
66
+ >
67
+ See what&apos;s new
68
+ </Button>
69
+ </motion.div>} />
70
+ ),
71
+ };
72
+
@@ -23,35 +23,44 @@ const navItems = [
23
23
  ];
24
24
 
25
25
  export const Default: Story = {
26
- render: () => (
27
- <div className="h-screen bg-[linear-gradient(var(--gradient-0))]">
26
+ args: {
27
+ isStrategy: false,
28
+ onLinkClick: (href) => console.log("Clicked:", href),
29
+ pathname: "/",
30
+ },
31
+ render: (args) => (
32
+ <div className="h-screen bg-cyan-900">
28
33
  <Navigation
29
- navItems={navItems}
30
- isStrategy={false}
31
- onLinkClick={(href) => console.log("Clicked:", href)}
34
+ {...args}
32
35
  />
33
- <div className="pt-20 p-8">
34
- <p className="text-gray-600">
35
- Navigation component is fixed at the top.
36
- </p>
37
- <p className="text-gray-600">Hover over menu items to see dropdowns.</p>
38
- </div>
36
+
37
+ </div>
38
+ ),
39
+ };
40
+
41
+ export const WithNavItems: Story = {
42
+ args: {
43
+ navItems: navItems,
44
+ isStrategy: false,
45
+ onLinkClick: (href) => console.log("Clicked:", href),
46
+ pathname: "/",
47
+ },
48
+ render: (args) => (
49
+ <div className="h-screen bg-cyan-900">
50
+ <Navigation {...args} />
39
51
  </div>
40
52
  ),
41
53
  };
42
54
 
43
55
  export const StrategyMode: Story = {
44
- render: () => (
56
+ args: {
57
+ isStrategy: true,
58
+ onLinkClick: (href) => console.log("Clicked:", href),
59
+ pathname: "/strategy",
60
+ },
61
+ render: (args) => (
45
62
  <div className="h-screen bg-white">
46
- <Navigation
47
- navItems={navItems}
48
- isStrategy={true}
49
- onLinkClick={(href) => console.log("Clicked:", href)}
50
- />
51
-
52
- <div className="pt-20 p-8">
53
- <p className="text-gray-600">Strategy mode navigation.</p>
54
- </div>
63
+ <Navigation {...args} />
55
64
  </div>
56
65
  ),
57
66
  };