aravint-ui-navigation 1.0.21 → 1.0.22

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/Readme.md CHANGED
@@ -1,249 +1,102 @@
1
- # @digitus-fci-oa/button
1
+ # CustomTabs
2
2
 
3
- A reusable, accessible Button component with support for variants, icons, loading states, and tooltip-enabled icon buttons.
3
+ A reusable, dependency-free React + TypeScript tabs component with numbered badges, sticky tab bar, and mobile-responsive sizing — while preserving the original desktop/tablet look exactly.
4
4
 
5
- Refer to this URL for npm:
6
-
7
- https://github.com/digitus-git/AFCI_OffAuto/tree/develop_rel_phase1/packages
8
-
9
-
5
+ ## Features
10
6
 
11
- ---
7
+ - Controlled or uncontrolled usage (`value`/`onValueChange` or `defaultValue`)
8
+ - Numbered badges per tab (optional)
9
+ - Optional icons per tab
10
+ - Disabled tab support
11
+ - Sticky tab bar (`position: sticky; top: 0`)
12
+ - Active-tab underline-hiding trick (`marginBottom: -1`) to visually merge the active tab with its content panel
13
+ - Responsive breakpoints for tablet (`≤768px`) and phone (`≤480px`) that only affect sizing (padding, font-size, gap, badge size) — colors, borders, and desktop layout are untouched
14
+ - On phones, tabs wrap to a new row instead of overflowing or forcing horizontal scroll
12
15
 
13
16
  ## Installation
14
17
 
15
- ```bash
16
- npm install @digitus-fci-oa/button
17
- ```
18
-
19
- ---
18
+ Copy `CustomTabs.tsx` into your project (e.g. `src/components/CustomTabs.tsx`). No extra dependencies — just React.
20
19
 
21
- ## Usage
20
+ ## Basic Usage
22
21
 
23
22
  ```tsx
24
- import { Button } from '@digitus-fci-oa/button';
25
- import { Save, Trash2, X, Pencil } from 'lucide-react';
26
-
27
- export function TestButton() {
28
- return (
29
- <div style={{ display: "flex", gap: "10px", padding: "20px" }}>
30
-
31
- <Button variant="save" leftIcon={<Save size={14} />} loading={saveLoading}>
32
- Save
33
- </Button>
34
-
35
- <Button variant="update" rightIcon={<Save size={14} />}>
36
- Update
37
- </Button>
38
-
39
- <Button variant="delete" leftIcon={<Trash2 size={14} />}>
40
- Delete
41
- </Button>
42
-
43
- <Button variant="cancel" leftIcon={<X size={14} />}>
44
- Cancel
45
- </Button>
46
-
47
- {/* Icon-only button with tooltip */}
48
- <Button
49
- variant="update"
50
- size="icon"
51
- iconButton
52
- tooltipLabel="Edit record"
53
- >
54
- <Pencil size={16} />
55
- </Button>
23
+ import CustomTabs, { TabItem } from "@digitus-fci-oa/navigation";
56
24
 
57
- </div>
58
- );
59
- }
60
- ```
61
- export default function Example() {
62
- const [open, setOpen] = useState(false);
25
+ const tabs: TabItem[] = [
26
+ { id: "overview", label: "Overview", content: <OverviewPanel /> },
27
+ { id: "details", label: "Details", content: <DetailsPanel /> },
28
+ { id: "history", label: "History", content: <HistoryPanel />, disabled: true },
29
+ ];
63
30
 
64
- const handleExport = async (
65
- type: "xlsx" | "csv" | "pdf"
66
- ) => {
67
- console.log(type);
68
- };
31
+ function App() {
32
+ const [activeTab, setActiveTab] = useState("overview");
69
33
 
70
34
  return (
71
- <ExportButton
72
- open={open}
73
- setOpen={setOpen}
74
- onExport={handleExportClick}
75
- buttonClassName="
76
- flex items-center
77
- gap-[2px]
78
- bg-[hsla(161,94%,30%,1)]
79
- h-[30px]
80
- px-3
81
- rounded-[8px]
82
- text-white
83
- text-xs
84
- font-medium
85
- "
86
- buttonIcon={
87
- <>
88
- <Download className="w-4 h-4 text-white" />
89
- <span className="text-white">Export</span>
90
- </>
91
- }
92
- items={{
93
- xlsx: {
94
- label: "XLSX",
95
- icon: <FileSpreadsheet />,
96
- iconClassName: "text-green-600",
97
- textClassName: "text-green-600",
98
- iconWidth: "w-5",
99
- iconHeight: "h-5",
100
- },
101
-
102
- csv: {
103
- label: "CSV",
104
- icon: <FileText />,
105
- iconClassName: "text-blue-600",
106
- textClassName: "text-blue-600",
107
- iconWidth: "w-5",
108
- iconHeight: "h-5",
109
- },
110
-
111
- pdf: {
112
- label: "PDF",
113
- icon: <FileText />,
114
- iconClassName: "text-red-600",
115
- textClassName: "text-red-600",
116
- iconWidth: "w-5",
117
- iconHeight: "h-5",
118
- },
119
- }}
120
- />
35
+ <div className="h-screen bg-gray-50 flex flex-col">
36
+ <div className="flex-1 min-h-0">
37
+ <CustomTabs
38
+ tabs={tabs}
39
+ value={activeTab}
40
+ onValueChange={setActiveTab}
41
+ showTabNumbers
42
+ className="h-full"
43
+ tabListClassName="bg-white"
44
+ />
45
+ </div>
46
+ </div>
121
47
  );
122
48
  }
123
49
  ```
124
50
 
125
- ---
126
- ---
127
-
128
51
  ## Props
129
52
 
130
- | Prop | Type | Default | Description |
131
- |----------------|-------------------|-------------|-----------------------------------------------------------------------------|
132
- | `variant` | `string` | `"default"` | Button style: `save`, `update`, `delete`, `cancel` |
133
- | `size` | `string` | `"default"` | Button size: `default`, `sm`, `lg`, `icon`, `xs` |
134
- | `loading` | `boolean` | `false` | Shows a loading spinner and disables the button |
135
- | `leftIcon` | `React.ReactNode` | `undefined` | Icon displayed to the left of the label |
136
- | `rightIcon` | `React.ReactNode` | `undefined` | Icon displayed to the right of the label |
137
- | `iconButton` | `boolean` | `false` | Wraps the button in a tooltip provider (use with `tooltipLabel`) |
138
- | `tooltipLabel` | `string` | `undefined` | Tooltip text shown on hover when `iconButton` is `true` |
139
- | `onClick` | `() => void` | `undefined` | Click handler |
140
- | `children` | `React.ReactNode` | | Button label text or icon content |
141
- | `disabled` | `boolean` | `false` | Disables the button |
142
- | `className` | `string` | `undefined` | Additional CSS classes (Tailwind supported) |
143
- | `style` | `CSSProperties` | `undefined` | Inline styles (merged on top of variant styles) |
144
-
145
- | `open` | `boolean` | |Controls dropdown visibility |
146
- | `setOpen` | `Dispatch<SetStateAction<boolean>>` | Updates dropdown state |
147
- | `onExport` | `(type) => void` | Export callback |
148
- | `buttonLabel` | `string` | | Button label |
149
- | `buttonIcon` | `ReactNode` | | Optional button icon |
150
- | `items` | `Record` | | Export menu items |
151
- | `className` | `string` | | Additional classes |
152
-
153
- ---
154
-
155
- ## Variants
156
-
157
- | Variant | Color | Description |
158
- |-----------|------------------|----------------------------------|
159
- | `default` | Blue (`#3B82F6`) | General-purpose action |
160
- | `save` | Navy (`#003B71`) | Primary save / create action |
161
- | `update` | Navy (`#003B71`) | Edit / update action |
162
- | `delete` | Red (`#FF6070`) | Destructive / remove action |
163
- | `cancel` | White / bordered | Dismiss / abort action |
164
-
165
- ---
166
-
167
- ## Sizes
168
-
169
- | Size | Height | Description |
170
- |-----------|--------|------------------------------------|
171
- | `default` | 40px | Standard button |
172
- | `sm` | 36px | Compact button |
173
- | `lg` | 44px | Large button |
174
- | `icon` | 40×40px| Square icon-only button |
175
- | `xs` | 20px | Extra-small button (e.g. in tables)|
176
-
177
- ---
178
-
179
- ## Icon Support
180
-
181
- Icons can be placed on the **left** or **right** side of the button label using `leftIcon` and `rightIcon` props. Works with any icon library (e.g. [lucide-react](https://lucide.dev/)).
53
+ | Prop | Type | Default | Description |
54
+ |---|---|---|---|
55
+ | `tabs` | `TabItem[]` | | **Required.** Array of tab definitions. |
56
+ | `defaultValue` | `string` | first tab's `id` | Initial active tab (uncontrolled mode). |
57
+ | `value` | `string` | | Active tab id (controlled mode). Providing this switches the component to controlled. |
58
+ | `onValueChange` | `(value: string) => void` | | Called when the user selects a tab. |
59
+ | `className` | `string` | `""` | Class on the outer wrapper. |
60
+ | `tabListClassName` | `string` | `""` | Class on the tab bar container. |
61
+ | `tabButtonClassName` | `string` | `""` | Class on each tab button. |
62
+ | `contentClassName` | `string` | `""` | Class on the content panel. |
63
+ | `showTabNumbers` | `boolean` | `true` | Show/hide the numbered badge on each tab. |
64
+ | `showContent` | `boolean` | `true` | Show/hide the content panel entirely (render tab bar only). |
65
+ | `animated` | `boolean` | `true` | Enables the opacity transition on the content panel. |
182
66
 
183
- ```tsx
184
- import { Pencil } from 'lucide-react';
185
-
186
- <Button variant="update" leftIcon={<Pencil size={14} />}>
187
- Edit
188
- </Button>
189
- ```
67
+ ### `TabItem`
190
68
 
191
- ---
69
+ | Field | Type | Description |
70
+ |---|---|---|
71
+ | `id` | `string` | **Required.** Unique tab identifier. |
72
+ | `label` | `string` | **Required.** Tab display text. |
73
+ | `content` | `React.ReactNode` | Content rendered when this tab is active. |
74
+ | `disabled` | `boolean` | Disables selection of this tab. |
75
+ | `icon` | `React.ReactNode` | Optional icon rendered before the label. |
192
76
 
193
- ## Loading State
77
+ ## Controlled vs Uncontrolled
194
78
 
195
- Pass `loading={true}` to show a spinner and automatically disable the button during async operations.
79
+ - **Uncontrolled:** omit `value`. The component manages its own active tab internally, seeded by `defaultValue` (or the first tab).
80
+ - **Controlled:** pass `value` + `onValueChange`. You own the active-tab state; the component only reports selection events.
196
81
 
197
- ```tsx
198
- const [saving, setSaving] = useState(false);
199
-
200
- <Button
201
- variant="save"
202
- loading={saving}
203
- onClick={() => setSaving(true)}
204
- leftIcon={<Save size={14} />}
205
- >
206
- Save
207
- </Button>
208
- ```
82
+ ## Styling Approach
209
83
 
210
- ## Supported Export Types
84
+ Colors, borders, radii, and the sticky/active-tab layout tricks are set as **inline styles** and are the same across all screen sizes — this is what keeps the desktop/tablet appearance unchanged.
211
85
 
212
- - XLSX
213
- - CSV
214
- - PDF
215
- ---
216
- ## Features
86
+ Only size-related properties (`padding`, `font-size`, `gap`, badge `width`/`height`) live in an injected `<style>` block using CSS classes (`.ctabs-list`, `.ctabs-btn`, `.ctabs-badge`, `.ctabs-label`), because inline styles can't respond to `@media` queries. This block ships inside the component, so no external CSS file is required.
217
87
 
218
- - Reusable dropdown export button
219
- - TailwindCSS support
220
- - Custom icons
221
- - Controlled open state
222
- - Lightweight and reusable
223
-
224
- ---
225
- ## Icon Button with Tooltip
226
-
227
- Set `iconButton={true}` to wrap the button in a tooltip. Pass `tooltipLabel` to set the tooltip text. Pair with `size="icon"` for a square icon-only button.
228
-
229
- ```tsx
230
- import { Trash2 } from 'lucide-react';
231
-
232
- <Button
233
- variant="delete"
234
- size="icon"
235
- iconButton
236
- tooltipLabel="Delete record"
237
- onClick={handleDelete}
238
- >
239
- <Trash2 size={16} />
240
- </Button>
241
- ```
88
+ ### Breakpoints
242
89
 
243
- > **Note:** `tooltipLabel` only displays when `iconButton` is `true`. If `tooltipLabel` is omitted while `iconButton` is `true`, the tooltip trigger is still rendered but no tooltip content is shown.
90
+ | Breakpoint | Behavior |
91
+ |---|---|
92
+ | Desktop (default) | Original sizing: `8px 20px` padding, `14px` font, `20px` badges. |
93
+ | Tablet (`≤768px`) | Slightly reduced padding/font/badge size. Tab bar scrolls horizontally if tabs overflow. |
94
+ | Phone (`≤480px`) | Further reduced padding/font/badge size. Tab bar **wraps** to a new row instead of scrolling, so every label stays fully visible. |
244
95
 
245
- ---
96
+ To customize breakpoint values, edit the `@media` blocks inside the component's `<style>` tag directly.
246
97
 
247
- ## License
98
+ ## Notes / Gotchas
248
99
 
249
- MIT
100
+ - `marginBottom: -1` on the active tab intentionally overlaps the tab bar's bottom border so the active tab visually "merges" into its content panel. This depends on `alignItems: "flex-end"` on the tab list — don't remove that when customizing.
101
+ - The phone-only `flex-wrap: wrap` sets `overflow-x: visible` to explicitly undo the tablet breakpoint's `overflow-x: auto`, since media query rules don't reset each other automatically.
102
+ - If you have a large number of tabs, consider whether wrapping (phone behavior) or horizontal scroll suits your use case better, and adjust the `480px` block accordingly.
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime"),B=require("react"),D=({tabs:o,defaultValue:p,value:a,onValueChange:i,className:c="",tabListClassName:x="",tabButtonClassName:b="",contentClassName:g="",showTabNumbers:h=!0,showContent:f=!0,animated:u=!0})=>{var l;const r=a!==void 0,[m,y]=B.useState(p||((l=o[0])==null?void 0:l.id)||""),n=r?a:m,w=e=>{r||y(e),i==null||i(e)},d=o.find(e=>e.id===n),F={display:"flex",alignItems:"flex-end",borderBottom:"1px solid #059669",position:"sticky",top:0,zIndex:100,flexShrink:0},v={display:"flex",alignItems:"center",fontFamily:"inherit",background:"transparent",cursor:"pointer",outline:"none",transition:"all .2s ease",position:"relative"},T={background:"#E8F7F1",color:"#059669",fontWeight:700,borderTop:"3px solid #059669",borderLeft:"1px solid #059669",borderRight:"1px solid #059669",borderBottom:"1px solid #E8F7F1",borderTopLeftRadius:8,borderTopRightRadius:8,marginBottom:-1,zIndex:2},k={background:"transparent",color:"#2D3748",borderTop:"3px solid transparent",borderLeft:"1px solid transparent",borderRight:"1px solid transparent",borderBottom:"1px solid transparent",borderTopLeftRadius:8,borderTopRightRadius:8},R={background:"#FFFFFF",color:"#059669",fontWeight:700,border:"1px solid #059669"},S={background:"#FFFFFF",color:"#374151",fontWeight:"500",border:"1px solid #D1D5DB"},j={background:"#FFFFFF",border:"1px solid #D9E1E7",borderTop:"none",borderBottomLeftRadius:12,borderBottomRightRadius:12,boxShadow:"0 2px 6px rgba(0,0,0,.05)",transition:u?"opacity .2s ease":void 0,opacity:1,flex:1,overflowY:"auto",minHeight:0};return t.jsxs("div",{className:c,style:{display:"flex",flexDirection:"column",width:"100%",height:"100%",minHeight:0,overflow:"hidden"},children:[t.jsx("style",{children:`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),v=require("react"),z=({tabs:i,defaultValue:d,value:s,onValueChange:a,className:o="",tabListClassName:n="",tabButtonClassName:b="",contentClassName:c="",showTabNumbers:r=!0,showContent:l=!0,animated:m=!0})=>{var S;const p=s!==void 0,[_,w]=v.useState(d||((S=i[0])==null?void 0:S.id)||""),f=p?s:_,y=t=>{p||w(t),a==null||a(t)},u=i.find(t=>t.id===f),j={display:"flex",alignItems:"flex-end",borderBottom:"1px solid #059669",position:"sticky",top:0,zIndex:100,flexShrink:0},F={display:"flex",alignItems:"center",fontFamily:"inherit",background:"transparent",cursor:"pointer",outline:"none",transition:"all .2s ease",position:"relative"},x={background:"#E8F7F1",color:"#059669",fontWeight:700,borderTop:"3px solid #059669",borderLeft:"1px solid #059669",borderRight:"1px solid #059669",borderBottom:"1px solid #E8F7F1",borderTopLeftRadius:8,borderTopRightRadius:8,marginBottom:-1,zIndex:2},g={background:"transparent",color:"#2D3748",borderTop:"3px solid transparent",borderLeft:"1px solid transparent",borderRight:"1px solid transparent",borderBottom:"1px solid transparent",borderTopLeftRadius:8,borderTopRightRadius:8},h={background:"#ECFDF5",color:"#059669",fontWeight:700,border:"1px solid #059669"},T={background:"#FFFFFF",color:"#1F2937",fontWeight:"500",border:"1px solid #1F2937"},B={background:"#FFFFFF",border:"1px solid #D9E1E7",borderTop:"none",borderBottomLeftRadius:12,borderBottomRightRadius:12,boxShadow:"0 2px 6px rgba(0,0,0,.05)",transition:m?"opacity .2s ease":void 0,opacity:1,flex:1,overflowY:"auto",minHeight:0};return e.jsxs("div",{className:o,style:{display:"flex",flexDirection:"column",width:"100%",height:"100%",minHeight:0,overflow:"hidden"},children:[e.jsx("style",{children:`
2
2
  .ctabs-list {
3
3
  padding: 0 10px;
4
4
  gap: 0px;
@@ -10,7 +10,7 @@
10
10
 
11
11
  .ctabs-btn {
12
12
  padding: 4px 20px;
13
- font-size: 14px;
13
+ font-size: 13px;
14
14
  font-weight: 500;
15
15
  gap: 8px;
16
16
  white-space: nowrap;
@@ -21,7 +21,7 @@
21
21
  width: 20px;
22
22
  height: 20px;
23
23
  border-radius: 4px;
24
- font-size: 12px;
24
+ font-size: 10px;
25
25
  font-weight: 600;
26
26
  flex-shrink: 0;
27
27
  display: flex;
@@ -72,4 +72,4 @@
72
72
  font-size: 10px;
73
73
  }
74
74
  }
75
- `}),t.jsx("div",{style:F,className:`ctabs-list ${x}`,children:o.map((e,z)=>{const s=n===e.id;return t.jsxs("button",{role:"tab","aria-selected":s,disabled:e.disabled,onClick:()=>!e.disabled&&w(e.id),style:{...v,...s?T:k,opacity:e.disabled?.5:1,cursor:e.disabled?"not-allowed":"pointer"},className:`ctabs-btn ${b}`,children:[h&&t.jsx("span",{className:"ctabs-badge",style:s?R:S,children:z+1}),e.icon,t.jsx("span",{className:"ctabs-label",children:e.label})]},e.id)})}),f&&d&&t.jsx("div",{style:j,className:g,children:d.content})]})};exports.CustomTabs=D;
75
+ `}),e.jsx("div",{style:j,className:`ctabs-list ${n}`,children:i.map((t,R)=>{const N=f===t.id;return e.jsxs("button",{role:"tab","aria-selected":N,disabled:t.disabled,onClick:()=>!t.disabled&&y(t.id),style:{...F,...N?x:g,opacity:t.disabled?.5:1,cursor:t.disabled?"not-allowed":"pointer"},className:`ctabs-btn ${b}`,children:[r&&e.jsx("span",{className:"ctabs-badge",style:N?h:T,children:R+1}),t.icon,e.jsx("span",{className:"ctabs-label",children:t.label})]},t.id)})}),l&&u&&e.jsx("div",{style:B,className:c,children:u.content})]})},L=()=>e.jsx("svg",{viewBox:"0 0 12 12",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:e.jsx("path",{d:"M2 6.2L4.6 8.8L10 3",stroke:"#ffffff",strokeWidth:"1.6",strokeLinecap:"round",strokeLinejoin:"round"})}),k=v.memo(({computed:i,showTime:d})=>{const{step:s,index:a,status:o}=i,n=["rs-stepper__circle",o==="completed"?"rs-stepper__circle--completed":"",o==="active"?"rs-stepper__circle--active":""].filter(Boolean).join(" "),b=["rs-stepper__title",o==="pending"?"rs-stepper__title--pending":"",o==="active"?"rs-stepper__title--active":""].filter(Boolean).join(" "),c=a!==0;return e.jsxs("div",{className:"rs-stepper__step",children:[e.jsxs("div",{className:"rs-stepper__circle-wrap",children:[e.jsx("div",{className:n,children:c?a:null}),o==="completed"&&e.jsx("span",{className:"rs-stepper__check","aria-hidden":"true",children:e.jsx(L,{})})]}),e.jsx("div",{className:b,children:s.title}),s.date&&e.jsx("div",{className:"rs-stepper__date",children:s.date}),d&&s.time&&e.jsx("div",{className:"rs-stepper__time",children:s.time})]})});k.displayName="StepCircle";const E=({steps:i,currentStep:d,completedColor:s="#059669",pendingColor:a="#9ca3af",activeColor:o="#059669",lineColor:n="#e5e7eb",showTime:b=!0,orientation:c="responsive"})=>{const r=i.length,l=d>r,m=Math.max(1,Math.min(d,r)),p=l?Math.max(0,r-1):Math.max(0,Math.min(r-1,m-1)),_=v.useMemo(()=>i.map((x,g)=>{let h="pending";return l||g<p?h="completed":g===p&&(h="active"),{step:x,index:g,status:h}}),[i,p,l]),w=r>0?100/r/2:0,f=r>1?l?100:p/(r-1)*100:0,y=l||m>1?s:n,u=l||m>r?s:n,j={"--rs-completed-color":s,"--rs-pending-color":a,"--rs-active-color":o,"--rs-line-color":n,"--rs-half-step":`${w}%`,"--rs-progress":`${f}%`,"--rs-left-side-color":y,"--rs-right-side-color":u};if(r===0)return null;const F=c==="vertical"?"rs-stepper--vertical":c==="horizontal"?"rs-stepper--horizontal":"rs-stepper--responsive";return e.jsxs("div",{className:"border border-[#E5E7EB] py-2 mx-2 rounded-lg bg-[#F9FAFB] shadow-[0px_2px_4px_-1px_#00000008,0px_4px_6px_-1px_#0000000D]",children:[e.jsx("div",{className:"pl-2 pt-2 pb-3 text-[14px] font-bold",children:"Workflow Progress"}),e.jsx("div",{className:`rs-stepper ${F}`,style:j,children:e.jsx("div",{className:"rs-stepper__scroll",children:e.jsxs("div",{className:"rs-stepper__row",children:[e.jsx("div",{className:"rs-stepper__track",children:e.jsx("div",{className:"rs-stepper__progress"})}),_.map(x=>e.jsx(k,{computed:x,showTime:b},x.step.id))]})})})]})},I=v.memo(E);exports.CustomTabs=z;exports.Stepper=I;
@@ -1 +1 @@
1
- /*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-font-weight:initial;--tw-outline-style:solid;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-600:oklch(57.7% .245 27.325);--color-green-600:oklch(62.7% .194 149.214);--color-blue-600:oklch(54.6% .245 262.881);--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--font-weight-medium:500;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.relative{position:relative}.sticky{position:sticky}.block{display:block}.flex{display:flex}.hidden{display:none}.inline{display:inline}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-\[30px\]{height:30px}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.flex-shrink{flex-shrink:1}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.gap-\[2px\]{gap:2px}.rounded-\[8px\]{border-radius:8px}.border{border-style:var(--tw-border-style);border-width:1px}.bg-\[hsla\(161\,94\%\,30\%\,1\)\]{background-color:#059467}.px-3{padding-inline:calc(var(--spacing) * 3)}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.text-blue-600{color:var(--color-blue-600)}.text-green-600{color:var(--color-green-600)}.text-red-600{color:var(--color-red-600)}.text-white{color:var(--color-white)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-ease{syntax:"*";inherits:false}
1
+ /*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-gray-50:oklch(98.5% .002 247.839);--color-white:#fff;--spacing:.25rem;--font-weight-bold:700;--radius-lg:.5rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.visible{visibility:visible}.relative{position:relative}.sticky{position:sticky}.mx-2{margin-inline:calc(var(--spacing) * 2)}.block{display:block}.flex{display:flex}.hidden{display:none}.inline{display:inline}.h-full{height:100%}.h-screen{height:100vh}.min-h-0{min-height:0}.flex-1{flex:1}.flex-shrink{flex-shrink:1}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.resize{resize:both}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.rounded-lg{border-radius:var(--radius-lg)}.border{border-style:var(--tw-border-style);border-width:1px}.border-\[\#E5E7EB\]{border-color:#e5e7eb}.bg-\[\#F9FAFB\]{background-color:#f9fafb}.bg-gray-50{background-color:var(--color-gray-50)}.bg-white{background-color:var(--color-white)}.py-2{padding-block:calc(var(--spacing) * 2)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-2{padding-left:calc(var(--spacing) * 2)}.text-\[14px\]{font-size:14px}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.shadow-\[0px_2px_4px_-1px_\#00000008\,0px_4px_6px_-1px_\#0000000D\]{--tw-shadow:0px 2px 4px -1px var(--tw-shadow-color,#00000008), 0px 4px 6px -1px var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-ease{syntax:"*";inherits:false}.rs-stepper{--rs-completed-color: #059669;--rs-pending-color: #9ca3af;--rs-active-color: #059669;--rs-line-color: #e5e7eb;--rs-half-step: 0%;--rs-progress: 0%;--rs-left-side-color: var(--rs-line-color);--rs-right-side-color: var(--rs-line-color);position:relative;width:100%;box-sizing:border-box}.rs-stepper *{box-sizing:border-box}.rs-stepper__scroll{width:100%;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;scrollbar-width:thin}.rs-stepper__row{position:relative;display:flex;align-items:flex-start;width:max-content;min-width:100%}.rs-stepper__track{position:absolute;top:26px;left:var(--rs-half-step);right:var(--rs-half-step);height:3px;background-color:transparent;transform:translateY(-1px);z-index:0}.rs-stepper__track:before{content:"";position:absolute;top:0;left:calc(-1 * (var(--rs-half-step)));right:calc(-1 * (var(--rs-half-step)));height:100%;background-image:linear-gradient(to right,var(--rs-left-side-color) 0,var(--rs-left-side-color) calc(var(--rs-half-step)),var(--rs-line-color) calc(var(--rs-half-step)),var(--rs-line-color) calc(100% - (var(--rs-half-step))),var(--rs-right-side-color) calc(100% - (var(--rs-half-step))),var(--rs-right-side-color) 100%);z-index:0}.rs-stepper__progress{position:absolute;top:0;left:0;width:var(--rs-progress);height:100%;background-color:var(--rs-completed-color);z-index:1;transition:width .3s ease,height .3s ease}.rs-stepper--vertical .rs-stepper__progress{position:relative;left:auto;width:100%}.rs-stepper__step{position:relative;z-index:1;flex:1 1 0;min-width:120px;display:flex;flex-direction:column;align-items:center;text-align:center;padding:4px 0}.rs-stepper__circle-wrap{position:relative;width:48px;height:48px;flex-shrink:0}.rs-stepper__circle{width:48px;height:48px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:600;background-color:#fff;border:2px solid var(--rs-line-color);color:var(--rs-pending-color);transition:border-color .2s ease,background-color .2s ease,box-shadow .2s ease,color .2s ease}.rs-stepper__circle--completed{background-color:var(--rs-completed-color);border-color:var(--rs-completed-color);color:#fff}.rs-stepper__circle--active{background-color:#fff;border-color:var(--rs-active-color);color:var(--rs-active-color);box-shadow:0 0 0 4px #d4e3e0}.rs-stepper__check{position:absolute;top:-2px;right:-2px;width:20px;height:20px;border-radius:50%;background-color:var(--rs-completed-color);border:2px solid #ffffff;display:flex;align-items:center;justify-content:center}.rs-stepper__check svg{width:10px;height:10px;display:block}.rs-stepper__title{margin-top:12px;font-size:12px;font-weight:700;line-height:1.3;color:#1e293b;max-width:140px}.rs-stepper__title--pending{color:var(--rs-pending-color);font-weight:600}.rs-stepper__title--active{color:var(--rs-active-color)}.rs-stepper__date,.rs-stepper__time{margin-top:2px;font-size:10px;line-height:1.3;color:#6b7280}@media(max-width:640px){.rs-stepper__step{min-width:96px}.rs-stepper__circle-wrap,.rs-stepper__circle{width:44px;height:44px}.rs-stepper__track{top:22px}.rs-stepper__circle{font-size:15px}.rs-stepper__title{font-size:12.5px;max-width:110px}.rs-stepper__date,.rs-stepper__time{font-size:11px}}.rs-stepper--vertical .rs-stepper__scroll{overflow-x:hidden;overflow-y:auto;-webkit-overflow-scrolling:touch}.rs-stepper--vertical .rs-stepper__row{flex-direction:column;align-items:flex-start;padding-left:2px;min-width:0;width:fit-content}.rs-stepper--vertical .rs-stepper__track{top:var(--rs-half-step);bottom:var(--rs-half-step);left:28px;right:auto;width:2px;height:auto;transform:translate(-1px)}.rs-stepper--vertical .rs-stepper__track:before{content:"";position:absolute;left:0;top:calc(-1 * (var(--rs-half-step) / 2));bottom:calc(-1 * (var(--rs-half-step) / 2));width:100%;background-image:linear-gradient(to bottom,var(--rs-left-side-color) 0,var(--rs-left-side-color) calc(var(--rs-half-step) / 2),var(--rs-line-color) calc(var(--rs-half-step) / 2),var(--rs-line-color) calc(100% - (var(--rs-half-step) / 2)),var(--rs-right-side-color) calc(100% - (var(--rs-half-step) / 2)),var(--rs-right-side-color) 100%);z-index:0}.rs-stepper--vertical .rs-stepper__progress{width:100%;height:var(--rs-progress)}.rs-stepper--vertical .rs-stepper__step{flex-direction:row;align-items:flex-start;text-align:left;width:100%;min-width:0;padding:0 0 32px}.rs-stepper--vertical .rs-stepper__step:last-child{padding-bottom:0}.rs-stepper--vertical .rs-stepper__title,.rs-stepper--vertical .rs-stepper__date,.rs-stepper--vertical .rs-stepper__time{margin-top:0;text-align:left;max-width:none}.rs-stepper--vertical .rs-stepper__title{margin-left:16px;padding-top:6px}.rs-stepper--vertical .rs-stepper__date,.rs-stepper--vertical .rs-stepper__time{margin-left:16px}@media(max-width:640px){.rs-stepper--vertical .rs-stepper__track{left:22px}.rs-stepper--responsive .rs-stepper__scroll,.rs-stepper--vertical .rs-stepper__scroll{max-height:min(70dvh,24rem);overflow-y:auto;overflow-x:hidden;padding-right:.25rem}}@media(max-width:640px){.rs-stepper--responsive .rs-stepper__row{flex-direction:column;align-items:flex-start;min-width:0;width:fit-content;padding-left:2px}.rs-stepper--responsive .rs-stepper__track{top:var(--rs-half-step);bottom:var(--rs-half-step);left:24px;right:auto;width:2px;height:auto;transform:translate(-1px)}.rs-stepper--responsive .rs-stepper__track:before{content:"";position:absolute;left:0;top:calc(-1 * (var(--rs-half-step) / 2));bottom:calc(-1 * (var(--rs-half-step) / 2));width:100%;background-image:linear-gradient(to bottom,var(--rs-left-side-color) 0,var(--rs-left-side-color) calc(var(--rs-half-step) / 2),var(--rs-line-color) calc(var(--rs-half-step) / 2),var(--rs-line-color) calc(100% - (var(--rs-half-step) / 2)),var(--rs-right-side-color) calc(100% - (var(--rs-half-step) / 2)),var(--rs-right-side-color) 100%);z-index:0}.rs-stepper--responsive .rs-stepper__progress{position:relative;left:auto;width:100%;height:var(--rs-progress)}.rs-stepper--responsive .rs-stepper__step{flex-direction:row;align-items:flex-start;text-align:left;width:100%;min-width:0;padding:0 0 32px}.rs-stepper--responsive .rs-stepper__step:last-child{padding-bottom:0}.rs-stepper--responsive .rs-stepper__title,.rs-stepper--responsive .rs-stepper__date,.rs-stepper--responsive .rs-stepper__time{margin-top:0;text-align:left;max-width:none}.rs-stepper--responsive .rs-stepper__title{margin-left:16px;padding-top:4px}.rs-stepper--responsive .rs-stepper__date,.rs-stepper--responsive .rs-stepper__time{margin-left:16px}}
@@ -1,24 +1,24 @@
1
- import { jsxs as p, jsx as e } from "react/jsx-runtime";
2
- import { useState as I } from "react";
3
- const E = ({
4
- tabs: o,
5
- defaultValue: c,
6
- value: a,
7
- onValueChange: i,
8
- className: b = "",
9
- tabListClassName: x = "",
10
- tabButtonClassName: h = "",
11
- contentClassName: g = "",
12
- showTabNumbers: f = !0,
13
- showContent: m = !0,
14
- animated: u = !0
1
+ import { jsxs as h, jsx as e } from "react/jsx-runtime";
2
+ import { useState as E, memo as T, useMemo as I } from "react";
3
+ const W = ({
4
+ tabs: i,
5
+ defaultValue: d,
6
+ value: s,
7
+ onValueChange: a,
8
+ className: o = "",
9
+ tabListClassName: n = "",
10
+ tabButtonClassName: b = "",
11
+ contentClassName: m = "",
12
+ showTabNumbers: r = !0,
13
+ showContent: l = !0,
14
+ animated: f = !0
15
15
  }) => {
16
- var l;
17
- const r = a !== void 0, [w, y] = I(
18
- c || ((l = o[0]) == null ? void 0 : l.id) || ""
19
- ), n = r ? a : w, F = (t) => {
20
- r || y(t), i == null || i(t);
21
- }, d = o.find((t) => t.id === n), v = {
16
+ var S;
17
+ const p = s !== void 0, [_, w] = E(
18
+ d || ((S = i[0]) == null ? void 0 : S.id) || ""
19
+ ), v = p ? s : _, y = (t) => {
20
+ p || w(t), a == null || a(t);
21
+ }, u = i.find((t) => t.id === v), F = {
22
22
  display: "flex",
23
23
  alignItems: "flex-end",
24
24
  borderBottom: "1px solid #059669",
@@ -26,8 +26,7 @@ const E = ({
26
26
  top: 0,
27
27
  zIndex: 100,
28
28
  flexShrink: 0
29
- // padding + gap now come from .ctabs-list (responsive)
30
- }, T = {
29
+ }, k = {
31
30
  display: "flex",
32
31
  alignItems: "center",
33
32
  fontFamily: "inherit",
@@ -36,8 +35,7 @@ const E = ({
36
35
  outline: "none",
37
36
  transition: "all .2s ease",
38
37
  position: "relative"
39
- // padding + font-size + gap now come from .ctabs-btn (responsive)
40
- }, k = {
38
+ }, c = {
41
39
  background: "#E8F7F1",
42
40
  color: "#059669",
43
41
  fontWeight: 700,
@@ -50,7 +48,7 @@ const E = ({
50
48
  borderTopRightRadius: 8,
51
49
  marginBottom: -1,
52
50
  zIndex: 2
53
- }, R = {
51
+ }, g = {
54
52
  background: "transparent",
55
53
  color: "#2D3748",
56
54
  borderTop: "3px solid transparent",
@@ -59,33 +57,33 @@ const E = ({
59
57
  borderBottom: "1px solid transparent",
60
58
  borderTopLeftRadius: 8,
61
59
  borderTopRightRadius: 8
62
- }, S = {
63
- background: "#FFFFFF",
60
+ }, x = {
61
+ background: "#ECFDF5",
64
62
  color: "#059669",
65
63
  fontWeight: 700,
66
64
  border: "1px solid #059669"
67
65
  }, z = {
68
66
  background: "#FFFFFF",
69
- color: "#374151",
67
+ color: "#1F2937",
70
68
  fontWeight: "500",
71
- border: "1px solid #D1D5DB"
72
- }, B = {
69
+ border: "1px solid #1F2937"
70
+ }, R = {
73
71
  background: "#FFFFFF",
74
72
  border: "1px solid #D9E1E7",
75
73
  borderTop: "none",
76
74
  borderBottomLeftRadius: 12,
77
75
  borderBottomRightRadius: 12,
78
76
  boxShadow: "0 2px 6px rgba(0,0,0,.05)",
79
- transition: u ? "opacity .2s ease" : void 0,
77
+ transition: f ? "opacity .2s ease" : void 0,
80
78
  opacity: 1,
81
79
  flex: 1,
82
80
  overflowY: "auto",
83
81
  minHeight: 0
84
82
  };
85
- return /* @__PURE__ */ p(
83
+ return /* @__PURE__ */ h(
86
84
  "div",
87
85
  {
88
- className: b,
86
+ className: o,
89
87
  style: {
90
88
  display: "flex",
91
89
  flexDirection: "column",
@@ -107,7 +105,7 @@ const E = ({
107
105
 
108
106
  .ctabs-btn {
109
107
  padding: 4px 20px;
110
- font-size: 14px;
108
+ font-size: 13px;
111
109
  font-weight: 500;
112
110
  gap: 8px;
113
111
  white-space: nowrap;
@@ -118,7 +116,7 @@ const E = ({
118
116
  width: 20px;
119
117
  height: 20px;
120
118
  border-radius: 4px;
121
- font-size: 12px;
119
+ font-size: 10px;
122
120
  font-weight: 600;
123
121
  flex-shrink: 0;
124
122
  display: flex;
@@ -173,31 +171,31 @@ const E = ({
173
171
  /* @__PURE__ */ e(
174
172
  "div",
175
173
  {
176
- style: v,
177
- className: `ctabs-list ${x}`,
178
- children: o.map((t, D) => {
179
- const s = n === t.id;
180
- return /* @__PURE__ */ p(
174
+ style: F,
175
+ className: `ctabs-list ${n}`,
176
+ children: i.map((t, L) => {
177
+ const N = v === t.id;
178
+ return /* @__PURE__ */ h(
181
179
  "button",
182
180
  {
183
181
  role: "tab",
184
- "aria-selected": s,
182
+ "aria-selected": N,
185
183
  disabled: t.disabled,
186
- onClick: () => !t.disabled && F(t.id),
184
+ onClick: () => !t.disabled && y(t.id),
187
185
  style: {
188
- ...T,
189
- ...s ? k : R,
186
+ ...k,
187
+ ...N ? c : g,
190
188
  opacity: t.disabled ? 0.5 : 1,
191
189
  cursor: t.disabled ? "not-allowed" : "pointer"
192
190
  },
193
- className: `ctabs-btn ${h}`,
191
+ className: `ctabs-btn ${b}`,
194
192
  children: [
195
- f && /* @__PURE__ */ e(
193
+ r && /* @__PURE__ */ e(
196
194
  "span",
197
195
  {
198
196
  className: "ctabs-badge",
199
- style: s ? S : z,
200
- children: D + 1
197
+ style: N ? x : z,
198
+ children: L + 1
201
199
  }
202
200
  ),
203
201
  t.icon,
@@ -209,11 +207,82 @@ const E = ({
209
207
  })
210
208
  }
211
209
  ),
212
- m && d && /* @__PURE__ */ e("div", { style: B, className: g, children: d.content })
210
+ l && u && /* @__PURE__ */ e("div", { style: R, className: m, children: u.content })
213
211
  ]
214
212
  }
215
213
  );
216
- };
214
+ }, C = () => /* @__PURE__ */ e("svg", { viewBox: "0 0 12 12", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ e(
215
+ "path",
216
+ {
217
+ d: "M2 6.2L4.6 8.8L10 3",
218
+ stroke: "#ffffff",
219
+ strokeWidth: "1.6",
220
+ strokeLinecap: "round",
221
+ strokeLinejoin: "round"
222
+ }
223
+ ) }), B = T(({ computed: i, showTime: d }) => {
224
+ const { step: s, index: a, status: o } = i, n = [
225
+ "rs-stepper__circle",
226
+ o === "completed" ? "rs-stepper__circle--completed" : "",
227
+ o === "active" ? "rs-stepper__circle--active" : ""
228
+ ].filter(Boolean).join(" "), b = [
229
+ "rs-stepper__title",
230
+ o === "pending" ? "rs-stepper__title--pending" : "",
231
+ o === "active" ? "rs-stepper__title--active" : ""
232
+ ].filter(Boolean).join(" ");
233
+ return /* @__PURE__ */ h("div", { className: "rs-stepper__step", children: [
234
+ /* @__PURE__ */ h("div", { className: "rs-stepper__circle-wrap", children: [
235
+ /* @__PURE__ */ e("div", { className: n, children: a !== 0 ? a : null }),
236
+ o === "completed" && /* @__PURE__ */ e("span", { className: "rs-stepper__check", "aria-hidden": "true", children: /* @__PURE__ */ e(C, {}) })
237
+ ] }),
238
+ /* @__PURE__ */ e("div", { className: b, children: s.title }),
239
+ s.date && /* @__PURE__ */ e("div", { className: "rs-stepper__date", children: s.date }),
240
+ d && s.time && /* @__PURE__ */ e("div", { className: "rs-stepper__time", children: s.time })
241
+ ] });
242
+ });
243
+ B.displayName = "StepCircle";
244
+ const M = ({
245
+ steps: i,
246
+ currentStep: d,
247
+ completedColor: s = "#059669",
248
+ pendingColor: a = "#9ca3af",
249
+ activeColor: o = "#059669",
250
+ lineColor: n = "#e5e7eb",
251
+ showTime: b = !0,
252
+ orientation: m = "responsive"
253
+ }) => {
254
+ const r = i.length, l = d > r, f = Math.max(1, Math.min(d, r)), p = l ? Math.max(0, r - 1) : Math.max(0, Math.min(r - 1, f - 1)), _ = I(
255
+ () => i.map((c, g) => {
256
+ let x = "pending";
257
+ return l || g < p ? x = "completed" : g === p && (x = "active"), { step: c, index: g, status: x };
258
+ }),
259
+ [i, p, l]
260
+ ), w = r > 0 ? 100 / r / 2 : 0, v = r > 1 ? l ? 100 : p / (r - 1) * 100 : 0, y = l || f > 1 ? s : n, u = l || f > r ? s : n, F = {
261
+ "--rs-completed-color": s,
262
+ "--rs-pending-color": a,
263
+ "--rs-active-color": o,
264
+ "--rs-line-color": n,
265
+ "--rs-half-step": `${w}%`,
266
+ "--rs-progress": `${v}%`,
267
+ "--rs-left-side-color": y,
268
+ "--rs-right-side-color": u
269
+ };
270
+ return r === 0 ? null : /* @__PURE__ */ h("div", { className: "border border-[#E5E7EB] py-2 mx-2 rounded-lg bg-[#F9FAFB] shadow-[0px_2px_4px_-1px_#00000008,0px_4px_6px_-1px_#0000000D]", children: [
271
+ /* @__PURE__ */ e("div", { className: "pl-2 pt-2 pb-3 text-[14px] font-bold", children: "Workflow Progress" }),
272
+ /* @__PURE__ */ e("div", { className: `rs-stepper ${m === "vertical" ? "rs-stepper--vertical" : m === "horizontal" ? "rs-stepper--horizontal" : "rs-stepper--responsive"}`, style: F, children: /* @__PURE__ */ e("div", { className: "rs-stepper__scroll", children: /* @__PURE__ */ h("div", { className: "rs-stepper__row", children: [
273
+ /* @__PURE__ */ e("div", { className: "rs-stepper__track", children: /* @__PURE__ */ e("div", { className: "rs-stepper__progress" }) }),
274
+ _.map((c) => /* @__PURE__ */ e(
275
+ B,
276
+ {
277
+ computed: c,
278
+ showTime: b
279
+ },
280
+ c.step.id
281
+ ))
282
+ ] }) }) })
283
+ ] });
284
+ }, $ = T(M);
217
285
  export {
218
- E as CustomTabs
286
+ W as CustomTabs,
287
+ $ as Stepper
219
288
  };
@@ -1,23 +1,4 @@
1
1
  import React from "react";
2
- export interface TabItem {
3
- id: string;
4
- label: string;
5
- content?: React.ReactNode;
6
- disabled?: boolean;
7
- icon?: React.ReactNode;
8
- }
9
- export interface CustomTabsProps {
10
- tabs: TabItem[];
11
- defaultValue?: string;
12
- value?: string;
13
- onValueChange?: (value: string) => void;
14
- className?: string;
15
- tabListClassName?: string;
16
- tabButtonClassName?: string;
17
- contentClassName?: string;
18
- showTabNumbers?: boolean;
19
- showContent?: boolean;
20
- animated?: boolean;
21
- }
2
+ import type { CustomTabsProps } from "../types/tabs";
22
3
  declare const CustomTabs: React.FC<CustomTabsProps>;
23
4
  export default CustomTabs;
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ import "./Stepper.css";
3
+ import { StepperProps } from "../types/stepper";
4
+ declare const _default: React.NamedExoticComponent<StepperProps>;
5
+ export default _default;
@@ -1,3 +1,5 @@
1
1
  import "./index.css";
2
2
  export { default as CustomTabs } from "./components/CustomTabs";
3
- export type { TabItem, CustomTabsProps, } from "./components/CustomTabs";
3
+ export type { TabItem, CustomTabsProps, } from "./types/tabs";
4
+ export { default as Stepper } from "./components/Stepper";
5
+ export type { StepItem, StepperProps } from "./types/stepper";
@@ -0,0 +1,35 @@
1
+ export interface StepItem {
2
+ /** Unique identifier for the step */
3
+ id: string;
4
+ /** Label shown under the circle */
5
+ title: string;
6
+ /** Optional date shown under the title (e.g. "21 May 2026") */
7
+ date?: string;
8
+ /** Optional time shown under the date (e.g. "09:40 AM") */
9
+ time?: string;
10
+ }
11
+ export interface StepperProps {
12
+ /** Ordered list of steps to render */
13
+ steps: StepItem[];
14
+ /**
15
+ * Index of the current (active) step, 1-based, matching the numbering
16
+ * shown inside the circles. Steps with index < currentStep are treated
17
+ * as completed, the step === currentStep is treated as active/current,
18
+ * and steps > currentStep are treated as upcoming.
19
+ *
20
+ * Example: currentStep={3} means step 1 and 2 are completed, step 3 is
21
+ * active, and the rest are upcoming.
22
+ */
23
+ currentStep: number;
24
+ /** Fill color for completed step circles and their connecting lines. Default: #059669 */
25
+ completedColor?: string;
26
+ /** Color for upcoming step circles, numbers, titles and connecting lines. Default: #9CA3AF */
27
+ pendingColor?: string;
28
+ /** Border/number/title color for the current/active step. Default: #059669 */
29
+ activeColor?: string;
30
+ /** Base color for the connecting line track behind the circles. Default: #E5E7EB */
31
+ lineColor?: string;
32
+ /** Whether to render the optional `time` field under `date`. Default: true */
33
+ showTime?: boolean;
34
+ orientation?: string;
35
+ }
@@ -0,0 +1,21 @@
1
+ import React from "react";
2
+ export interface TabItem {
3
+ id: string;
4
+ label: string;
5
+ content?: React.ReactNode;
6
+ disabled?: boolean;
7
+ icon?: React.ReactNode;
8
+ }
9
+ export interface CustomTabsProps {
10
+ tabs: TabItem[];
11
+ defaultValue?: string;
12
+ value?: string;
13
+ onValueChange?: (value: string) => void;
14
+ className?: string;
15
+ tabListClassName?: string;
16
+ tabButtonClassName?: string;
17
+ contentClassName?: string;
18
+ showTabNumbers?: boolean;
19
+ showContent?: boolean;
20
+ animated?: boolean;
21
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aravint-ui-navigation",
3
- "version": "1.0.21",
3
+ "version": "1.0.22",
4
4
  "main": "dist/navigation.cjs.js",
5
5
  "module": "dist/navigation.es.js",
6
6
  "types": "dist/types/index.d.ts",