@flood-md/react 0.2.10 → 0.2.12
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 +275 -5
- package/dist/app-shell.d.ts +3 -0
- package/dist/app-shell.js +66 -0
- package/dist/bulk-action-bar.d.ts +3 -0
- package/dist/bulk-action-bar.js +17 -0
- package/dist/collection-toolbar.d.ts +3 -0
- package/dist/collection-toolbar.js +26 -0
- package/dist/collection-view-switcher.d.ts +3 -0
- package/dist/collection-view-switcher.js +19 -0
- package/dist/combobox.d.ts +6 -1
- package/dist/combobox.js +77 -29
- package/dist/command-list.d.ts +5 -1
- package/dist/command-list.js +2 -2
- package/dist/data-display.js +28 -4
- package/dist/data-table-columns.d.ts +25 -0
- package/dist/data-table-columns.js +271 -0
- package/dist/data-table-expansion.d.ts +21 -0
- package/dist/data-table-expansion.js +79 -0
- package/dist/data-table.js +140 -12
- package/dist/date-picker.js +2 -2
- package/dist/date-range-picker.js +2 -2
- package/dist/date-time-picker.js +2 -2
- package/dist/date-time-range-picker.js +2 -2
- package/dist/disclosure.d.ts +2 -1
- package/dist/disclosure.js +4 -4
- package/dist/editable.js +57 -18
- package/dist/filter-condition.d.ts +3 -0
- package/dist/filter-condition.js +21 -0
- package/dist/filter-group.d.ts +2 -0
- package/dist/filter-group.js +62 -0
- package/dist/foundations.css +1131 -93
- package/dist/index.d.ts +469 -5
- package/dist/index.js +72 -9
- package/dist/menu.js +5 -4
- package/dist/menubar.d.ts +2 -0
- package/dist/menubar.js +85 -0
- package/dist/navigation-group.d.ts +3 -0
- package/dist/navigation-group.js +13 -0
- package/dist/navigation-item.d.ts +3 -0
- package/dist/navigation-item.js +68 -0
- package/dist/navigation-layout.d.ts +2 -1
- package/dist/navigation-layout.js +12 -4
- package/dist/navigation-tree.js +51 -7
- package/dist/navigation.js +2 -2
- package/dist/overflow-actions.d.ts +2 -0
- package/dist/overflow-actions.js +75 -0
- package/dist/overlay-runtime.d.ts +6 -2
- package/dist/overlay-runtime.js +41 -5
- package/dist/overlays.d.ts +1 -0
- package/dist/overlays.js +34 -18
- package/dist/select.js +4 -1
- package/dist/sidebar.d.ts +2 -0
- package/dist/sidebar.js +58 -0
- package/dist/sparkline.d.ts +2 -0
- package/dist/sparkline.js +65 -0
- package/dist/toolbar.js +2 -2
- package/package.json +2 -2
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, useEffect, useId, useImperativeHandle, useLayoutEffect, useRef } from 'react';
|
|
3
|
+
import { Button, Fieldset, FilterCondition, IconSlot, Inline, SegmentedControl, Stack } from './index.js';
|
|
4
|
+
const useBrowserLayoutEffect = typeof window === 'undefined' ? useEffect : useLayoutEffect;
|
|
5
|
+
export const PredicateGroup = /* @__PURE__ */ forwardRef(function PredicateGroup({ label, properties, value, onValueChange, controlSize = 'sm', hideLabel = true, disabled = false, allowDuplicateProperties = false, maxConditions, labels, conditionLabels, className, ...props }, forwardedRef) {
|
|
6
|
+
const root = useRef(null), add = useRef(null), serial = useRef(0);
|
|
7
|
+
const generated = useId();
|
|
8
|
+
useImperativeHandle(forwardedRef, () => root.current, []);
|
|
9
|
+
const pending = useRef(null);
|
|
10
|
+
const ids = value.conditions.map(condition => condition.id);
|
|
11
|
+
const source = JSON.stringify(ids);
|
|
12
|
+
if (!label.trim() || !['all', 'any'].includes(value.match) || ids.some(id => !id.trim()) || new Set(ids).size !== ids.length)
|
|
13
|
+
throw new Error('Flood FilterGroup requires a named group, unique condition IDs and a supported match mode');
|
|
14
|
+
if (maxConditions !== undefined && (!Number.isSafeInteger(maxConditions) || maxConditions < 1))
|
|
15
|
+
throw new Error('Flood FilterGroup maxConditions must be a positive safe integer');
|
|
16
|
+
if (new Set(properties.map(property => property.id)).size !== properties.length || properties.some(property => !property.id.trim() || !property.label.trim()))
|
|
17
|
+
throw new Error('Flood FilterGroup properties require unique nonempty IDs and labels');
|
|
18
|
+
const names = { match: 'Match conditions', all: 'All conditions', any: 'Any condition', add: 'Add condition', condition: 'Condition', ...labels };
|
|
19
|
+
if (Object.values(names).some(name => typeof name !== 'string' || !name.trim()))
|
|
20
|
+
throw new Error('Flood FilterGroup control labels must be nonempty');
|
|
21
|
+
const available = properties.filter(property => !property.disabled &&
|
|
22
|
+
(allowDuplicateProperties || !value.conditions.some(condition => condition.property === property.id)));
|
|
23
|
+
const canAdd = !disabled && available.length > 0 && (maxConditions === undefined || ids.length < maxConditions);
|
|
24
|
+
useBrowserLayoutEffect(() => {
|
|
25
|
+
const request = pending.current, node = root.current;
|
|
26
|
+
if (!request || !node)
|
|
27
|
+
return;
|
|
28
|
+
const accepted = request.kind === 'add' ? ids.includes(request.id) : !ids.includes(request.id);
|
|
29
|
+
if (!accepted) {
|
|
30
|
+
if (source !== request.source)
|
|
31
|
+
pending.current = null;
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
pending.current = null;
|
|
35
|
+
const active = node.ownerDocument.activeElement;
|
|
36
|
+
if (active !== request.opener && !(active === node.ownerDocument.body && (!request.opener?.isConnected || request.opener.matches(':disabled'))))
|
|
37
|
+
return;
|
|
38
|
+
const rows = Array.from(node.querySelectorAll('[data-filter-condition-id]'));
|
|
39
|
+
const targetId = request.kind === 'add' ? request.id : ids.includes(request.next ?? '') ? request.next : request.previous;
|
|
40
|
+
const row = rows.find(row => row.dataset.filterConditionId === targetId);
|
|
41
|
+
(row?.querySelector('[role="combobox"]') ?? (add.current?.disabled ? node : add.current))?.focus({ preventScroll: true });
|
|
42
|
+
}, [source]);
|
|
43
|
+
function append() {
|
|
44
|
+
if (!canAdd)
|
|
45
|
+
return;
|
|
46
|
+
let id;
|
|
47
|
+
do {
|
|
48
|
+
id = `${generated}-condition-${++serial.current}`;
|
|
49
|
+
} while (ids.includes(id));
|
|
50
|
+
pending.current = { kind: 'add', id, source, opener: root.current?.ownerDocument.activeElement ?? null };
|
|
51
|
+
onValueChange({ ...value, conditions: [...value.conditions, { id, property: available[0].id, operator: 'is', values: [] }] });
|
|
52
|
+
}
|
|
53
|
+
function remove(id, index) {
|
|
54
|
+
if (disabled)
|
|
55
|
+
return;
|
|
56
|
+
pending.current = { kind: 'remove', id, source, next: ids[index + 1], previous: ids[index - 1], opener: root.current?.ownerDocument.activeElement ?? null };
|
|
57
|
+
onValueChange({ ...value, conditions: value.conditions.filter(condition => condition.id !== id) });
|
|
58
|
+
}
|
|
59
|
+
return _jsx(Fieldset, { ...props, ref: root, tabIndex: props.tabIndex ?? -1, legend: label, hideLabel: hideLabel, disabled: disabled, className: ['flood-filter-group', className].filter(Boolean).join(' '), children: _jsxs(Stack, { gap: "3", children: [ids.length > 1 && _jsx(SegmentedControl, { label: names.match, name: `${generated}-match`, hideLabel: true, controlSize: controlSize, value: value.match, disabled: disabled, options: [{ value: 'all', label: names.all }, { value: 'any', label: names.any }], onValueChange: match => { if (!disabled)
|
|
60
|
+
onValueChange({ ...value, match: match }); } }), value.conditions.map((condition, index) => _jsx(FilterCondition, { "data-filter-condition-id": condition.id, label: `${names.condition} ${index + 1}`, labels: conditionLabels, controlSize: controlSize, disabled: disabled, properties: properties.map(property => ({ ...property, disabled: property.disabled || (!allowDuplicateProperties && value.conditions.some(other => other.id !== condition.id && other.property === property.id)) })), value: condition, onValueChange: next => { if (!disabled)
|
|
61
|
+
onValueChange({ ...value, conditions: value.conditions.map(row => row.id === condition.id ? { ...row, ...next, id: row.id } : row) }); }, onRemove: () => remove(condition.id, index) }, condition.id)), _jsx(Inline, { gap: "2", children: _jsxs(Button, { ref: add, "data-add-condition": true, variant: "subtle", size: controlSize, disabled: !canAdd, onClick: append, children: [_jsx(IconSlot, { size: controlSize, children: _jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", strokeLinecap: "round", "aria-hidden": "true", children: _jsx("path", { d: "M12 5v14M5 12h14" }) }) }), names.add] }) })] }) });
|
|
62
|
+
});
|