@crispy-seed/data-table 0.1.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 (56) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +30 -0
  3. package/README.md +103 -0
  4. package/dist/DataTable-12s-8LMBtS2u.cjs +1532 -0
  5. package/dist/DataTable-12s-Bd20OuMs.js +1482 -0
  6. package/dist/DataTable-12s-Zml1x9Kr-12s-CTRzgvMT.cjs +161 -0
  7. package/dist/DataTable-12s-Zml1x9Kr-12s-Coi-3lUa.js +153 -0
  8. package/dist/Menu-12s-Db_zr1AP.cjs +104 -0
  9. package/dist/Menu-12s-Di5JADW4.js +78 -0
  10. package/dist/Select-12s-1Uh7XbkG.js +219 -0
  11. package/dist/Select-12s-D8DdKT-U.cjs +250 -0
  12. package/dist/body-cells-12s-BnOVUTKN.js +453 -0
  13. package/dist/body-cells-12s-BoOTcg-l.cjs +462 -0
  14. package/dist/column-calc-12s-C6IPSOaF.js +129 -0
  15. package/dist/column-calc-12s-CKuSpe-l.cjs +149 -0
  16. package/dist/column-layout-12s-CTu5yT_D.cjs +120 -0
  17. package/dist/column-layout-12s-s7wnxkMN.js +99 -0
  18. package/dist/column-menu-12s-BPE9N1gs.cjs +427 -0
  19. package/dist/column-menu-12s-mRBk-4oa.js +407 -0
  20. package/dist/data-table-recipe.css +442 -0
  21. package/dist/data-table-recipe.layered.css +505 -0
  22. package/dist/editors-12s-BO9Mp034.js +525 -0
  23. package/dist/editors-12s-DO8TZkYV.cjs +555 -0
  24. package/dist/index.cjs +14 -0
  25. package/dist/index.d.ts +323 -0
  26. package/dist/index.js +10 -0
  27. package/dist/resize-12s-jQY-PX67.cjs +58 -0
  28. package/dist/resize-12s-nsMvrmLt.js +58 -0
  29. package/dist/states-12s-CLO_uVue.cjs +125 -0
  30. package/dist/states-12s-DEFSxJCO.js +122 -0
  31. package/dist/styles.css +14660 -0
  32. package/dist/toolbar-12s-AVU-sbDW.js +69 -0
  33. package/dist/toolbar-12s-CaLgJrDo.cjs +71 -0
  34. package/dist/useDataTable-12s-BHiDUubw-12s-CBeCwTe7.js +61 -0
  35. package/dist/useDataTable-12s-BHiDUubw-12s-Dgvt7XDk.cjs +61 -0
  36. package/dist/useDataTableColumnCalc-12s-DTQQTtEJ-12s-CvD14JYo.cjs +207 -0
  37. package/dist/useDataTableColumnCalc-12s-DTQQTtEJ-12s-DsEse3uq.js +183 -0
  38. package/dist/useDataTableColumns-12s-Cn2ZAzFL-12s-CD6goR59.js +289 -0
  39. package/dist/useDataTableColumns-12s-Cn2ZAzFL-12s-CUk_CpYT.cjs +292 -0
  40. package/dist/useDataTableEdit-12s-9Wb_UCrN-12s-BoOHq3GB.js +98 -0
  41. package/dist/useDataTableEdit-12s-9Wb_UCrN-12s-De6YHBba.cjs +98 -0
  42. package/dist/useDataTableFilter-12s-ZzbmWMin-12s-CWyBeFna.js +74 -0
  43. package/dist/useDataTableFilter-12s-ZzbmWMin-12s-lpjzZY3_.cjs +74 -0
  44. package/dist/useDataTableInfiniteScroll-12s-8ZG31URd-12s-BexjP6iO.js +104 -0
  45. package/dist/useDataTableInfiniteScroll-12s-8ZG31URd-12s-Bt8gojr9.cjs +104 -0
  46. package/dist/useDataTableRow-12s-CPYaDa1p-12s-BmUSAnPe.js +30 -0
  47. package/dist/useDataTableRow-12s-CPYaDa1p-12s-D-DRjwAe.cjs +30 -0
  48. package/dist/useDataTableScroll-12s-BKDCr0en-12s-C7f2vHeG.js +61 -0
  49. package/dist/useDataTableScroll-12s-BKDCr0en-12s-CUvUYMtt.cjs +61 -0
  50. package/dist/useDataTableSearch-12s-Ck3iWcpX-12s-B-65V6gH.js +37 -0
  51. package/dist/useDataTableSearch-12s-Ck3iWcpX-12s-DhVfN2Hq.cjs +37 -0
  52. package/dist/useDataTableSelection-12s-BIDtiRQq-12s-IS__VAnU.cjs +71 -0
  53. package/dist/useDataTableSelection-12s-BIDtiRQq-12s-O6M_BhrH.js +71 -0
  54. package/dist/useDataTableSort-12s-DvJYtmeS-12s-C5VGnsq4.cjs +78 -0
  55. package/dist/useDataTableSort-12s-DvJYtmeS-12s-DABSNt6U.js +78 -0
  56. package/package.json +78 -0
@@ -0,0 +1,555 @@
1
+ 'use client';
2
+ function __insertCSS(code) {
3
+ if (!code || typeof document == 'undefined') return
4
+ let head = document.head || document.getElementsByTagName('head')[0]
5
+ let style = document.createElement('style')
6
+ style.type = 'text/css'
7
+ head.appendChild(style)
8
+ ;style.styleSheet ? (style.styleSheet.cssText = code) : style.appendChild(document.createTextNode(code))
9
+ }
10
+
11
+ var Select12s = require('./Select-12s-D8DdKT-U.cjs');
12
+ var React = require('react');
13
+ var jsxRuntime = require('react/jsx-runtime');
14
+ var DataTable12s = require('./DataTable-12s-8LMBtS2u.cjs');
15
+ var bodyCells12s = require('./body-cells-12s-BoOTcg-l.cjs');
16
+ var reactSwitch = require('@seed-design/react-switch');
17
+ var _switch = require('@seed-design/css/recipes/switch');
18
+ var switchmark = require('@seed-design/css/recipes/switchmark');
19
+ var reactPrimitive = require('@seed-design/react-primitive');
20
+ var reactTextField = require('@seed-design/react-text-field');
21
+ var reactField = require('@seed-design/react-field');
22
+ var textInput = require('@seed-design/css/recipes/text-input');
23
+ var domUtils = require('@seed-design/dom-utils');
24
+
25
+ function _interopNamespace(e) {
26
+ if (e && e.__esModule) return e;
27
+ var n = Object.create(null);
28
+ if (e) {
29
+ Object.keys(e).forEach(function (k) {
30
+ if (k !== 'default') {
31
+ var d = Object.getOwnPropertyDescriptor(e, k);
32
+ Object.defineProperty(n, k, d.get ? d : {
33
+ enumerable: true,
34
+ get: function () { return e[k]; }
35
+ });
36
+ }
37
+ });
38
+ }
39
+ n.default = e;
40
+ return n;
41
+ }
42
+
43
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
44
+
45
+ const { withContext: withContext$1, ClassNamesProvider } = DataTable12s.createSlotRecipeContext(_switch.switchStyle);
46
+ const { withContext: withControlContext, PropsProvider: ControlPropsProvider, withProvider: withControlProvider } = DataTable12s.createSlotRecipeContext(switchmark.switchmark);
47
+ const withStateProps$1 = DataTable12s.createWithStateProps([
48
+ reactSwitch.useSwitchContext
49
+ ]);
50
+ const SwitchRoot = /*#__PURE__*/ React__namespace.default.forwardRef(({ className, ...props }, ref)=>{
51
+ const [{ switch: switchVariantProps, switchmark: switchmarkVariantProps }, otherProps] = DataTable12s.splitMultipleVariantsProps(props, {
52
+ switchmark: switchmark.switchmark,
53
+ switch: _switch.switchStyle
54
+ });
55
+ const classNames = _switch.switchStyle(switchVariantProps);
56
+ return /*#__PURE__*/ jsxRuntime.jsx(ControlPropsProvider, {
57
+ value: switchmarkVariantProps,
58
+ children: /*#__PURE__*/ jsxRuntime.jsx(ClassNamesProvider, {
59
+ value: classNames,
60
+ children: /*#__PURE__*/ jsxRuntime.jsx(reactSwitch.Switch.Root, {
61
+ ref: ref,
62
+ className: DataTable12s.clsx(classNames.root, className),
63
+ ...otherProps
64
+ })
65
+ })
66
+ });
67
+ });
68
+ SwitchRoot.displayName = "SwitchRoot";
69
+ const SwitchControl = DataTable12s.withScaleFeedback(withControlProvider(reactSwitch.Switch.Control, "root"));
70
+ const SwitchThumb = withControlContext(reactSwitch.Switch.Thumb, "thumb");
71
+ withContext$1(withStateProps$1(reactPrimitive.Primitive.span), "label");
72
+ const SwitchHiddenInput = reactSwitch.Switch.HiddenInput;
73
+
74
+ // src/use-layout-effect.tsx
75
+ var useLayoutEffect2 = globalThis?.document ? React__namespace.useLayoutEffect : ()=>{};
76
+
77
+ const { withProvider, withContext, useClassNames } = DataTable12s.createSlotRecipeContext(textInput.textInput);
78
+ const withFieldStateProps = DataTable12s.createWithStateProps([
79
+ {
80
+ useContext: reactField.useFieldContext,
81
+ strict: false
82
+ }
83
+ ]);
84
+ const withStateProps = DataTable12s.createWithStateProps([
85
+ reactTextField.useTextFieldContext,
86
+ {
87
+ useContext: reactField.useFieldContext,
88
+ strict: false
89
+ }
90
+ ]);
91
+ const TextFieldRoot = withProvider(withFieldStateProps(reactTextField.TextField.Root), "root");
92
+ const TextFieldPrefixIcon = withContext(withStateProps(DataTable12s.InternalIcon), "prefixIcon");
93
+ withContext(withStateProps(reactPrimitive.Primitive.span), "prefixText");
94
+ withContext(withStateProps(DataTable12s.InternalIcon), "suffixIcon");
95
+ withContext(withStateProps(reactPrimitive.Primitive.span), "suffixText");
96
+ const TextFieldInput = /*#__PURE__*/ React.forwardRef(({ className, ...otherProps }, ref)=>{
97
+ const classNames = useClassNames();
98
+ const textFieldContext = reactTextField.useTextFieldContext();
99
+ const fieldContext = reactField.useFieldContext({
100
+ strict: false
101
+ });
102
+ const mergedProps = domUtils.mergeProps(fieldContext ? fieldContext.stateProps : {}, fieldContext ? fieldContext.inputAriaAttributes : {}, textFieldContext.inputProps, fieldContext ? fieldContext.inputProps : {}, otherProps);
103
+ if (// if not in field, then must have aria-label or aria-labelledby
104
+ !fieldContext && !otherProps["aria-label"] && !otherProps["aria-labelledby"]) {
105
+ console.warn("TextFieldInput: Please provide `aria-label` or `aria-labelledby` for accessibility, or put `TextFieldInput` inside a `Field` where a `FieldLabel` is provided.");
106
+ }
107
+ return /*#__PURE__*/ jsxRuntime.jsx(reactTextField.TextField.Input, {
108
+ ref: ref,
109
+ ...mergedProps,
110
+ className: DataTable12s.clsx(classNames.value, className)
111
+ });
112
+ });
113
+ TextFieldInput.displayName = "TextFieldInput";
114
+ const TextFieldTextarea = /*#__PURE__*/ React.forwardRef(({ className, autoresize = true, ...otherProps }, ref)=>{
115
+ const classNames = useClassNames();
116
+ const textFieldContext = reactTextField.useTextFieldContext();
117
+ const fieldContext = reactField.useFieldContext({
118
+ strict: false
119
+ });
120
+ const mergedProps = domUtils.mergeProps(fieldContext ? fieldContext.stateProps : {}, fieldContext ? fieldContext.inputAriaAttributes : {}, textFieldContext.inputProps, fieldContext ? fieldContext.inputProps : {}, otherProps);
121
+ if (// if not in field, then must have aria-label or aria-labelledby
122
+ !fieldContext && !otherProps["aria-label"] && !otherProps["aria-labelledby"]) {
123
+ console.warn("TextFieldTextarea: Please provide `aria-label` or `aria-labelledby` for accessibility, or put `TextFieldTextarea` inside a `Field` where a `FieldLabel` is provided.");
124
+ }
125
+ // referenced from React Spectrum
126
+ const inputRef = React.useRef(null);
127
+ // biome-ignore lint/correctness/useExhaustiveDependencies: intended
128
+ const onHeightChange = React.useCallback(()=>{
129
+ if (!inputRef.current) return;
130
+ if (otherProps.style?.height) return;
131
+ if (!autoresize) return;
132
+ // Quiet textareas always grow based on their text content.
133
+ // Standard textareas also grow by default, unless an explicit height is set.
134
+ const input = inputRef.current;
135
+ const prevAlignment = input.style.alignSelf;
136
+ const prevOverflow = input.style.overflow;
137
+ // Firefox scroll position is lost when overflow: 'hidden' is applied so we skip applying it.
138
+ // The measure/applied height is also incorrect/reset if we turn on and off
139
+ // overflow: hidden in Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1787062
140
+ const isFirefox = "MozAppearance" in input.style;
141
+ if (!isFirefox) {
142
+ input.style.overflow = "hidden";
143
+ }
144
+ input.style.alignSelf = "start";
145
+ input.style.height = "auto";
146
+ // offsetHeight - clientHeight accounts for the border/padding.
147
+ input.style.height = `${input.scrollHeight + (input.offsetHeight - input.clientHeight)}px`;
148
+ input.style.overflow = prevOverflow;
149
+ input.style.alignSelf = prevAlignment;
150
+ }, [
151
+ inputRef,
152
+ otherProps.style?.height,
153
+ autoresize
154
+ ]);
155
+ useLayoutEffect2(()=>{
156
+ if (inputRef.current) {
157
+ onHeightChange();
158
+ }
159
+ }, [
160
+ onHeightChange,
161
+ textFieldContext.value,
162
+ inputRef
163
+ ]);
164
+ return /*#__PURE__*/ jsxRuntime.jsx(reactTextField.TextField.Textarea, {
165
+ ref: DataTable12s.composeRefs(inputRef, ref),
166
+ ...mergedProps,
167
+ className: DataTable12s.clsx(classNames.value, className)
168
+ });
169
+ });
170
+ TextFieldTextarea.displayName = "TextFieldTextarea";
171
+
172
+ /** The raw value a live editor reads, distinct from `DataTableColumn.value` (the
173
+ * accessor sort/search/filter/export share): `editValue` returns whatever TYPE the
174
+ * editor itself expects -- a real `boolean` for `editor: "switch"`/`type:
175
+ * "checkbox"`, a `number` for `type: "rating"`, the option's own string for `select`/
176
+ * `reference`/`actor` -- where `value`/`render` may format that same field for
177
+ * display. Falls back to the table's own accessor when the column supplies none. */ function resolveEditValue(column, row, fallback) {
178
+ return column.editValue ? column.editValue(row) : fallback;
179
+ }
180
+ function EditPendingIndicator() {
181
+ return /*#__PURE__*/ jsxRuntime.jsxs("svg", {
182
+ className: "seed-data-table-edit-pending",
183
+ width: 14,
184
+ height: 14,
185
+ viewBox: "0 0 16 16",
186
+ fill: "none",
187
+ role: "presentation",
188
+ "aria-hidden": "true",
189
+ children: [
190
+ /*#__PURE__*/ jsxRuntime.jsx("circle", {
191
+ cx: 8,
192
+ cy: 8,
193
+ r: 6.5,
194
+ stroke: "currentColor",
195
+ strokeOpacity: 0.25,
196
+ strokeWidth: 2
197
+ }),
198
+ /*#__PURE__*/ jsxRuntime.jsx("path", {
199
+ d: "M14.5 8a6.5 6.5 0 0 0-6.5-6.5",
200
+ stroke: "currentColor",
201
+ strokeWidth: 2,
202
+ strokeLinecap: "round"
203
+ })
204
+ ]
205
+ });
206
+ }
207
+ function EditError({ message }) {
208
+ return /*#__PURE__*/ jsxRuntime.jsx("span", {
209
+ className: "seed-data-table-edit-error",
210
+ children: message
211
+ });
212
+ }
213
+ ////////////////////////////////////////////////////////////////////////////////////
214
+ // -- plain editable: text/number (seed TextField) and date/datetime (a native input,
215
+ // styled the same way, per `cellType`) -- both double-click gated, Enter/blur
216
+ // commits, Escape cancels. -------------------------------------------------------
217
+ function TextEditor({ column, value, pending, onCommit, onCancel }) {
218
+ const [draft, setDraft] = React__namespace.useState(()=>value == null ? "" : String(value));
219
+ return(// `size="medium"` (seed's smallest fixed `TextField` size, 40px min-height,
220
+ // `text-input.ts`'s own token) -- the default `size="large"` overflowed a 36px
221
+ // table row (same class of fix as `toolbar.tsx`'s `SearchBox`, which made the
222
+ // same call for its own 32px-ish search box).
223
+ /*#__PURE__*/ jsxRuntime.jsx(TextFieldRoot, {
224
+ size: "medium",
225
+ style: {
226
+ width: "100%"
227
+ },
228
+ onClick: (event)=>event.stopPropagation(),
229
+ onKeyDown: (event)=>event.stopPropagation(),
230
+ children: /*#__PURE__*/ jsxRuntime.jsx(TextFieldInput, {
231
+ autoFocus: true,
232
+ type: column.cellType === "number" ? "number" : "text",
233
+ "aria-label": `Edit ${column.key}`,
234
+ value: draft,
235
+ disabled: pending,
236
+ onChange: (event)=>setDraft(event.target.value),
237
+ onBlur: ()=>onCommit(draft),
238
+ onKeyDown: (event)=>{
239
+ if (event.key === "Enter") onCommit(draft);
240
+ else if (event.key === "Escape") onCancel();
241
+ }
242
+ })
243
+ }));
244
+ }
245
+ function DateEditor({ column, value, pending, onCommit, onCancel }) {
246
+ const isDateTime = column.cellType === "datetime";
247
+ const [draft, setDraft] = React__namespace.useState(()=>isDateTime ? bodyCells12s.toDateTimeInputValue(value) : bodyCells12s.toDateInputValue(value));
248
+ return(// See `TextEditor`'s own comment above -- same `size="medium"` fix.
249
+ /*#__PURE__*/ jsxRuntime.jsx(TextFieldRoot, {
250
+ size: "medium",
251
+ style: {
252
+ width: "100%"
253
+ },
254
+ onClick: (event)=>event.stopPropagation(),
255
+ onKeyDown: (event)=>event.stopPropagation(),
256
+ children: /*#__PURE__*/ jsxRuntime.jsx(TextFieldInput, {
257
+ autoFocus: true,
258
+ type: isDateTime ? "datetime-local" : "date",
259
+ "aria-label": `Edit ${column.key}`,
260
+ value: draft,
261
+ disabled: pending,
262
+ onChange: (event)=>setDraft(event.target.value),
263
+ onBlur: ()=>onCommit(draft),
264
+ onKeyDown: (event)=>{
265
+ if (event.key === "Enter") onCommit(draft);
266
+ else if (event.key === "Escape") onCancel();
267
+ }
268
+ })
269
+ }));
270
+ }
271
+ ////////////////////////////////////////////////////////////////////////////////////
272
+ // -- editor: "select" -- double-click opens seed's own Select, auto-opened (seed's
273
+ // `SelectRoot` takes `defaultOpen` directly -- unlike crisp's closed-API `Select`,
274
+ // which needs a synthetic click on its own trigger to start open). -------------
275
+ function SelectEditor({ column, value, pending, onCommit, onCancel }) {
276
+ const options = column.options ?? [];
277
+ const current = value == null ? "" : String(value);
278
+ return /*#__PURE__*/ jsxRuntime.jsxs(Select12s.SelectRoot, {
279
+ // Controlled open, per docs/examples/react/select/controlled-open.tsx --
280
+ // this editor is only ever mounted while the cell IS editing, so it always
281
+ // wants to start (and stay) open; `onOpenChange(false)` is what tells us
282
+ // the popover wants to close for ANY reason (Escape, an outside click, OR
283
+ // the internal auto-close a single-select commit already triggers), so
284
+ // `onCancel` alone now covers the Escape gap the old raw `document`
285
+ // listener existed for, without a second, independent listener.
286
+ open: true,
287
+ onOpenChange: (next)=>{
288
+ if (!next) onCancel();
289
+ },
290
+ disabled: pending,
291
+ value: current ? [
292
+ current
293
+ ] : [],
294
+ onValueChange: (next)=>onCommit(next[0] ?? ""),
295
+ children: [
296
+ /*#__PURE__*/ jsxRuntime.jsxs(Select12s.SelectTrigger, {
297
+ "aria-label": `Edit ${column.key}`,
298
+ children: [
299
+ /*#__PURE__*/ jsxRuntime.jsx(Select12s.SelectValue, {}),
300
+ /*#__PURE__*/ jsxRuntime.jsx(Select12s.SelectPlaceholder, {
301
+ children: "Select…"
302
+ }),
303
+ /*#__PURE__*/ jsxRuntime.jsx(Select12s.SelectSuffixIcon, {
304
+ svg: /*#__PURE__*/ jsxRuntime.jsx(DataTable12s.IconChevronDownSmallLine_default, {})
305
+ })
306
+ ]
307
+ }),
308
+ /*#__PURE__*/ jsxRuntime.jsx(Select12s.SelectPositioner, {
309
+ children: /*#__PURE__*/ jsxRuntime.jsx(Select12s.SelectContent, {
310
+ children: /*#__PURE__*/ jsxRuntime.jsx(Select12s.SelectScrollArea, {
311
+ children: options.map((option)=>/*#__PURE__*/ jsxRuntime.jsxs(Select12s.SelectItem, {
312
+ value: option.value,
313
+ label: option.label,
314
+ children: [
315
+ /*#__PURE__*/ jsxRuntime.jsx(Select12s.SelectItemBody, {
316
+ children: /*#__PURE__*/ jsxRuntime.jsx(Select12s.SelectItemLabel, {})
317
+ }),
318
+ /*#__PURE__*/ jsxRuntime.jsx(Select12s.SelectItemIndicator, {
319
+ selected: /*#__PURE__*/ jsxRuntime.jsx(DataTable12s.IconCheckmarkFatFill_default, {})
320
+ })
321
+ ]
322
+ }, option.value))
323
+ })
324
+ })
325
+ })
326
+ ]
327
+ });
328
+ }
329
+ ////////////////////////////////////////////////////////////////////////////////////
330
+ // -- editor: "reference" / "actor" -- same picker, search-enabled, each option
331
+ // carrying a small avatar (a photo for a real one, a generic person glyph for
332
+ // none) -- `actor` is `reference` over people specifically (crisp's own #449/
333
+ // #432 `ReferenceCell` shape), so the two share one component; only the search
334
+ // placeholder differs. Seed's `Select` has no built-in search combobox (unlike
335
+ // crisp's own `Select`), so this filters `refOptions` itself against a small
336
+ // `TextField` rendered as the content's own first row. --------------------------
337
+ function ReferenceEditor({ column, value, pending, onCommit, onCancel }) {
338
+ const [query, setQuery] = React__namespace.useState("");
339
+ const options = column.refOptions ?? [];
340
+ const filtered = query.trim() ? options.filter((option)=>option.label.toLowerCase().includes(query.trim().toLowerCase())) : options;
341
+ const current = value == null ? "" : String(value);
342
+ const isActor = column.editor === "actor";
343
+ return /*#__PURE__*/ jsxRuntime.jsxs(Select12s.SelectRoot, {
344
+ // See `SelectEditor`'s own comment above -- same controlled-open wiring.
345
+ open: true,
346
+ onOpenChange: (next)=>{
347
+ if (!next) onCancel();
348
+ },
349
+ disabled: pending,
350
+ value: current ? [
351
+ current
352
+ ] : [],
353
+ onValueChange: (next)=>onCommit(next[0] ?? ""),
354
+ children: [
355
+ /*#__PURE__*/ jsxRuntime.jsxs(Select12s.SelectTrigger, {
356
+ "aria-label": `Edit ${column.key}`,
357
+ children: [
358
+ /*#__PURE__*/ jsxRuntime.jsx(Select12s.SelectValue, {}),
359
+ /*#__PURE__*/ jsxRuntime.jsx(Select12s.SelectPlaceholder, {
360
+ children: isActor ? "Assign…" : "Select…"
361
+ }),
362
+ /*#__PURE__*/ jsxRuntime.jsx(Select12s.SelectSuffixIcon, {
363
+ svg: /*#__PURE__*/ jsxRuntime.jsx(DataTable12s.IconChevronDownSmallLine_default, {})
364
+ })
365
+ ]
366
+ }),
367
+ /*#__PURE__*/ jsxRuntime.jsx(Select12s.SelectPositioner, {
368
+ children: /*#__PURE__*/ jsxRuntime.jsxs(Select12s.SelectContent, {
369
+ children: [
370
+ /*#__PURE__*/ jsxRuntime.jsx(TextFieldRoot, {
371
+ size: "medium",
372
+ style: {
373
+ margin: 4
374
+ },
375
+ onKeyDown: (event)=>{
376
+ // The listbox's own typeahead/arrow handling lives on THIS field's
377
+ // sibling items, not on the field itself -- stop everything except
378
+ // Escape from also driving the listbox's own keyboard nav. Escape
379
+ // itself needs no special-casing to "reach" anything any more: it's
380
+ // SelectContent's own `DismissibleLayer` (Select.tsx) that closes the
381
+ // listbox, and that dismissal is a document-level listener outside
382
+ // this React subtree entirely -- a synthetic `stopPropagation` here
383
+ // was never able to block it either way, so the controlled `open`
384
+ // above (via `onOpenChange`) is what actually ends this cell's edit.
385
+ if (event.key !== "Escape") event.stopPropagation();
386
+ },
387
+ children: /*#__PURE__*/ jsxRuntime.jsx(TextFieldInput, {
388
+ autoFocus: true,
389
+ "aria-label": isActor ? "Search people" : `Search ${column.key}`,
390
+ placeholder: isActor ? "Search people…" : "Search…",
391
+ value: query,
392
+ onChange: (event)=>setQuery(event.target.value)
393
+ })
394
+ }),
395
+ /*#__PURE__*/ jsxRuntime.jsxs(Select12s.SelectScrollArea, {
396
+ children: [
397
+ filtered.length === 0 && /*#__PURE__*/ jsxRuntime.jsx("div", {
398
+ style: {
399
+ padding: "6px 12px",
400
+ opacity: 0.63,
401
+ fontSize: 13
402
+ },
403
+ children: isActor ? "No users" : "No results"
404
+ }),
405
+ filtered.map((option)=>/*#__PURE__*/ jsxRuntime.jsxs(Select12s.SelectItem, {
406
+ value: option.value,
407
+ label: option.label,
408
+ children: [
409
+ /*#__PURE__*/ jsxRuntime.jsxs(Select12s.SelectItemBody, {
410
+ children: [
411
+ /*#__PURE__*/ jsxRuntime.jsx(ReferenceAvatar, {
412
+ avatar: option.avatar
413
+ }),
414
+ /*#__PURE__*/ jsxRuntime.jsx(Select12s.SelectItemLabel, {})
415
+ ]
416
+ }),
417
+ /*#__PURE__*/ jsxRuntime.jsx(Select12s.SelectItemIndicator, {
418
+ selected: /*#__PURE__*/ jsxRuntime.jsx(DataTable12s.IconCheckmarkFatFill_default, {})
419
+ })
420
+ ]
421
+ }, option.value))
422
+ ]
423
+ })
424
+ ]
425
+ })
426
+ })
427
+ ]
428
+ });
429
+ }
430
+ function ReferenceAvatar({ avatar }) {
431
+ return /*#__PURE__*/ jsxRuntime.jsxs(bodyCells12s.AvatarRoot, {
432
+ size: "20",
433
+ children: [
434
+ avatar && /*#__PURE__*/ jsxRuntime.jsx(bodyCells12s.AvatarImage, {
435
+ src: avatar,
436
+ alt: ""
437
+ }),
438
+ /*#__PURE__*/ jsxRuntime.jsx(bodyCells12s.AvatarFallback, {
439
+ children: /*#__PURE__*/ jsxRuntime.jsx(DataTable12s.IconPersonCircleLine_default, {})
440
+ })
441
+ ]
442
+ });
443
+ }
444
+ ////////////////////////////////////////////////////////////////////////////////////
445
+ // -- always-live editors: no double-click gate, no separate rest/edit state --
446
+ // interacting with the widget IS the commit gesture (crisp's own #453/#760/#761).
447
+ function SwitchEditor({ column, value, pending, onCommit }) {
448
+ const checked = value === true || value === "true";
449
+ return /*#__PURE__*/ jsxRuntime.jsxs("span", {
450
+ className: "seed-data-table-edit-picker",
451
+ children: [
452
+ /*#__PURE__*/ jsxRuntime.jsxs(SwitchRoot, {
453
+ size: "16",
454
+ checked: checked,
455
+ disabled: pending,
456
+ onCheckedChange: (next)=>onCommit(String(next)),
457
+ children: [
458
+ /*#__PURE__*/ jsxRuntime.jsx(SwitchControl, {
459
+ children: /*#__PURE__*/ jsxRuntime.jsx(SwitchThumb, {})
460
+ }),
461
+ /*#__PURE__*/ jsxRuntime.jsx(SwitchHiddenInput, {
462
+ "aria-label": `Edit ${column.key}`
463
+ })
464
+ ]
465
+ }),
466
+ pending && /*#__PURE__*/ jsxRuntime.jsx(EditPendingIndicator, {})
467
+ ]
468
+ });
469
+ }
470
+ function CheckboxEditor({ column, value, pending, onCommit }) {
471
+ const checked = value === true || value === "true";
472
+ return /*#__PURE__*/ jsxRuntime.jsxs("span", {
473
+ className: "seed-data-table-edit-picker",
474
+ children: [
475
+ /*#__PURE__*/ jsxRuntime.jsxs(DataTable12s.CheckboxRoot, {
476
+ checked: checked,
477
+ disabled: pending,
478
+ onCheckedChange: (next)=>onCommit(String(next)),
479
+ children: [
480
+ /*#__PURE__*/ jsxRuntime.jsx(DataTable12s.CheckboxControl, {
481
+ children: /*#__PURE__*/ jsxRuntime.jsx(DataTable12s.CheckboxIndicator, {
482
+ checked: bodyCells12s.CHECKBOX_CELL_CHECKED_ICON
483
+ })
484
+ }),
485
+ /*#__PURE__*/ jsxRuntime.jsx(DataTable12s.CheckboxHiddenInput, {
486
+ "aria-label": `Edit ${column.key}`
487
+ })
488
+ ]
489
+ }),
490
+ pending && /*#__PURE__*/ jsxRuntime.jsx(EditPendingIndicator, {})
491
+ ]
492
+ });
493
+ }
494
+ function RatingEditor({ column, value, pending, onCommit }) {
495
+ const maxRating = column.maxRating ?? 5;
496
+ const rating = typeof value === "number" ? value : Number(value) || 0;
497
+ return /*#__PURE__*/ jsxRuntime.jsxs("span", {
498
+ className: "seed-data-table-edit-picker",
499
+ children: [
500
+ /*#__PURE__*/ jsxRuntime.jsx("span", {
501
+ role: "group",
502
+ "aria-label": `Edit ${column.key}`,
503
+ style: {
504
+ display: "inline-flex",
505
+ alignItems: "center",
506
+ gap: 2
507
+ },
508
+ children: Array.from({
509
+ length: maxRating
510
+ }, (_, index)=>{
511
+ const starValue = index + 1;
512
+ return /*#__PURE__*/ jsxRuntime.jsx("button", {
513
+ type: "button",
514
+ disabled: pending,
515
+ "aria-label": `Set ${starValue} out of ${maxRating}`,
516
+ "aria-pressed": starValue <= rating,
517
+ onClick: ()=>onCommit(String(starValue)),
518
+ style: {
519
+ border: "none",
520
+ background: "none",
521
+ padding: 0,
522
+ cursor: "pointer",
523
+ lineHeight: 0
524
+ },
525
+ children: /*#__PURE__*/ jsxRuntime.jsx("svg", {
526
+ width: 16,
527
+ height: 16,
528
+ viewBox: "0 0 16 16",
529
+ fill: "none",
530
+ "aria-hidden": "true",
531
+ children: /*#__PURE__*/ jsxRuntime.jsx("path", {
532
+ d: bodyCells12s.RATING_STAR_D,
533
+ fill: starValue <= rating ? bodyCells12s.RATING_FILLED : bodyCells12s.RATING_EMPTY
534
+ })
535
+ })
536
+ }, index);
537
+ })
538
+ }),
539
+ pending && /*#__PURE__*/ jsxRuntime.jsx(EditPendingIndicator, {})
540
+ ]
541
+ });
542
+ }
543
+
544
+ exports.CheckboxEditor = CheckboxEditor;
545
+ exports.DateEditor = DateEditor;
546
+ exports.EditError = EditError;
547
+ exports.RatingEditor = RatingEditor;
548
+ exports.ReferenceEditor = ReferenceEditor;
549
+ exports.SelectEditor = SelectEditor;
550
+ exports.SwitchEditor = SwitchEditor;
551
+ exports.TextEditor = TextEditor;
552
+ exports.TextFieldInput = TextFieldInput;
553
+ exports.TextFieldPrefixIcon = TextFieldPrefixIcon;
554
+ exports.TextFieldRoot = TextFieldRoot;
555
+ exports.resolveEditValue = resolveEditValue;
package/dist/index.cjs ADDED
@@ -0,0 +1,14 @@
1
+ function __insertCSS(code) {
2
+ if (!code || typeof document == 'undefined') return
3
+ let head = document.head || document.getElementsByTagName('head')[0]
4
+ let style = document.createElement('style')
5
+ style.type = 'text/css'
6
+ head.appendChild(style)
7
+ ;style.styleSheet ? (style.styleSheet.cssText = code) : style.appendChild(document.createTextNode(code))
8
+ }
9
+
10
+ var DataTable12s = require('./DataTable-12s-8LMBtS2u.cjs');
11
+
12
+
13
+
14
+ exports.DataTable = DataTable12s.DataTable;