@myelmut/design-system 0.1.52 → 0.1.53
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/index.cjs +39 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +421 -362
- package/dist/index.es.js.map +1 -1
- package/dist/types/index.d.ts +1 -2
- package/package.json +1 -1
- package/src/components/Cards/PlanCard/PlanCard.tsx +1 -1
- package/src/components/Navigation/Tabs/Tabs.stories.tsx +16 -4
- package/src/components/Navigation/Tabs/Tabs.tsx +85 -21
package/dist/types/index.d.ts
CHANGED
|
@@ -640,7 +640,7 @@ declare interface TabItem {
|
|
|
640
640
|
disabled?: boolean;
|
|
641
641
|
}
|
|
642
642
|
|
|
643
|
-
export declare const Tabs: ({ tabs, defaultActiveTab, onTabChange, className, tabClassName, activeTabClassName,
|
|
643
|
+
export declare const Tabs: ({ tabs, defaultActiveTab, onTabChange, className, tabClassName, activeTabClassName, variant }: TabsProps) => JSX.Element;
|
|
644
644
|
|
|
645
645
|
declare interface TabsProps {
|
|
646
646
|
tabs: TabItem[];
|
|
@@ -649,7 +649,6 @@ declare interface TabsProps {
|
|
|
649
649
|
className?: string;
|
|
650
650
|
tabClassName?: string;
|
|
651
651
|
activeTabClassName?: string;
|
|
652
|
-
contentClassName?: string;
|
|
653
652
|
variant?: 'default';
|
|
654
653
|
}
|
|
655
654
|
|
package/package.json
CHANGED
|
@@ -39,7 +39,7 @@ export const PlanCard = ({
|
|
|
39
39
|
}: PlanCardProps) => {
|
|
40
40
|
return (
|
|
41
41
|
<div className={clsx(
|
|
42
|
-
'bg-beige-dark rounded-
|
|
42
|
+
'bg-beige-dark rounded-br-2xl rounded-bl-2xl border-2 border-beige-dark p-6 flex flex-col md:flex-row gap-6 relative overflow-visible',
|
|
43
43
|
className
|
|
44
44
|
)}>
|
|
45
45
|
{/* Product Image */}
|
|
@@ -35,10 +35,6 @@ const meta = {
|
|
|
35
35
|
control: 'text',
|
|
36
36
|
description: 'Additional classes to apply to the active tab button',
|
|
37
37
|
},
|
|
38
|
-
contentClassName: {
|
|
39
|
-
control: 'text',
|
|
40
|
-
description: 'Additional classes to apply to the content area',
|
|
41
|
-
},
|
|
42
38
|
},
|
|
43
39
|
|
|
44
40
|
globals: {
|
|
@@ -85,6 +81,22 @@ const sampleTabs = [
|
|
|
85
81
|
/>
|
|
86
82
|
),
|
|
87
83
|
},
|
|
84
|
+
{
|
|
85
|
+
id: 'quarter',
|
|
86
|
+
label: 'Elmut quart pension',
|
|
87
|
+
content: (
|
|
88
|
+
<PlanCard
|
|
89
|
+
title="Quart pension"
|
|
90
|
+
description="Du Elmut pour couvrir 25% des besoins caloriques de votre animal, complété par vos croquettes habituelles."
|
|
91
|
+
dailyAmount="150g/jour"
|
|
92
|
+
price="1,35€"
|
|
93
|
+
originalPrice="1,93€"
|
|
94
|
+
discountPercentage="-30%"
|
|
95
|
+
planImage="/images/trash/full-cat.png"
|
|
96
|
+
planImageAlt="Demi-bol de nourriture pour chien"
|
|
97
|
+
/>
|
|
98
|
+
),
|
|
99
|
+
},
|
|
88
100
|
];
|
|
89
101
|
|
|
90
102
|
export const Default: Story = {
|
|
@@ -20,11 +20,10 @@ export interface TabsProps {
|
|
|
20
20
|
className?: string;
|
|
21
21
|
tabClassName?: string;
|
|
22
22
|
activeTabClassName?: string;
|
|
23
|
-
contentClassName?: string;
|
|
24
23
|
variant?: 'default';
|
|
25
24
|
}
|
|
26
25
|
|
|
27
|
-
export const Tabs = ({ tabs, defaultActiveTab, onTabChange, className = '', tabClassName = '', activeTabClassName = '',
|
|
26
|
+
export const Tabs = ({ tabs, defaultActiveTab, onTabChange, className = '', tabClassName = '', activeTabClassName = '', variant = 'default' }: TabsProps) => {
|
|
28
27
|
const [activeTab, setActiveTab] = useState(defaultActiveTab || tabs[0]?.id);
|
|
29
28
|
|
|
30
29
|
const handleTabClick = (e: React.MouseEvent<HTMLButtonElement>, tabId: string) => {
|
|
@@ -49,45 +48,110 @@ export const Tabs = ({ tabs, defaultActiveTab, onTabChange, className = '', tabC
|
|
|
49
48
|
default: `bg-claret-violet-dark/30 text-claret-violet-dark `,
|
|
50
49
|
};
|
|
51
50
|
|
|
51
|
+
const firstTabShape = `shape(
|
|
52
|
+
from bottom left,
|
|
53
|
+
|
|
54
|
+
/* 1) go a bit OUTSIDE below the card */
|
|
55
|
+
curve to 12px calc(100% + 12px) with 0 calc(100% + 0px),
|
|
56
|
+
|
|
57
|
+
/* 2) come back to the normal bottom edge */
|
|
58
|
+
curve to 0px calc(100% - 0px) with 0 100%,
|
|
59
|
+
|
|
60
|
+
/* 3) original path resumes */
|
|
61
|
+
vline to 12px,
|
|
62
|
+
curve to 24px 0 with 12px 0,
|
|
63
|
+
hline to calc(100% - calc(12px * 2)),
|
|
64
|
+
curve to calc(100% - 12px) 12px with calc(100% - 12px) 0,
|
|
65
|
+
vline to calc(100% - 12px),
|
|
66
|
+
curve to 100% 100% with calc(100% - 12px) 100%
|
|
67
|
+
)`;
|
|
68
|
+
|
|
69
|
+
const middleTabShape = `shape(
|
|
70
|
+
from bottom left,
|
|
71
|
+
curve to 12px calc(100% - 12px) with
|
|
72
|
+
12px 100%,
|
|
73
|
+
vline to 12px,
|
|
74
|
+
curve to 24px 0 with 12px 0,
|
|
75
|
+
hline to calc(100% - calc(12px * 2)),
|
|
76
|
+
curve to calc(100% - 12px) 12px with
|
|
77
|
+
calc(100% - 12px) 0,
|
|
78
|
+
vline to calc(100% - 12px),
|
|
79
|
+
curve to 100% 100% with calc(100% - 12px) 100%
|
|
80
|
+
)`;
|
|
81
|
+
|
|
82
|
+
const lastTabShape = `shape(
|
|
83
|
+
from bottom left,
|
|
84
|
+
curve to 12px calc(100% - 12px) with
|
|
85
|
+
12px 100%,
|
|
86
|
+
vline to 12px,
|
|
87
|
+
curve to 24px 0 with 12px 0,
|
|
88
|
+
hline to calc(100%),
|
|
89
|
+
curve to calc(100%) 12px with
|
|
90
|
+
calc(100%) 0,
|
|
91
|
+
vline to calc(100% - 12px),
|
|
92
|
+
curve to calc(100%) 100% with calc(100%) 100%
|
|
93
|
+
)`;
|
|
94
|
+
|
|
52
95
|
|
|
53
96
|
return (
|
|
54
97
|
<div className={clsx('w-full', className)}>
|
|
55
98
|
{/* Tab Navigation */}
|
|
56
|
-
<div className={clsx('flex
|
|
99
|
+
<div className={clsx('flex gap-2')}>
|
|
57
100
|
{tabs.map((tab, index) => {
|
|
58
101
|
const isActive = activeTab === tab.id;
|
|
59
102
|
const isDisabled = tab.disabled;
|
|
103
|
+
const isFirstIndex = index === 0;
|
|
60
104
|
const isLastIndex = index === tabs.length - 1;
|
|
105
|
+
const clipPathStyle = isFirstIndex ? firstTabShape : isLastIndex ? lastTabShape : middleTabShape;
|
|
61
106
|
|
|
62
107
|
return (
|
|
63
|
-
<
|
|
108
|
+
<div
|
|
64
109
|
key={tab.id}
|
|
65
|
-
onClick={(e) => handleTabClick(e, tab.id)}
|
|
66
|
-
disabled={isDisabled}
|
|
67
110
|
className={clsx(
|
|
68
111
|
"w-full",
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
tabClassName,
|
|
75
|
-
{
|
|
76
|
-
[activeTabClassName]: isActive,
|
|
77
|
-
},
|
|
112
|
+
"relative",
|
|
113
|
+
// Z-index pour l'onglet actif
|
|
114
|
+
isActive && "z-20",
|
|
115
|
+
// Chevauchement des tabs (sauf le premier)
|
|
116
|
+
!isFirstIndex && "-ml-6",
|
|
78
117
|
)}
|
|
79
118
|
>
|
|
80
|
-
<
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
119
|
+
<button
|
|
120
|
+
onClick={(e) => handleTabClick(e, tab.id)}
|
|
121
|
+
disabled={isDisabled}
|
|
122
|
+
className={clsx(
|
|
123
|
+
"relative w-full inline-block whitespace-nowrap font-bold text-decoration-none transition-transform duration-100",
|
|
124
|
+
baseTabStyles[variant],
|
|
125
|
+
{
|
|
126
|
+
[activeTabStyles[variant]]: isActive,
|
|
127
|
+
[inactiveTabStyles[variant]]: !isActive,
|
|
128
|
+
},
|
|
129
|
+
tabClassName,
|
|
130
|
+
{
|
|
131
|
+
[activeTabClassName]: isActive,
|
|
132
|
+
},
|
|
133
|
+
)}
|
|
134
|
+
style={{
|
|
135
|
+
clipPath: clipPathStyle,
|
|
136
|
+
}}
|
|
137
|
+
>
|
|
138
|
+
<div className="flex items-center gap-[16px]">
|
|
139
|
+
<div className="w-6">{isActive ? <CheckRoundedIcon className="w-6" /> : null}</div>
|
|
140
|
+
<Text size="xl">{tab.label}</Text>
|
|
141
|
+
</div>
|
|
142
|
+
</button>
|
|
143
|
+
</div>
|
|
85
144
|
);
|
|
86
145
|
})}
|
|
87
146
|
</div>
|
|
88
147
|
|
|
89
148
|
{/* Tab Content */}
|
|
90
|
-
{activeTabContent ?
|
|
149
|
+
{activeTabContent ? (
|
|
150
|
+
<div
|
|
151
|
+
>
|
|
152
|
+
{activeTabContent}
|
|
153
|
+
</div>
|
|
154
|
+
) : null}
|
|
91
155
|
</div>
|
|
92
156
|
);
|
|
93
157
|
};
|