@syscore/ui-library 1.2.2 → 1.3.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/icons/ConceptIcons.tsx +27 -23
- package/client/components/ui/tag.tsx +1 -1
- package/client/components/ui/typography.tsx +116 -0
- package/client/global.css +22 -3
- package/client/ui/Card.stories.tsx +143 -25
- package/client/ui/Typography.stories.tsx +148 -307
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +1 -1
- package/package.json +1 -1
|
@@ -84,6 +84,9 @@ export const conceptColors = {
|
|
|
84
84
|
} as const;
|
|
85
85
|
|
|
86
86
|
|
|
87
|
+
const DEFAULT_FILL = "#EFF5FB";
|
|
88
|
+
const DEFAULT_STROKE = "#2E74AD";
|
|
89
|
+
|
|
87
90
|
interface ConceptIconProps {
|
|
88
91
|
className?: string;
|
|
89
92
|
active?: boolean;
|
|
@@ -99,8 +102,8 @@ export const IconConceptMind: React.FC<ConceptIconProps> = ({
|
|
|
99
102
|
outlined = false,
|
|
100
103
|
}) => {
|
|
101
104
|
const conceptColor = conceptColors.mind.solid;
|
|
102
|
-
const bgFill = outlined ? "white" : active ? conceptColor :
|
|
103
|
-
const strokeColor = outlined ? conceptColor : active ? "white" :
|
|
105
|
+
const bgFill = outlined ? "white" : active ? conceptColor : DEFAULT_FILL;
|
|
106
|
+
const strokeColor = outlined ? conceptColor : active ? "white" : DEFAULT_STROKE;
|
|
104
107
|
|
|
105
108
|
return (
|
|
106
109
|
<svg
|
|
@@ -196,8 +199,8 @@ export const IconConceptCommunity: React.FC<ConceptIconProps> = ({
|
|
|
196
199
|
outlined = false,
|
|
197
200
|
}) => {
|
|
198
201
|
const conceptColor = conceptColors.community.solid;
|
|
199
|
-
const bgFill = outlined ? "white" : active ? conceptColor :
|
|
200
|
-
const strokeColor = outlined ? conceptColor : active ? "white" :
|
|
202
|
+
const bgFill = outlined ? "white" : active ? conceptColor : DEFAULT_FILL;
|
|
203
|
+
const strokeColor = outlined ? conceptColor : active ? "white" : DEFAULT_STROKE;
|
|
201
204
|
|
|
202
205
|
return (
|
|
203
206
|
<svg
|
|
@@ -253,8 +256,8 @@ export const IconConceptMovement: React.FC<ConceptIconProps> = ({
|
|
|
253
256
|
outlined = false,
|
|
254
257
|
}) => {
|
|
255
258
|
const conceptColor = conceptColors.movement.solid;
|
|
256
|
-
const bgFill = outlined ? "white" : active ? conceptColor :
|
|
257
|
-
const strokeColor = outlined ? conceptColor : active ? "white" :
|
|
259
|
+
const bgFill = outlined ? "white" : active ? conceptColor : DEFAULT_FILL;
|
|
260
|
+
const strokeColor = outlined ? conceptColor : active ? "white" : DEFAULT_STROKE;
|
|
258
261
|
|
|
259
262
|
return (
|
|
260
263
|
<svg
|
|
@@ -286,8 +289,8 @@ export const IconConceptWater: React.FC<ConceptIconProps> = ({
|
|
|
286
289
|
outlined = false,
|
|
287
290
|
}) => {
|
|
288
291
|
const conceptColor = conceptColors.water.solid;
|
|
289
|
-
const bgFill = outlined ? "white" : active ? conceptColor :
|
|
290
|
-
const strokeColor = outlined ? conceptColor : active ? "white" :
|
|
292
|
+
const bgFill = outlined ? "white" : active ? conceptColor : DEFAULT_FILL;
|
|
293
|
+
const strokeColor = outlined ? conceptColor : active ? "white" : DEFAULT_STROKE;
|
|
291
294
|
|
|
292
295
|
return (
|
|
293
296
|
<svg
|
|
@@ -327,8 +330,8 @@ export const IconConceptAir: React.FC<ConceptIconProps> = ({
|
|
|
327
330
|
outlined = false,
|
|
328
331
|
}) => {
|
|
329
332
|
const conceptColor = conceptColors.air.contrast || conceptColors.air.solid;
|
|
330
|
-
const bgFill = outlined ? "white" : active ? conceptColor :
|
|
331
|
-
const strokeColor = outlined ? conceptColor : active ? "white" :
|
|
333
|
+
const bgFill = outlined ? "white" : active ? conceptColor : DEFAULT_FILL;
|
|
334
|
+
const strokeColor = outlined ? conceptColor : active ? "white" : DEFAULT_STROKE;
|
|
332
335
|
|
|
333
336
|
return (
|
|
334
337
|
<svg
|
|
@@ -376,8 +379,8 @@ export const IconConceptLight: React.FC<ConceptIconProps> = ({
|
|
|
376
379
|
outlined = false,
|
|
377
380
|
}) => {
|
|
378
381
|
const conceptColor = conceptColors.light.contrast || conceptColors.light.solid;
|
|
379
|
-
const bgFill = outlined ? "white" : active ? conceptColor :
|
|
380
|
-
const strokeColor = outlined ? conceptColor : active ? "white" :
|
|
382
|
+
const bgFill = outlined ? "white" : active ? conceptColor : DEFAULT_FILL;
|
|
383
|
+
const strokeColor = outlined ? conceptColor : active ? "white" : DEFAULT_STROKE;
|
|
381
384
|
|
|
382
385
|
return (
|
|
383
386
|
<svg
|
|
@@ -472,9 +475,10 @@ export const IconConceptThermalComfort: React.FC<ConceptIconProps> = ({
|
|
|
472
475
|
active = true,
|
|
473
476
|
outlined = false,
|
|
474
477
|
}) => {
|
|
475
|
-
const conceptColor =
|
|
476
|
-
|
|
477
|
-
const
|
|
478
|
+
const conceptColor =
|
|
479
|
+
conceptColors.thermalComfort?.contrast || conceptColors.thermalComfort.solid;
|
|
480
|
+
const bgFill = outlined ? "white" : active ? conceptColor : DEFAULT_FILL;
|
|
481
|
+
const strokeColor = outlined ? conceptColor : active ? "white" : DEFAULT_STROKE;
|
|
478
482
|
|
|
479
483
|
return (
|
|
480
484
|
<svg
|
|
@@ -586,8 +590,8 @@ export const IconConceptNourishment: React.FC<ConceptIconProps> = ({
|
|
|
586
590
|
outlined = false,
|
|
587
591
|
}) => {
|
|
588
592
|
const conceptColor = conceptColors.nourishment.solid;
|
|
589
|
-
const bgFill = outlined ? "white" : active ? conceptColor :
|
|
590
|
-
const strokeColor = outlined ? conceptColor : active ? "white" :
|
|
593
|
+
const bgFill = outlined ? "white" : active ? conceptColor : DEFAULT_FILL;
|
|
594
|
+
const strokeColor = outlined ? conceptColor : active ? "white" : DEFAULT_STROKE;
|
|
591
595
|
|
|
592
596
|
return (
|
|
593
597
|
<svg
|
|
@@ -643,8 +647,8 @@ export const IconConceptSound: React.FC<ConceptIconProps> = ({
|
|
|
643
647
|
outlined = false,
|
|
644
648
|
}) => {
|
|
645
649
|
const conceptColor = conceptColors.sound.solid;
|
|
646
|
-
const bgFill = outlined ? "white" : active ? conceptColor :
|
|
647
|
-
const strokeColor = outlined ? conceptColor : active ? "white" :
|
|
650
|
+
const bgFill = outlined ? "white" : active ? conceptColor : DEFAULT_FILL;
|
|
651
|
+
const strokeColor = outlined ? conceptColor : active ? "white" : DEFAULT_STROKE;
|
|
648
652
|
|
|
649
653
|
return (
|
|
650
654
|
<svg
|
|
@@ -716,8 +720,8 @@ export const IconConceptMaterials: React.FC<ConceptIconProps> = ({
|
|
|
716
720
|
outlined = false,
|
|
717
721
|
}) => {
|
|
718
722
|
const conceptColor = conceptColors.materials.solid;
|
|
719
|
-
const bgFill = outlined ? "white" : active ? conceptColor :
|
|
720
|
-
const strokeColor = outlined ? conceptColor : active ? "white" :
|
|
723
|
+
const bgFill = outlined ? "white" : active ? conceptColor : DEFAULT_FILL;
|
|
724
|
+
const strokeColor = outlined ? conceptColor : active ? "white" : DEFAULT_STROKE;
|
|
721
725
|
|
|
722
726
|
return (
|
|
723
727
|
<svg
|
|
@@ -773,8 +777,8 @@ export const IconConceptInnovation: React.FC<ConceptIconProps> = ({
|
|
|
773
777
|
outlined = false,
|
|
774
778
|
}) => {
|
|
775
779
|
const conceptColor = conceptColors.innovation.solid;
|
|
776
|
-
const bgFill = outlined ? "white" : active ? conceptColor :
|
|
777
|
-
const strokeColor = outlined ? conceptColor : active ? "white" :
|
|
780
|
+
const bgFill = outlined ? "white" : active ? conceptColor : DEFAULT_FILL;
|
|
781
|
+
const strokeColor = outlined ? conceptColor : active ? "white" : DEFAULT_STROKE;
|
|
778
782
|
|
|
779
783
|
return (
|
|
780
784
|
<svg
|
|
@@ -16,7 +16,7 @@ const getStatusClass = (
|
|
|
16
16
|
status: TagStatus,
|
|
17
17
|
variant: "light" | "dark" = "light"
|
|
18
18
|
) => {
|
|
19
|
-
return `tag tag--${variant}-${status}`;
|
|
19
|
+
return `status-tag tag--${variant}-${status}`;
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
export const Tag = React.forwardRef<HTMLButtonElement, TagProps>(
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
3
|
+
|
|
4
|
+
import { cn } from "@/lib/utils";
|
|
5
|
+
|
|
6
|
+
const typographyVariants = cva("", {
|
|
7
|
+
variants: {
|
|
8
|
+
variant: {
|
|
9
|
+
"heading-large": "heading-large",
|
|
10
|
+
"heading-medium": "heading-medium",
|
|
11
|
+
"heading-small": "heading-small",
|
|
12
|
+
"heading-xsmall": "heading-xsmall",
|
|
13
|
+
"heading-xxsmall": "heading-xxsmall",
|
|
14
|
+
"body-large": "body-large",
|
|
15
|
+
"body-base": "body-base",
|
|
16
|
+
"body-small": "body-small",
|
|
17
|
+
"overline-large": "overline-large",
|
|
18
|
+
"overline-medium": "overline-medium",
|
|
19
|
+
"overline-small": "overline-small",
|
|
20
|
+
"number-large": "number-large",
|
|
21
|
+
"number-base": "number-base",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
defaultVariants: {
|
|
25
|
+
variant: "body-base",
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
type Variant = NonNullable<VariantProps<typeof typographyVariants>["variant"]>;
|
|
30
|
+
|
|
31
|
+
const defaultElementMap: Record<Variant, React.ElementType> = {
|
|
32
|
+
"heading-large": "h1",
|
|
33
|
+
"heading-medium": "h2",
|
|
34
|
+
"heading-small": "h3",
|
|
35
|
+
"heading-xsmall": "h4",
|
|
36
|
+
"heading-xxsmall": "h5",
|
|
37
|
+
"body-large": "p",
|
|
38
|
+
"body-base": "p",
|
|
39
|
+
"body-small": "p",
|
|
40
|
+
"overline-large": "span",
|
|
41
|
+
"overline-medium": "span",
|
|
42
|
+
"overline-small": "span",
|
|
43
|
+
"number-large": "span",
|
|
44
|
+
"number-base": "span",
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
interface TextProps extends React.HTMLAttributes<HTMLElement> {
|
|
48
|
+
variant?: Variant;
|
|
49
|
+
as?: React.ElementType;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const Text = React.forwardRef<HTMLElement, TextProps>(
|
|
53
|
+
({ className, variant = "body-base", as, ...props }, ref) => {
|
|
54
|
+
const Component = as || defaultElementMap[variant];
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<Component
|
|
58
|
+
ref={ref}
|
|
59
|
+
className={cn(typographyVariants({ variant }), className)}
|
|
60
|
+
{...props}
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
Text.displayName = "Text";
|
|
66
|
+
|
|
67
|
+
interface ListProps extends React.HTMLAttributes<HTMLUListElement> {}
|
|
68
|
+
|
|
69
|
+
const List = React.forwardRef<HTMLUListElement, ListProps>(
|
|
70
|
+
({ className, ...props }, ref) => {
|
|
71
|
+
return (
|
|
72
|
+
<ul
|
|
73
|
+
ref={ref}
|
|
74
|
+
className={cn("typography-list", className)}
|
|
75
|
+
{...props}
|
|
76
|
+
/>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
List.displayName = "List";
|
|
81
|
+
|
|
82
|
+
interface ListItemProps extends React.HTMLAttributes<HTMLLIElement> {
|
|
83
|
+
variant?: Variant;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const ListItem = React.forwardRef<HTMLLIElement, ListItemProps>(
|
|
87
|
+
({ className, variant = "body-base", children, ...props }, ref) => {
|
|
88
|
+
return (
|
|
89
|
+
<li
|
|
90
|
+
ref={ref}
|
|
91
|
+
className={cn("typography-list-item", className)}
|
|
92
|
+
{...props}
|
|
93
|
+
>
|
|
94
|
+
<svg
|
|
95
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
96
|
+
width="4"
|
|
97
|
+
height="4"
|
|
98
|
+
viewBox="0 0 4 4"
|
|
99
|
+
fill="none"
|
|
100
|
+
className="typography-list-bullet"
|
|
101
|
+
aria-hidden="true"
|
|
102
|
+
>
|
|
103
|
+
<circle cx="2" cy="2" r="2" fill="#71747D" />
|
|
104
|
+
</svg>
|
|
105
|
+
<span className={cn(typographyVariants({ variant }))}>
|
|
106
|
+
{children}
|
|
107
|
+
</span>
|
|
108
|
+
</li>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
ListItem.displayName = "ListItem";
|
|
113
|
+
|
|
114
|
+
export { Text, List, ListItem, typographyVariants, defaultElementMap };
|
|
115
|
+
export type { TextProps, ListProps, ListItemProps, Variant as TypographyVariant };
|
|
116
|
+
|
package/client/global.css
CHANGED
|
@@ -699,7 +699,7 @@
|
|
|
699
699
|
}
|
|
700
700
|
|
|
701
701
|
/* Tag Styles */
|
|
702
|
-
.tag {
|
|
702
|
+
.status-tag {
|
|
703
703
|
display: inline-flex;
|
|
704
704
|
align-items: center;
|
|
705
705
|
padding: 8px;
|
|
@@ -709,14 +709,14 @@
|
|
|
709
709
|
transition: all 0.2s ease-in-out;
|
|
710
710
|
}
|
|
711
711
|
|
|
712
|
-
.tag:focus-visible {
|
|
712
|
+
.status-tag:focus-visible {
|
|
713
713
|
outline: none;
|
|
714
714
|
box-shadow:
|
|
715
715
|
0 0 0 2px hsl(var(--ring)),
|
|
716
716
|
0 0 0 4px var(--color-white, #fff);
|
|
717
717
|
}
|
|
718
718
|
|
|
719
|
-
.tag:disabled {
|
|
719
|
+
.status-tag:disabled {
|
|
720
720
|
opacity: 0.5;
|
|
721
721
|
cursor: not-allowed;
|
|
722
722
|
}
|
|
@@ -5528,3 +5528,22 @@
|
|
|
5528
5528
|
width: 1rem;
|
|
5529
5529
|
height: 1rem;
|
|
5530
5530
|
}
|
|
5531
|
+
|
|
5532
|
+
/* Typography List Styles */
|
|
5533
|
+
.typography-list {
|
|
5534
|
+
display: flex;
|
|
5535
|
+
flex-direction: column;
|
|
5536
|
+
gap: 1rem;
|
|
5537
|
+
padding-left: 0.5rem;
|
|
5538
|
+
margin-top: 1rem;
|
|
5539
|
+
}
|
|
5540
|
+
|
|
5541
|
+
.typography-list-item {
|
|
5542
|
+
display: flex;
|
|
5543
|
+
align-items: center;
|
|
5544
|
+
}
|
|
5545
|
+
|
|
5546
|
+
.typography-list-bullet {
|
|
5547
|
+
flex-shrink: 0;
|
|
5548
|
+
margin-right: 1rem;
|
|
5549
|
+
}
|
|
@@ -19,7 +19,20 @@ import {
|
|
|
19
19
|
} from "../components/ui/select";
|
|
20
20
|
import { Label } from "../components/ui/label";
|
|
21
21
|
import { Toggle } from "../components/ui/toggle";
|
|
22
|
-
|
|
22
|
+
import {
|
|
23
|
+
IconConceptMind,
|
|
24
|
+
IconConceptCommunity,
|
|
25
|
+
IconConceptMovement,
|
|
26
|
+
IconConceptWater,
|
|
27
|
+
IconConceptAir,
|
|
28
|
+
IconConceptLight,
|
|
29
|
+
IconConceptThermalComfort,
|
|
30
|
+
IconConceptNourishment,
|
|
31
|
+
IconConceptSound,
|
|
32
|
+
IconConceptMaterials,
|
|
33
|
+
IconConceptInnovation,
|
|
34
|
+
} from "../components/icons/ConceptIcons";
|
|
35
|
+
import { Text } from "../components/ui/typography";
|
|
23
36
|
import { UtilityReset } from "../components/icons/UtilityReset";
|
|
24
37
|
|
|
25
38
|
const meta = {
|
|
@@ -192,20 +205,6 @@ export const FiltersPanel: Story = {
|
|
|
192
205
|
// },
|
|
193
206
|
// };
|
|
194
207
|
|
|
195
|
-
import {
|
|
196
|
-
IconConceptAir,
|
|
197
|
-
IconConceptCommunity,
|
|
198
|
-
IconConceptLight,
|
|
199
|
-
IconConceptMaterials,
|
|
200
|
-
IconConceptMind,
|
|
201
|
-
IconConceptMovement,
|
|
202
|
-
IconConceptNourishment,
|
|
203
|
-
IconConceptSound,
|
|
204
|
-
IconConceptThermalComfort,
|
|
205
|
-
IconConceptWater,
|
|
206
|
-
} from "../components/icons/ConceptIcons";
|
|
207
|
-
|
|
208
|
-
// ... existing imports
|
|
209
208
|
|
|
210
209
|
export const NavigatorPanel: Story = {
|
|
211
210
|
render: () => {
|
|
@@ -255,11 +254,10 @@ export const NavigatorPanel: Story = {
|
|
|
255
254
|
<button
|
|
256
255
|
key={theme}
|
|
257
256
|
onClick={() => setActiveTheme(theme)}
|
|
258
|
-
className={`w-12 h-8 rounded-[6px] flex items-center justify-center transition-colors ${
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}`}
|
|
257
|
+
className={`w-12 h-8 rounded-[6px] flex items-center justify-center transition-colors ${activeTheme === theme
|
|
258
|
+
? "bg-cyan-800 text-white"
|
|
259
|
+
: "bg-blue-100 text-blue-600 hover:bg-blue-200"
|
|
260
|
+
}`}
|
|
263
261
|
>
|
|
264
262
|
<span className="body-small font-semibold">{theme}</span>
|
|
265
263
|
</button>
|
|
@@ -275,11 +273,10 @@ export const NavigatorPanel: Story = {
|
|
|
275
273
|
<button
|
|
276
274
|
key={strategy}
|
|
277
275
|
onClick={() => setActiveStrategy(strategy)}
|
|
278
|
-
className={`w-12 h-8 rounded-[6px] flex items-center justify-center transition-colors ${
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
}`}
|
|
276
|
+
className={`w-12 h-8 rounded-[6px] flex items-center justify-center transition-colors ${activeStrategy === strategy
|
|
277
|
+
? "bg-[#0F748A]/10 border border-[#0F748A]/20 text-cyan-900"
|
|
278
|
+
: "bg-blue-100 text-blue-600 hover:bg-blue-200"
|
|
279
|
+
}`}
|
|
283
280
|
>
|
|
284
281
|
<span className="body-small font-semibold">{strategy}</span>
|
|
285
282
|
</button>
|
|
@@ -303,3 +300,124 @@ export const NavigatorPanel: Story = {
|
|
|
303
300
|
);
|
|
304
301
|
},
|
|
305
302
|
};
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
export const ConceptCard: Story = {
|
|
306
|
+
render: () => {
|
|
307
|
+
const CONCEPTS_MOCK = [
|
|
308
|
+
{
|
|
309
|
+
id: "air",
|
|
310
|
+
slug: "air",
|
|
311
|
+
name: "Air",
|
|
312
|
+
title: "AIR",
|
|
313
|
+
description: "Reduce or minimize sources of indoor air pollution",
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
id: "water",
|
|
317
|
+
slug: "water",
|
|
318
|
+
name: "Water",
|
|
319
|
+
title: "WATER",
|
|
320
|
+
description: "Increase hydration and access to high quality water",
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
id: "nourishment",
|
|
324
|
+
slug: "nourishment",
|
|
325
|
+
name: "Nourishment",
|
|
326
|
+
title: "NOURISHMENT",
|
|
327
|
+
description:
|
|
328
|
+
"Make healthy foods the easy decision and encourage better food choices",
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
id: "light",
|
|
332
|
+
slug: "light",
|
|
333
|
+
name: "Light",
|
|
334
|
+
title: "LIGHT",
|
|
335
|
+
description:
|
|
336
|
+
"Design lighting to increase alertness, enhance occupant experience, and promote optimal sleep patterns",
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
id: "movement",
|
|
340
|
+
slug: "movement",
|
|
341
|
+
name: "Movement",
|
|
342
|
+
title: "MOVEMENT",
|
|
343
|
+
description: "Integrate physical activity and fitness into everyday life",
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
id: "thermal-comfort",
|
|
347
|
+
slug: "thermal-comfort",
|
|
348
|
+
name: "Thermal Comfort",
|
|
349
|
+
title: "THERMAL COMFORT",
|
|
350
|
+
description: "Provide productive and comfortable indoor environments",
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
id: "sound",
|
|
354
|
+
slug: "sound",
|
|
355
|
+
name: "Sound",
|
|
356
|
+
title: "SOUND",
|
|
357
|
+
description:
|
|
358
|
+
"Support optimal acoustical comfort to reduce distractions and promote focus",
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
id: "materials",
|
|
362
|
+
slug: "materials",
|
|
363
|
+
name: "Materials",
|
|
364
|
+
title: "MATERIALS",
|
|
365
|
+
description:
|
|
366
|
+
"Improve respiratory health through use of safe materials and finishes",
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
id: "community",
|
|
370
|
+
slug: "community",
|
|
371
|
+
name: "Community",
|
|
372
|
+
title: "COMMUNITY",
|
|
373
|
+
description: "Foster community engagement and social support",
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
id: "mind",
|
|
377
|
+
slug: "mind",
|
|
378
|
+
name: "Mind",
|
|
379
|
+
title: "MIND",
|
|
380
|
+
description:
|
|
381
|
+
"Support cognitive and emotional health through design, technology, and treatment strategies",
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
id: "innovation",
|
|
385
|
+
slug: "innovation",
|
|
386
|
+
name: "Innovation",
|
|
387
|
+
title: "INNOVATION",
|
|
388
|
+
description: "Develop unique strategies for creating healthy environments",
|
|
389
|
+
},
|
|
390
|
+
];
|
|
391
|
+
|
|
392
|
+
const CONCEPT_ICONS = {
|
|
393
|
+
air: IconConceptAir,
|
|
394
|
+
water: IconConceptWater,
|
|
395
|
+
nourishment: IconConceptNourishment,
|
|
396
|
+
light: IconConceptLight,
|
|
397
|
+
movement: IconConceptMovement,
|
|
398
|
+
"thermal-comfort": IconConceptThermalComfort,
|
|
399
|
+
sound: IconConceptSound,
|
|
400
|
+
materials: IconConceptMaterials,
|
|
401
|
+
community: IconConceptCommunity,
|
|
402
|
+
mind: IconConceptMind,
|
|
403
|
+
innovation: IconConceptInnovation,
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
return (
|
|
407
|
+
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
408
|
+
{CONCEPTS_MOCK.map((concept) => {
|
|
409
|
+
const Icon = CONCEPT_ICONS[concept.slug as keyof typeof CONCEPT_ICONS];
|
|
410
|
+
return (
|
|
411
|
+
<Card key={concept.id} className=" border-gray-100 bg-white p-6 gap-6 hover:scale-102 hover:border-gray-200 ease-in-out duration-200 will-change-transform">
|
|
412
|
+
<div className="flex items-center gap-4">
|
|
413
|
+
{Icon && <Icon className="size-12" />}
|
|
414
|
+
<Text as="h3" variant="overline-large">{concept.title}</Text>
|
|
415
|
+
</div>
|
|
416
|
+
<Text as="p" variant="body-base">{concept.description}</Text>
|
|
417
|
+
</Card>
|
|
418
|
+
);
|
|
419
|
+
})}
|
|
420
|
+
</div>
|
|
421
|
+
);
|
|
422
|
+
},
|
|
423
|
+
};
|