@tribepad/themis 1.2.0 → 1.3.0

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.
Files changed (37) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/elements/PageTitle/PageTitle.d.ts +33 -0
  3. package/dist/elements/PageTitle/PageTitle.d.ts.map +1 -0
  4. package/dist/elements/PageTitle/PageTitle.styles.d.ts +33 -0
  5. package/dist/elements/PageTitle/PageTitle.styles.d.ts.map +1 -0
  6. package/dist/elements/PageTitle/PageTitle.types.d.ts +181 -0
  7. package/dist/elements/PageTitle/PageTitle.types.d.ts.map +1 -0
  8. package/dist/elements/PageTitle/PageTitleActions.d.ts +13 -0
  9. package/dist/elements/PageTitle/PageTitleActions.d.ts.map +1 -0
  10. package/dist/elements/PageTitle/PageTitleBreadcrumbs.d.ts +13 -0
  11. package/dist/elements/PageTitle/PageTitleBreadcrumbs.d.ts.map +1 -0
  12. package/dist/elements/PageTitle/PageTitleContext.d.ts +7 -0
  13. package/dist/elements/PageTitle/PageTitleContext.d.ts.map +1 -0
  14. package/dist/elements/PageTitle/PageTitleDescription.d.ts +9 -0
  15. package/dist/elements/PageTitle/PageTitleDescription.d.ts.map +1 -0
  16. package/dist/elements/PageTitle/PageTitleHeading.d.ts +12 -0
  17. package/dist/elements/PageTitle/PageTitleHeading.d.ts.map +1 -0
  18. package/dist/elements/PageTitle/PageTitleTabs.d.ts +11 -0
  19. package/dist/elements/PageTitle/PageTitleTabs.d.ts.map +1 -0
  20. package/dist/elements/PageTitle/index.d.ts +11 -0
  21. package/dist/elements/PageTitle/index.d.ts.map +1 -0
  22. package/dist/elements/PageTitle/index.js +3 -0
  23. package/dist/elements/PageTitle/index.js.map +1 -0
  24. package/dist/elements/PageTitle/index.mjs +3 -0
  25. package/dist/elements/PageTitle/index.mjs.map +1 -0
  26. package/dist/elements/index.d.ts +2 -0
  27. package/dist/elements/index.d.ts.map +1 -1
  28. package/dist/elements/index.js +1 -1
  29. package/dist/elements/index.js.map +1 -1
  30. package/dist/elements/index.mjs +1 -1
  31. package/dist/elements/index.mjs.map +1 -1
  32. package/dist/index.js +2 -2
  33. package/dist/index.js.map +1 -1
  34. package/dist/index.mjs +2 -2
  35. package/dist/index.mjs.map +1 -1
  36. package/package.json +6 -1
  37. package/src/elements/PageTitle/PageTitle.stories.tsx +288 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tribepad/themis",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Accessible React component library built on React Aria primitives",
5
5
  "author": "Tribepad <mbasford@tribepad.com>",
6
6
  "license": "MIT",
@@ -250,6 +250,11 @@
250
250
  "name": "Sidebar only",
251
251
  "path": "dist/elements/Sidebar/index.mjs",
252
252
  "limit": "35 KB"
253
+ },
254
+ {
255
+ "name": "PageTitle only",
256
+ "path": "dist/elements/PageTitle/index.mjs",
257
+ "limit": "60 KB"
253
258
  }
254
259
  ],
255
260
  "keywords": [
@@ -0,0 +1,288 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { Plus } from 'lucide-react';
3
+ import { Button } from '../Button';
4
+ import { PageTitle } from './PageTitle';
5
+
6
+ const BREADCRUMB_ITEMS = [
7
+ { id: 'home', label: 'Dashboard', href: '/' },
8
+ { id: 'forms', label: 'Forms' },
9
+ ];
10
+
11
+ const LONG_BREADCRUMB_ITEMS = [
12
+ { id: 'home', label: 'Dashboard', href: '/' },
13
+ { id: 'bp', label: 'Blueprint', href: '/blueprint' },
14
+ { id: 'fields', label: 'Field library' },
15
+ ];
16
+
17
+ const meta = {
18
+ title: 'Elements/PageTitle',
19
+ component: PageTitle,
20
+ parameters: {
21
+ layout: 'fullscreen',
22
+ docs: {
23
+ description: {
24
+ component:
25
+ 'Accessible page header for listing and landing pages. Two variants — `default` (light card) and `feature` (primary gradient). Compound sub-components: `PageTitle.Breadcrumbs`, `PageTitle.Heading`, `PageTitle.Description`, `PageTitle.Actions`, `PageTitle.Tabs`. Renders as a semantic `<header>` landmark.',
26
+ },
27
+ },
28
+ },
29
+ tags: ['autodocs'],
30
+ } satisfies Meta<typeof PageTitle>;
31
+
32
+ export default meta;
33
+ type Story = StoryObj<typeof meta>;
34
+
35
+ // =============================================================================
36
+ // Default variant
37
+ // =============================================================================
38
+
39
+ export const Default: Story = {
40
+ render: () => (
41
+ <PageTitle variant="default">
42
+ <PageTitle.Breadcrumbs items={BREADCRUMB_ITEMS} />
43
+ <PageTitle.Heading>Forms</PageTitle.Heading>
44
+ <PageTitle.Description>
45
+ Build and manage reusable forms for applications, interviews, screening, and onboarding.
46
+ </PageTitle.Description>
47
+ <PageTitle.Actions>
48
+ <Button size="default">
49
+ <Plus aria-hidden="true" />
50
+ Create Form
51
+ </Button>
52
+ </PageTitle.Actions>
53
+ </PageTitle>
54
+ ),
55
+ };
56
+
57
+ export const DefaultMinimal: Story = {
58
+ render: () => (
59
+ <PageTitle variant="default">
60
+ <PageTitle.Heading>Dashboard</PageTitle.Heading>
61
+ </PageTitle>
62
+ ),
63
+ };
64
+
65
+ export const DefaultNoDescription: Story = {
66
+ render: () => (
67
+ <PageTitle variant="default">
68
+ <PageTitle.Breadcrumbs items={BREADCRUMB_ITEMS} />
69
+ <PageTitle.Heading>Forms</PageTitle.Heading>
70
+ <PageTitle.Actions>
71
+ <Button size="default">
72
+ <Plus aria-hidden="true" />
73
+ Create Form
74
+ </Button>
75
+ </PageTitle.Actions>
76
+ </PageTitle>
77
+ ),
78
+ };
79
+
80
+ export const DefaultNoActions: Story = {
81
+ render: () => (
82
+ <PageTitle variant="default">
83
+ <PageTitle.Breadcrumbs items={BREADCRUMB_ITEMS} />
84
+ <PageTitle.Heading>Forms</PageTitle.Heading>
85
+ <PageTitle.Description>
86
+ A read-only listing page — no primary action.
87
+ </PageTitle.Description>
88
+ </PageTitle>
89
+ ),
90
+ };
91
+
92
+ export const DefaultWithTabs: Story = {
93
+ render: () => (
94
+ <PageTitle variant="default">
95
+ <PageTitle.Breadcrumbs
96
+ items={[
97
+ { id: 'home', label: 'Settings', href: '/settings' },
98
+ { id: 'careers', label: 'Careers Site' },
99
+ ]}
100
+ />
101
+ <PageTitle.Heading as="h2">Careers Site</PageTitle.Heading>
102
+ <PageTitle.Description>
103
+ Manage the public careers site pages and branding.
104
+ </PageTitle.Description>
105
+ <PageTitle.Tabs>
106
+ <nav aria-label="Site sections" className="flex gap-4 border-b border-[var(--border)]">
107
+ <a href="/pages" className="px-3 py-2 border-b-2 border-[var(--primary)]">
108
+ Page Builder
109
+ </a>
110
+ <a href="/pages/theme" className="px-3 py-2">
111
+ Theme
112
+ </a>
113
+ <a href="/pages/domain" className="px-3 py-2">
114
+ Domain
115
+ </a>
116
+ </nav>
117
+ </PageTitle.Tabs>
118
+ </PageTitle>
119
+ ),
120
+ };
121
+
122
+ // =============================================================================
123
+ // Feature variant
124
+ // =============================================================================
125
+
126
+ export const Feature: Story = {
127
+ render: () => (
128
+ <PageTitle variant="feature">
129
+ <PageTitle.Breadcrumbs items={BREADCRUMB_ITEMS} />
130
+ <PageTitle.Heading>Forms</PageTitle.Heading>
131
+ <PageTitle.Description>
132
+ Build and manage reusable forms for applications, interviews, screening, and onboarding.
133
+ </PageTitle.Description>
134
+ <PageTitle.Actions>
135
+ <Button size="default">
136
+ <Plus aria-hidden="true" />
137
+ Create Form
138
+ </Button>
139
+ </PageTitle.Actions>
140
+ </PageTitle>
141
+ ),
142
+ };
143
+
144
+ export const FeatureMinimal: Story = {
145
+ render: () => (
146
+ <PageTitle variant="feature">
147
+ <PageTitle.Heading>Welcome</PageTitle.Heading>
148
+ </PageTitle>
149
+ ),
150
+ };
151
+
152
+ export const FeatureWithTabs: Story = {
153
+ render: () => (
154
+ <PageTitle variant="feature">
155
+ <PageTitle.Breadcrumbs items={LONG_BREADCRUMB_ITEMS} />
156
+ <PageTitle.Heading>Field library</PageTitle.Heading>
157
+ <PageTitle.Description>
158
+ Reusable form fields, shared across every form in your organisation.
159
+ </PageTitle.Description>
160
+ <PageTitle.Actions>
161
+ <Button size="default">
162
+ <Plus aria-hidden="true" />
163
+ Create Field
164
+ </Button>
165
+ </PageTitle.Actions>
166
+ <PageTitle.Tabs>
167
+ <nav
168
+ aria-label="Library sections"
169
+ className="flex gap-4 bg-[var(--content-background)] px-4 py-2"
170
+ >
171
+ <a href="/fields">All fields</a>
172
+ <a href="/fields/groups">Groups</a>
173
+ <a href="/fields/categories">Categories</a>
174
+ </nav>
175
+ </PageTitle.Tabs>
176
+ </PageTitle>
177
+ ),
178
+ };
179
+
180
+ export const FeatureLongTitle: Story = {
181
+ name: 'Feature · Long title (reflow check)',
182
+ render: () => (
183
+ <PageTitle variant="feature">
184
+ <PageTitle.Breadcrumbs items={BREADCRUMB_ITEMS} />
185
+ <PageTitle.Heading>
186
+ A deliberately very long page title that must wrap onto multiple lines without breaking the
187
+ layout at any viewport width
188
+ </PageTitle.Heading>
189
+ <PageTitle.Description>
190
+ Long titles keep the description column and the action button column from overlapping — the
191
+ actions wrap beneath the body on narrow viewports.
192
+ </PageTitle.Description>
193
+ <PageTitle.Actions>
194
+ <Button size="default">
195
+ <Plus aria-hidden="true" />
196
+ Create
197
+ </Button>
198
+ </PageTitle.Actions>
199
+ </PageTitle>
200
+ ),
201
+ };
202
+
203
+ export const FeatureLongDescription: Story = {
204
+ name: 'Feature · Long description',
205
+ render: () => (
206
+ <PageTitle variant="feature">
207
+ <PageTitle.Breadcrumbs items={BREADCRUMB_ITEMS} />
208
+ <PageTitle.Heading>Forms</PageTitle.Heading>
209
+ <PageTitle.Description>
210
+ This supporting text intentionally spans multiple lines so that the vertical rhythm between
211
+ the title, the description, and the action button can be assessed — recruiters read this
212
+ copy once per landing and it must feel like a single coherent block, not an afterthought
213
+ crammed beneath a button.
214
+ </PageTitle.Description>
215
+ <PageTitle.Actions>
216
+ <Button size="default">
217
+ <Plus aria-hidden="true" />
218
+ Create Form
219
+ </Button>
220
+ </PageTitle.Actions>
221
+ </PageTitle>
222
+ ),
223
+ };
224
+
225
+ export const FeatureRTL: Story = {
226
+ name: 'Feature · RTL',
227
+ render: () => (
228
+ <div dir="rtl">
229
+ <PageTitle variant="feature">
230
+ <PageTitle.Breadcrumbs
231
+ items={[
232
+ { id: 'home', label: 'لوحة التحكم', href: '/' },
233
+ { id: 'forms', label: 'النماذج' },
234
+ ]}
235
+ />
236
+ <PageTitle.Heading>النماذج</PageTitle.Heading>
237
+ <PageTitle.Description>
238
+ أنشئ وأدر نماذج قابلة للاستخدام عبر جميع المراحل.
239
+ </PageTitle.Description>
240
+ <PageTitle.Actions>
241
+ <Button size="default">
242
+ <Plus aria-hidden="true" />
243
+ إنشاء نموذج
244
+ </Button>
245
+ </PageTitle.Actions>
246
+ </PageTitle>
247
+ </div>
248
+ ),
249
+ };
250
+
251
+ // =============================================================================
252
+ // A11y — dedicated audit story for addon-a11y
253
+ // =============================================================================
254
+
255
+ export const A11yAudit: Story = {
256
+ name: 'A11y audit (AAA)',
257
+ parameters: {
258
+ a11y: {
259
+ config: {
260
+ rules: [{ id: 'color-contrast-enhanced', enabled: true }],
261
+ },
262
+ },
263
+ },
264
+ render: () => (
265
+ <div className="flex flex-col gap-8">
266
+ <PageTitle variant="default">
267
+ <PageTitle.Breadcrumbs items={BREADCRUMB_ITEMS} />
268
+ <PageTitle.Heading>Default variant</PageTitle.Heading>
269
+ <PageTitle.Description>Verified against WCAG 2.2 AAA rules.</PageTitle.Description>
270
+ <PageTitle.Actions>
271
+ <Button size="default">
272
+ Create
273
+ </Button>
274
+ </PageTitle.Actions>
275
+ </PageTitle>
276
+ <PageTitle variant="feature">
277
+ <PageTitle.Breadcrumbs items={BREADCRUMB_ITEMS} />
278
+ <PageTitle.Heading>Feature variant</PageTitle.Heading>
279
+ <PageTitle.Description>Verified against WCAG 2.2 AAA rules.</PageTitle.Description>
280
+ <PageTitle.Actions>
281
+ <Button size="default">
282
+ Create
283
+ </Button>
284
+ </PageTitle.Actions>
285
+ </PageTitle>
286
+ </div>
287
+ ),
288
+ };