aravint-ui-navigation 1.0.21 → 1.0.24

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 +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-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;--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}.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,)}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.border{border-style:var(--tw-border-style);border-width:1px}.bg-gray-50{background-color:var(--color-gray-50)}.bg-white{background-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-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-ease{syntax:"*";inherits:false}
@@ -26,7 +26,6 @@ const E = ({
26
26
  top: 0,
27
27
  zIndex: 100,
28
28
  flexShrink: 0
29
- // padding + gap now come from .ctabs-list (responsive)
30
29
  }, T = {
31
30
  display: "flex",
32
31
  alignItems: "center",
@@ -36,7 +35,6 @@ 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
38
  }, k = {
41
39
  background: "#E8F7F1",
42
40
  color: "#059669",
@@ -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;
@@ -1,3 +1,3 @@
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";
@@ -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.24",
4
4
  "main": "dist/navigation.cjs.js",
5
5
  "module": "dist/navigation.es.js",
6
6
  "types": "dist/types/index.d.ts",