@tribepad/themis 1.5.9 → 1.6.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.
- package/CHANGELOG.md +14 -0
- package/dist/elements/Checkbox/Checkbox.d.ts.map +1 -1
- package/dist/elements/Checkbox/index.js +1 -1
- package/dist/elements/Checkbox/index.js.map +1 -1
- package/dist/elements/Checkbox/index.mjs +1 -1
- package/dist/elements/Checkbox/index.mjs.map +1 -1
- package/dist/elements/Filters/AppliedFilters.d.ts +4 -0
- package/dist/elements/Filters/AppliedFilters.d.ts.map +1 -0
- package/dist/elements/Filters/FilterPopover.d.ts +33 -0
- package/dist/elements/Filters/FilterPopover.d.ts.map +1 -0
- package/dist/elements/Filters/Filters.d.ts +25 -0
- package/dist/elements/Filters/Filters.d.ts.map +1 -0
- package/dist/elements/Filters/Filters.styles.d.ts +24 -0
- package/dist/elements/Filters/Filters.styles.d.ts.map +1 -0
- package/dist/elements/Filters/Filters.types.d.ts +123 -0
- package/dist/elements/Filters/Filters.types.d.ts.map +1 -0
- package/dist/elements/Filters/FiltersContext.d.ts +36 -0
- package/dist/elements/Filters/FiltersContext.d.ts.map +1 -0
- package/dist/elements/Filters/index.css +2 -0
- package/dist/elements/Filters/index.css.map +1 -0
- package/dist/elements/Filters/index.d.ts +26 -0
- package/dist/elements/Filters/index.d.ts.map +1 -0
- package/dist/elements/Filters/index.js +3 -0
- package/dist/elements/Filters/index.js.map +1 -0
- package/dist/elements/Filters/index.mjs +3 -0
- package/dist/elements/Filters/index.mjs.map +1 -0
- package/dist/elements/PasswordField/PasswordField.types.d.ts +34 -34
- package/dist/elements/Table/BulkActionBar.d.ts +5 -0
- package/dist/elements/Table/BulkActionBar.d.ts.map +1 -0
- package/dist/elements/Table/BulkActionBar.styles.d.ts +17 -0
- package/dist/elements/Table/BulkActionBar.styles.d.ts.map +1 -0
- package/dist/elements/Table/BulkActionBar.types.d.ts +136 -0
- package/dist/elements/Table/BulkActionBar.types.d.ts.map +1 -0
- package/dist/elements/Table/Table.d.ts.map +1 -1
- package/dist/elements/Table/Table.styles.d.ts +2 -2
- package/dist/elements/Table/Table.styles.d.ts.map +1 -1
- package/dist/elements/Table/Table.types.d.ts +14 -4
- package/dist/elements/Table/Table.types.d.ts.map +1 -1
- package/dist/elements/Table/TableCardList.d.ts +25 -0
- package/dist/elements/Table/TableCardList.d.ts.map +1 -0
- package/dist/elements/Table/TableCardList.styles.d.ts +15 -0
- package/dist/elements/Table/TableCardList.styles.d.ts.map +1 -0
- package/dist/elements/Table/TableCardList.types.d.ts +48 -0
- package/dist/elements/Table/TableCardList.types.d.ts.map +1 -0
- package/dist/elements/Table/index.d.ts +9 -0
- package/dist/elements/Table/index.d.ts.map +1 -1
- package/dist/elements/Table/index.js +1 -1
- package/dist/elements/Table/index.js.map +1 -1
- package/dist/elements/Table/index.mjs +1 -1
- package/dist/elements/Table/index.mjs.map +1 -1
- package/dist/elements/Table/resolveSelectedCount.d.ts +20 -0
- package/dist/elements/Table/resolveSelectedCount.d.ts.map +1 -0
- package/dist/elements/Table/useBulkActionShortcut.d.ts +29 -0
- package/dist/elements/Table/useBulkActionShortcut.d.ts.map +1 -0
- package/dist/elements/TextField/TextField.types.d.ts +68 -68
- package/dist/elements/index.d.ts +4 -1
- package/dist/elements/index.d.ts.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/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/index.mjs +1 -1
- package/dist/hooks/index.mjs.map +1 -1
- package/dist/hooks/useContainerNarrow.d.ts +15 -0
- package/dist/hooks/useContainerNarrow.d.ts.map +1 -0
- 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/dist/styles/defaults.css +15 -0
- package/package.json +6 -1
- package/src/elements/Filters/Filters.stories.tsx +148 -0
- package/src/elements/Table/Table.stories.tsx +467 -10
package/dist/styles/defaults.css
CHANGED
|
@@ -42,6 +42,11 @@
|
|
|
42
42
|
--accent-foreground: #1f2937;
|
|
43
43
|
--accent-background: #f3f4f6;
|
|
44
44
|
|
|
45
|
+
/* Selection tint — selected table rows + the bulk-action toolbar band.
|
|
46
|
+
A light brand-purple lilac on light surfaces; dark/high-contrast themes
|
|
47
|
+
darken instead of lighten (see their blocks below). */
|
|
48
|
+
--selected: #f3eefe;
|
|
49
|
+
|
|
45
50
|
/* Muted Colors */
|
|
46
51
|
--muted: #f9fafb;
|
|
47
52
|
--muted-foreground: #6b7280;
|
|
@@ -150,6 +155,9 @@
|
|
|
150
155
|
--accent-foreground: #f9fafb;
|
|
151
156
|
--accent-background: #1a1a1a;
|
|
152
157
|
|
|
158
|
+
/* Selection tint — darker, elevated violet on the dark surface (not lighter). */
|
|
159
|
+
--selected: #2a2140;
|
|
160
|
+
|
|
153
161
|
--muted: #1f2937;
|
|
154
162
|
--muted-foreground: #9ca3af;
|
|
155
163
|
|
|
@@ -240,6 +248,10 @@
|
|
|
240
248
|
--accent-foreground: #ffffff;
|
|
241
249
|
--accent-background: #333333;
|
|
242
250
|
|
|
251
|
+
/* Selection tint — a clearly distinct dark surface on the black background
|
|
252
|
+
(high-contrast conveys selection via the checkbox/focus ring too). */
|
|
253
|
+
--selected: #333333;
|
|
254
|
+
|
|
243
255
|
/* Muted */
|
|
244
256
|
--muted: #1a1a1a;
|
|
245
257
|
--muted-foreground: #cccccc;
|
|
@@ -318,6 +330,9 @@
|
|
|
318
330
|
--primary: #1e40af;
|
|
319
331
|
--primary-foreground: #ffffff;
|
|
320
332
|
|
|
333
|
+
/* Selection tint — light blue tint of the colorblind-safe primary. */
|
|
334
|
+
--selected: #e8eefb;
|
|
335
|
+
|
|
321
336
|
/* Destructive — Orange instead of red (7.52:1 on white) */
|
|
322
337
|
--destructive-background: #9a3412;
|
|
323
338
|
--destructive-foreground: #ffffff;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tribepad/themis",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Accessible React component library built on React Aria primitives",
|
|
5
5
|
"author": "Tribepad <mbasford@tribepad.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -263,6 +263,11 @@
|
|
|
263
263
|
"name": "ChatInterface only",
|
|
264
264
|
"path": "dist/elements/ChatInterface/index.mjs",
|
|
265
265
|
"limit": "28 KB"
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
"name": "Filters (full barrel)",
|
|
269
|
+
"path": "dist/elements/Filters/index.mjs",
|
|
270
|
+
"limit": "80 KB"
|
|
266
271
|
}
|
|
267
272
|
],
|
|
268
273
|
"keywords": [
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filters — Storybook stories (compositional API)
|
|
3
|
+
*
|
|
4
|
+
* `<Filters values onChange labels>` owns one values map; controls are composed
|
|
5
|
+
* as children (`<FilterSearch>`, `<FilterSelect>`, `<FilterCombobox>` …) and
|
|
6
|
+
* `<FilterChips>` renders removable chips. Import only the controls you use.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { useState, type ReactElement } from 'react';
|
|
10
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
11
|
+
import {
|
|
12
|
+
Filters,
|
|
13
|
+
FilterSearch,
|
|
14
|
+
FilterSelect,
|
|
15
|
+
FilterMulti,
|
|
16
|
+
FilterToggle,
|
|
17
|
+
FilterWithin,
|
|
18
|
+
FilterCombobox,
|
|
19
|
+
FilterChips,
|
|
20
|
+
} from './Filters';
|
|
21
|
+
import type { FilterOption, FilterValues } from './Filters.types';
|
|
22
|
+
|
|
23
|
+
const statusOptions: FilterOption[] = [
|
|
24
|
+
{ value: 'open', label: 'Open' },
|
|
25
|
+
{ value: 'draft', label: 'Draft' },
|
|
26
|
+
{ value: 'closed', label: 'Closed' },
|
|
27
|
+
];
|
|
28
|
+
const teamOptions: FilterOption[] = [
|
|
29
|
+
{ value: 'eng', label: 'Engineering' },
|
|
30
|
+
{ value: 'design', label: 'Design' },
|
|
31
|
+
{ value: 'ops', label: 'Operations' },
|
|
32
|
+
];
|
|
33
|
+
const postedPresets: FilterOption[] = [
|
|
34
|
+
{ value: 'any', label: 'Any time' },
|
|
35
|
+
{ value: '24h', label: 'Last 24 hours' },
|
|
36
|
+
{ value: '7d', label: 'Last 7 days' },
|
|
37
|
+
{ value: '30d', label: 'Last 30 days' },
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
const meta = {
|
|
41
|
+
title: 'Elements/Filters',
|
|
42
|
+
component: Filters,
|
|
43
|
+
tags: ['autodocs'],
|
|
44
|
+
parameters: {
|
|
45
|
+
layout: 'padded',
|
|
46
|
+
docs: {
|
|
47
|
+
description: {
|
|
48
|
+
component:
|
|
49
|
+
'A compositional filter bar. `<Filters values onChange labels>` owns one controlled values map; controls are composed as children and `<FilterChips>` renders removable chips. Domain-free (labels-as-props), non-modal popovers, WCAG 2.2 AAA.',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
} satisfies Meta<typeof Filters>;
|
|
54
|
+
|
|
55
|
+
export default meta;
|
|
56
|
+
type Story = StoryObj<typeof meta>;
|
|
57
|
+
|
|
58
|
+
/** A full bar with every control kind plus removable chips. */
|
|
59
|
+
export const Default: Story = {
|
|
60
|
+
render: function FiltersStory(): ReactElement {
|
|
61
|
+
const [values, setValues] = useState<FilterValues>({ status: 'open', team: ['eng'] });
|
|
62
|
+
return (
|
|
63
|
+
<Filters
|
|
64
|
+
values={values}
|
|
65
|
+
onChange={setValues}
|
|
66
|
+
labels={{ done: 'Done', clear: 'Clear' }}
|
|
67
|
+
aria-label="Filter positions"
|
|
68
|
+
>
|
|
69
|
+
<FilterSearch name="q" label="Search positions" placeholder="Search name or title…" />
|
|
70
|
+
<FilterSelect name="status" label="Status" options={statusOptions} />
|
|
71
|
+
<FilterMulti name="team" label="Team" options={teamOptions} />
|
|
72
|
+
<FilterWithin name="posted" label="Posted" presets={postedPresets} />
|
|
73
|
+
<FilterToggle name="remote" label="Remote only" />
|
|
74
|
+
<FilterChips clearAllLabel="Clear all" removeChipLabel={(label) => `Remove ${label}`} />
|
|
75
|
+
</Filters>
|
|
76
|
+
);
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* API-backed type-ahead with `FilterCombobox` — the consumer fetches options in
|
|
82
|
+
* response to `onSearch` (debounce in real apps); the selected label persists in
|
|
83
|
+
* the chip even as the option list changes.
|
|
84
|
+
*/
|
|
85
|
+
export const AsyncCombobox: Story = {
|
|
86
|
+
render: function AsyncStory(): ReactElement {
|
|
87
|
+
const [values, setValues] = useState<FilterValues>({});
|
|
88
|
+
const [options, setOptions] = useState<FilterOption[]>([]);
|
|
89
|
+
const directory: FilterOption[] = [
|
|
90
|
+
{ value: 'u1', label: 'Ada Lovelace' },
|
|
91
|
+
{ value: 'u2', label: 'Alan Turing' },
|
|
92
|
+
{ value: 'u3', label: 'Grace Hopper' },
|
|
93
|
+
];
|
|
94
|
+
return (
|
|
95
|
+
<Filters values={values} onChange={setValues} labels={{ done: 'Done', clear: 'Clear' }}>
|
|
96
|
+
<FilterCombobox
|
|
97
|
+
name="assignee"
|
|
98
|
+
label="Assignee"
|
|
99
|
+
placeholder="Search people…"
|
|
100
|
+
options={options}
|
|
101
|
+
onSearch={(query) =>
|
|
102
|
+
setOptions(
|
|
103
|
+
query
|
|
104
|
+
? directory.filter((o) => o.label.toLowerCase().includes(query.toLowerCase()))
|
|
105
|
+
: []
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
/>
|
|
109
|
+
<FilterChips clearAllLabel="Clear all" removeChipLabel={(label) => `Remove ${label}`} />
|
|
110
|
+
</Filters>
|
|
111
|
+
);
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Mobile (narrow) — the bar collapses to a "Filters" button that opens a
|
|
117
|
+
* bottom-sheet of stacked controls; chips scroll horizontally. Pass `narrow`
|
|
118
|
+
* (measure once with `useContainerNarrow` and share it with your table switch).
|
|
119
|
+
*/
|
|
120
|
+
export const Mobile: Story = {
|
|
121
|
+
render: function MobileStory(): ReactElement {
|
|
122
|
+
const [values, setValues] = useState<FilterValues>({ status: 'open', team: ['eng'] });
|
|
123
|
+
return (
|
|
124
|
+
<div style={{ maxWidth: 380 }}>
|
|
125
|
+
<Filters
|
|
126
|
+
values={values}
|
|
127
|
+
onChange={setValues}
|
|
128
|
+
narrow
|
|
129
|
+
aria-label="Filter positions"
|
|
130
|
+
labels={{
|
|
131
|
+
done: 'Done',
|
|
132
|
+
clear: 'Clear',
|
|
133
|
+
clearAll: 'Clear all',
|
|
134
|
+
close: 'Close',
|
|
135
|
+
filtersButton: 'Filters',
|
|
136
|
+
}}
|
|
137
|
+
>
|
|
138
|
+
<FilterSearch name="q" label="Search positions" placeholder="Search…" />
|
|
139
|
+
<FilterSelect name="status" label="Status" options={statusOptions} />
|
|
140
|
+
<FilterMulti name="team" label="Team" options={teamOptions} />
|
|
141
|
+
<FilterWithin name="posted" label="Posted" presets={postedPresets} />
|
|
142
|
+
<FilterToggle name="remote" label="Remote only" />
|
|
143
|
+
<FilterChips clearAllLabel="Clear all" removeChipLabel={(label) => `Remove ${label}`} />
|
|
144
|
+
</Filters>
|
|
145
|
+
</div>
|
|
146
|
+
);
|
|
147
|
+
},
|
|
148
|
+
};
|