@tribepad/themis 1.0.6 → 1.0.7
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/elements/Tabs/Tabs.d.ts +2 -2
- package/dist/elements/Tabs/Tabs.d.ts.map +1 -1
- package/dist/elements/Tabs/Tabs.types.d.ts +3 -0
- package/dist/elements/Tabs/Tabs.types.d.ts.map +1 -1
- package/dist/elements/Tabs/index.js +1 -1
- package/dist/elements/Tabs/index.js.map +1 -1
- package/dist/elements/Tabs/index.mjs +1 -1
- package/dist/elements/Tabs/index.mjs.map +1 -1
- package/dist/elements/index.js +1 -1
- package/dist/elements/index.js.map +1 -1
- package/dist/elements/index.mjs +1 -1
- package/dist/elements/index.mjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -15
- package/src/elements/Tabs/Tabs.stories.tsx +231 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tribepad/themis",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "Accessible React component library built on React Aria primitives",
|
|
5
5
|
"author": "Tribepad <mbasford@tribepad.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -130,38 +130,38 @@
|
|
|
130
130
|
"react-aria": "^3.35.0",
|
|
131
131
|
"react-aria-components": "^1.5.0",
|
|
132
132
|
"react-stately": "^3.33.0",
|
|
133
|
-
"tailwind-merge": "^3.
|
|
133
|
+
"tailwind-merge": "^3.5.0"
|
|
134
134
|
},
|
|
135
135
|
"devDependencies": {
|
|
136
|
-
"@eslint/js": "^9.
|
|
136
|
+
"@eslint/js": "^9.39.3",
|
|
137
137
|
"@size-limit/preset-small-lib": "^11.0.0",
|
|
138
|
-
"@storybook/addon-a11y": "^10.2.
|
|
139
|
-
"@storybook/react-vite": "^10.2.
|
|
140
|
-
"@tailwindcss/vite": "^4.
|
|
138
|
+
"@storybook/addon-a11y": "^10.2.10",
|
|
139
|
+
"@storybook/react-vite": "^10.2.10",
|
|
140
|
+
"@tailwindcss/vite": "^4.2.0",
|
|
141
141
|
"@testing-library/jest-dom": "^6.0.0",
|
|
142
142
|
"@testing-library/react": "^16.0.0",
|
|
143
143
|
"@testing-library/user-event": "^14.0.0",
|
|
144
|
-
"@types/node": "^25.
|
|
145
|
-
"@types/react": "^19.
|
|
144
|
+
"@types/node": "^25.3.5",
|
|
145
|
+
"@types/react": "^19.2.14",
|
|
146
146
|
"@types/react-dom": "^19.0.0",
|
|
147
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
148
|
-
"@typescript-eslint/parser": "^8.
|
|
149
|
-
"@vitejs/plugin-react": "^5.1.
|
|
147
|
+
"@typescript-eslint/eslint-plugin": "^8.56.1",
|
|
148
|
+
"@typescript-eslint/parser": "^8.56.1",
|
|
149
|
+
"@vitejs/plugin-react": "^5.1.4",
|
|
150
150
|
"@vitest/coverage-v8": "^4.0.0",
|
|
151
151
|
"eslint": "^9.0.0",
|
|
152
152
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
153
153
|
"globals": "^17.3.0",
|
|
154
|
-
"happy-dom": "^20.
|
|
154
|
+
"happy-dom": "^20.7.0",
|
|
155
155
|
"jest-axe": "^10.0.0",
|
|
156
|
-
"jsdom": "^28.
|
|
156
|
+
"jsdom": "^28.1.0",
|
|
157
157
|
"lucide-react": ">=0.400.0",
|
|
158
158
|
"react": "^19.0.0",
|
|
159
159
|
"react-dom": "^19.0.0",
|
|
160
160
|
"size-limit": "^11.0.0",
|
|
161
|
-
"storybook": "^10.2.
|
|
161
|
+
"storybook": "^10.2.10",
|
|
162
162
|
"tsup": "^8.0.0",
|
|
163
163
|
"tsx": "^4.0.0",
|
|
164
|
-
"typescript": "^5.
|
|
164
|
+
"typescript": "^5.9.3",
|
|
165
165
|
"vitest": "^4.0.18",
|
|
166
166
|
"zod": "^4.3.6"
|
|
167
167
|
},
|
|
@@ -26,8 +26,8 @@ const meta = {
|
|
|
26
26
|
argTypes: {
|
|
27
27
|
variant: {
|
|
28
28
|
control: 'select',
|
|
29
|
-
options: ['default', 'block'],
|
|
30
|
-
description: 'Visual variant: underline (default)
|
|
29
|
+
options: ['default', 'block', 'stepper'],
|
|
30
|
+
description: 'Visual variant: underline (default), block/pill, or stepper (numbered steps)',
|
|
31
31
|
},
|
|
32
32
|
orientation: {
|
|
33
33
|
control: 'select',
|
|
@@ -131,6 +131,235 @@ export const Block: Story = {
|
|
|
131
131
|
),
|
|
132
132
|
};
|
|
133
133
|
|
|
134
|
+
// ============================================================================
|
|
135
|
+
// Stepper Variant Stories
|
|
136
|
+
// ============================================================================
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Stepper: Numbered step circles with connecting lines.
|
|
140
|
+
* Completed steps show a checkmark, the active step is highlighted.
|
|
141
|
+
*/
|
|
142
|
+
export const Stepper: Story = {
|
|
143
|
+
render: () => (
|
|
144
|
+
<Tabs variant="stepper" defaultSelectedKey="form" className="w-[600px]">
|
|
145
|
+
<TabList aria-label="Blueprint setup steps">
|
|
146
|
+
<Tab id="details">Job Details</Tab>
|
|
147
|
+
<Tab id="form">Application Form</Tab>
|
|
148
|
+
<Tab id="statuses">Statuses</Tab>
|
|
149
|
+
<Tab id="journeys">Journeys</Tab>
|
|
150
|
+
</TabList>
|
|
151
|
+
<TabPanel id="details">
|
|
152
|
+
<div className="p-4">
|
|
153
|
+
<h3 className="text-lg font-semibold mb-2">Job Details</h3>
|
|
154
|
+
<p className="text-sm text-[var(--muted-foreground)]">
|
|
155
|
+
Configure the basic job information and requirements.
|
|
156
|
+
</p>
|
|
157
|
+
</div>
|
|
158
|
+
</TabPanel>
|
|
159
|
+
<TabPanel id="form">
|
|
160
|
+
<div className="p-4">
|
|
161
|
+
<h3 className="text-lg font-semibold mb-2">Application Form</h3>
|
|
162
|
+
<p className="text-sm text-[var(--muted-foreground)]">
|
|
163
|
+
Build the candidate application form with fields and sections.
|
|
164
|
+
</p>
|
|
165
|
+
</div>
|
|
166
|
+
</TabPanel>
|
|
167
|
+
<TabPanel id="statuses">
|
|
168
|
+
<div className="p-4">
|
|
169
|
+
<h3 className="text-lg font-semibold mb-2">Statuses</h3>
|
|
170
|
+
<p className="text-sm text-[var(--muted-foreground)]">
|
|
171
|
+
Define the status workflow for applications.
|
|
172
|
+
</p>
|
|
173
|
+
</div>
|
|
174
|
+
</TabPanel>
|
|
175
|
+
<TabPanel id="journeys">
|
|
176
|
+
<div className="p-4">
|
|
177
|
+
<h3 className="text-lg font-semibold mb-2">Journeys</h3>
|
|
178
|
+
<p className="text-sm text-[var(--muted-foreground)]">
|
|
179
|
+
Configure candidate journeys for each status.
|
|
180
|
+
</p>
|
|
181
|
+
</div>
|
|
182
|
+
</TabPanel>
|
|
183
|
+
</Tabs>
|
|
184
|
+
),
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* StepperFirstStep: Stepper with the first step active (no completed steps).
|
|
189
|
+
*/
|
|
190
|
+
export const StepperFirstStep: Story = {
|
|
191
|
+
render: () => (
|
|
192
|
+
<Tabs variant="stepper" defaultSelectedKey="details" className="w-[600px]">
|
|
193
|
+
<TabList aria-label="Setup wizard">
|
|
194
|
+
<Tab id="details">Details</Tab>
|
|
195
|
+
<Tab id="form">Form</Tab>
|
|
196
|
+
<Tab id="statuses">Statuses</Tab>
|
|
197
|
+
<Tab id="journeys">Journeys</Tab>
|
|
198
|
+
</TabList>
|
|
199
|
+
<TabPanel id="details">
|
|
200
|
+
<div className="p-4">
|
|
201
|
+
<h3 className="text-lg font-semibold mb-2">Step 1: Details</h3>
|
|
202
|
+
<p className="text-sm text-[var(--muted-foreground)]">
|
|
203
|
+
First step is active. No completed steps yet.
|
|
204
|
+
</p>
|
|
205
|
+
</div>
|
|
206
|
+
</TabPanel>
|
|
207
|
+
<TabPanel id="form">
|
|
208
|
+
<div className="p-4">Step 2 content</div>
|
|
209
|
+
</TabPanel>
|
|
210
|
+
<TabPanel id="statuses">
|
|
211
|
+
<div className="p-4">Step 3 content</div>
|
|
212
|
+
</TabPanel>
|
|
213
|
+
<TabPanel id="journeys">
|
|
214
|
+
<div className="p-4">Step 4 content</div>
|
|
215
|
+
</TabPanel>
|
|
216
|
+
</Tabs>
|
|
217
|
+
),
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* StepperLastStep: Stepper with the last step active (all previous completed).
|
|
222
|
+
*/
|
|
223
|
+
export const StepperLastStep: Story = {
|
|
224
|
+
render: () => (
|
|
225
|
+
<Tabs variant="stepper" defaultSelectedKey="journeys" className="w-[600px]">
|
|
226
|
+
<TabList aria-label="Setup wizard">
|
|
227
|
+
<Tab id="details">Details</Tab>
|
|
228
|
+
<Tab id="form">Form</Tab>
|
|
229
|
+
<Tab id="statuses">Statuses</Tab>
|
|
230
|
+
<Tab id="journeys">Journeys</Tab>
|
|
231
|
+
</TabList>
|
|
232
|
+
<TabPanel id="details">
|
|
233
|
+
<div className="p-4">Step 1 content</div>
|
|
234
|
+
</TabPanel>
|
|
235
|
+
<TabPanel id="form">
|
|
236
|
+
<div className="p-4">Step 2 content</div>
|
|
237
|
+
</TabPanel>
|
|
238
|
+
<TabPanel id="statuses">
|
|
239
|
+
<div className="p-4">Step 3 content</div>
|
|
240
|
+
</TabPanel>
|
|
241
|
+
<TabPanel id="journeys">
|
|
242
|
+
<div className="p-4">
|
|
243
|
+
<h3 className="text-lg font-semibold mb-2">Step 4: Journeys</h3>
|
|
244
|
+
<p className="text-sm text-[var(--muted-foreground)]">
|
|
245
|
+
All previous steps show checkmarks as completed.
|
|
246
|
+
</p>
|
|
247
|
+
</div>
|
|
248
|
+
</TabPanel>
|
|
249
|
+
</Tabs>
|
|
250
|
+
),
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* StepperControlled: Stepper with external step navigation controls.
|
|
255
|
+
*/
|
|
256
|
+
export const StepperControlled: Story = {
|
|
257
|
+
render: function StepperControlledDemo() {
|
|
258
|
+
const steps = ['details', 'form', 'statuses', 'journeys'] as const;
|
|
259
|
+
const [selected, setSelected] = useState<Key>('details');
|
|
260
|
+
const currentIndex = steps.indexOf(selected as typeof steps[number]);
|
|
261
|
+
|
|
262
|
+
return (
|
|
263
|
+
<div className="w-[600px]">
|
|
264
|
+
<Tabs variant="stepper" selectedKey={selected} onSelectionChange={setSelected}>
|
|
265
|
+
<TabList aria-label="Controlled stepper">
|
|
266
|
+
<Tab id="details">Details</Tab>
|
|
267
|
+
<Tab id="form">Form</Tab>
|
|
268
|
+
<Tab id="statuses">Statuses</Tab>
|
|
269
|
+
<Tab id="journeys">Journeys</Tab>
|
|
270
|
+
</TabList>
|
|
271
|
+
<TabPanel id="details">
|
|
272
|
+
<div className="p-4">Step 1: Configure details</div>
|
|
273
|
+
</TabPanel>
|
|
274
|
+
<TabPanel id="form">
|
|
275
|
+
<div className="p-4">Step 2: Build the form</div>
|
|
276
|
+
</TabPanel>
|
|
277
|
+
<TabPanel id="statuses">
|
|
278
|
+
<div className="p-4">Step 3: Define statuses</div>
|
|
279
|
+
</TabPanel>
|
|
280
|
+
<TabPanel id="journeys">
|
|
281
|
+
<div className="p-4">Step 4: Set up journeys</div>
|
|
282
|
+
</TabPanel>
|
|
283
|
+
</Tabs>
|
|
284
|
+
<div className="flex justify-between mt-4 px-4">
|
|
285
|
+
<button
|
|
286
|
+
onClick={() => currentIndex > 0 && setSelected(steps[currentIndex - 1])}
|
|
287
|
+
disabled={currentIndex === 0}
|
|
288
|
+
className="px-4 py-2 text-sm rounded-md bg-[var(--secondary)] text-[var(--secondary-foreground)] disabled:opacity-50"
|
|
289
|
+
>
|
|
290
|
+
Previous
|
|
291
|
+
</button>
|
|
292
|
+
<button
|
|
293
|
+
onClick={() => currentIndex < steps.length - 1 && setSelected(steps[currentIndex + 1])}
|
|
294
|
+
disabled={currentIndex === steps.length - 1}
|
|
295
|
+
className="px-4 py-2 text-sm rounded-md bg-[var(--primary)] text-[var(--primary-foreground)] disabled:opacity-50"
|
|
296
|
+
>
|
|
297
|
+
Next
|
|
298
|
+
</button>
|
|
299
|
+
</div>
|
|
300
|
+
</div>
|
|
301
|
+
);
|
|
302
|
+
},
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* StepperWithDisabledTabs: Stepper with some tabs disabled.
|
|
307
|
+
*/
|
|
308
|
+
export const StepperWithDisabledTabs: Story = {
|
|
309
|
+
render: () => (
|
|
310
|
+
<Tabs variant="stepper" defaultSelectedKey="form" disabledKeys={['journeys']} className="w-[600px]">
|
|
311
|
+
<TabList aria-label="Steps with disabled">
|
|
312
|
+
<Tab id="details">Details</Tab>
|
|
313
|
+
<Tab id="form">Form</Tab>
|
|
314
|
+
<Tab id="statuses">Statuses</Tab>
|
|
315
|
+
<Tab id="journeys">Journeys</Tab>
|
|
316
|
+
</TabList>
|
|
317
|
+
<TabPanel id="details">
|
|
318
|
+
<div className="p-4">Step 1 content</div>
|
|
319
|
+
</TabPanel>
|
|
320
|
+
<TabPanel id="form">
|
|
321
|
+
<div className="p-4">
|
|
322
|
+
<h3 className="text-lg font-semibold mb-2">Step 2: Form</h3>
|
|
323
|
+
<p className="text-sm text-[var(--muted-foreground)]">
|
|
324
|
+
The "Journeys" step is disabled and cannot be selected.
|
|
325
|
+
</p>
|
|
326
|
+
</div>
|
|
327
|
+
</TabPanel>
|
|
328
|
+
<TabPanel id="statuses">
|
|
329
|
+
<div className="p-4">Step 3 content</div>
|
|
330
|
+
</TabPanel>
|
|
331
|
+
<TabPanel id="journeys">
|
|
332
|
+
<div className="p-4">Step 4 content (disabled)</div>
|
|
333
|
+
</TabPanel>
|
|
334
|
+
</Tabs>
|
|
335
|
+
),
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* StepperTwoSteps: Minimal stepper with only 2 steps.
|
|
340
|
+
*/
|
|
341
|
+
export const StepperTwoSteps: Story = {
|
|
342
|
+
render: () => (
|
|
343
|
+
<Tabs variant="stepper" defaultSelectedKey="review" className="w-[400px]">
|
|
344
|
+
<TabList aria-label="Two-step process">
|
|
345
|
+
<Tab id="configure">Configure</Tab>
|
|
346
|
+
<Tab id="review">Review</Tab>
|
|
347
|
+
</TabList>
|
|
348
|
+
<TabPanel id="configure">
|
|
349
|
+
<div className="p-4">Configuration step content</div>
|
|
350
|
+
</TabPanel>
|
|
351
|
+
<TabPanel id="review">
|
|
352
|
+
<div className="p-4">
|
|
353
|
+
<h3 className="text-lg font-semibold mb-2">Review</h3>
|
|
354
|
+
<p className="text-sm text-[var(--muted-foreground)]">
|
|
355
|
+
The first step shows a checkmark. This is the active step.
|
|
356
|
+
</p>
|
|
357
|
+
</div>
|
|
358
|
+
</TabPanel>
|
|
359
|
+
</Tabs>
|
|
360
|
+
),
|
|
361
|
+
};
|
|
362
|
+
|
|
134
363
|
// ============================================================================
|
|
135
364
|
// Orientation Stories
|
|
136
365
|
// ============================================================================
|