@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.
@@ -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, contentClassName, variant }: TabsProps) => JSX.Element;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myelmut/design-system",
3
- "version": "0.1.52",
3
+ "version": "0.1.53",
4
4
  "description": "Design system for Elmut project",
5
5
  "repository": {
6
6
  "type": "git",
@@ -39,7 +39,7 @@ export const PlanCard = ({
39
39
  }: PlanCardProps) => {
40
40
  return (
41
41
  <div className={clsx(
42
- 'bg-beige-dark rounded-tr-2xl rounded-br-2xl rounded-bl-2xl border-2 border-beige-dark p-6 flex flex-col md:flex-row gap-6 relative overflow-visible',
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 = '', contentClassName = '', variant = 'default' }: TabsProps) => {
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', variant === 'default' ? 'border-b border-gray-200' : 'gap-1')}>
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
- <button
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
- baseTabStyles[variant],
70
- {
71
- [activeTabStyles[variant]]: isActive,
72
- [inactiveTabStyles[variant]]: !isActive,
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
- <div className="flex items-center gap-[16px]">
81
- <div className="w-6">{isActive ? <CheckRoundedIcon className="w-6" /> : null}</div>
82
- <Text size="xl">{tab.label}</Text>
83
- </div>
84
- </button>
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 ? <div className={clsx(contentClassName)}>{activeTabContent}</div> : null}
149
+ {activeTabContent ? (
150
+ <div
151
+ >
152
+ {activeTabContent}
153
+ </div>
154
+ ) : null}
91
155
  </div>
92
156
  );
93
157
  };