@lerianstudio/sindarian-ui 2.0.0-beta.25 → 2.0.0-beta.26
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/charts/chart.js +4 -231
- package/dist/charts/index.js +1 -11
- package/dist/components/breadcrumb/get-breadcrumb-paths.js +1 -18
- package/dist/components/breadcrumb/index.js +1 -37
- package/dist/components/card/account-card/index.js +1 -69
- package/dist/components/card/basic-card/index.js +1 -20
- package/dist/components/card/dashboard-card/index.js +1 -20
- package/dist/components/card/entity-card/index.js +1 -68
- package/dist/components/card/index.js +1 -20
- package/dist/components/dialog/confirmation-dialog/index.js +1 -96
- package/dist/components/dialog/confirmation-dialog/use-confirm-dialog.js +1 -55
- package/dist/components/dialog/index.js +1 -19
- package/dist/components/dialog/large-dialog/index.js +1 -21
- package/dist/components/entity-box/index.js +1 -67
- package/dist/components/entity-data-table/index.js +1 -20
- package/dist/components/form/combo-box-field/index.js +1 -35
- package/dist/components/form/country-field/index.js +1 -11
- package/dist/components/form/date-picker-field/index.js +1 -83
- package/dist/components/form/date-range-field/index.js +1 -58
- package/dist/components/form/date-time-picker-field/index.js +1 -114
- package/dist/components/form/file-upload-field/index.js +1 -69
- package/dist/components/form/index.js +1 -31
- package/dist/components/form/input-field/index.js +1 -96
- package/dist/components/form/otp-field/index.js +1 -19
- package/dist/components/form/pagination-limit-field/index.js +1 -10
- package/dist/components/form/password-field/index.js +1 -16
- package/dist/components/form/radio-group-field/index.js +1 -36
- package/dist/components/form/renderable-label.js +1 -57
- package/dist/components/form/select-field/index.js +1 -68
- package/dist/components/form/state-field/index.js +1 -42
- package/dist/components/form/switch-field/index.js +1 -16
- package/dist/components/form/textarea-field/index.js +1 -23
- package/dist/components/page/index.js +1 -20
- package/dist/components/page-header/index.js +1 -80
- package/dist/components/pagination/index.js +1 -10
- package/dist/components/table/id-table-cell.js +1 -109
- package/dist/components/table/index.js +1 -19
- package/dist/components/table/locked-table-actions.js +1 -41
- package/dist/components/table/name-table-cell.js +1 -58
- package/dist/components/ui/accordion/index.js +1 -62
- package/dist/components/ui/alert/index.js +1 -45
- package/dist/components/ui/alert-dialog/index.js +1 -84
- package/dist/components/ui/autocomplete/index.js +1 -440
- package/dist/components/ui/autosize-textarea/index.js +1 -89
- package/dist/components/ui/avatar/index.js +1 -51
- package/dist/components/ui/badge/index.js +1 -83
- package/dist/components/ui/breadcrumb/index.js +1 -35
- package/dist/components/ui/button/index.js +1 -65
- package/dist/components/ui/calendar/index.js +1 -118
- package/dist/components/ui/card/index.js +1 -32
- package/dist/components/ui/checkbox/index.js +1 -44
- package/dist/components/ui/collapsible/index.js +1 -50
- package/dist/components/ui/command/index.js +1 -95
- package/dist/components/ui/copy-field/index.js +1 -163
- package/dist/components/ui/dialog/index.js +1 -80
- package/dist/components/ui/dropdown-menu/index.js +1 -110
- package/dist/components/ui/field/index.js +1 -82
- package/dist/components/ui/file-upload/index.js +1 -574
- package/dist/components/ui/form.js +1 -162
- package/dist/components/ui/hover-card/index.js +1 -51
- package/dist/components/ui/icon-button/index.js +1 -35
- package/dist/components/ui/input/adornment.js +1 -21
- package/dist/components/ui/input/index.js +1 -99
- package/dist/components/ui/label/index.js +1 -45
- package/dist/components/ui/lerian-wordmark/index.js +1 -7
- package/dist/components/ui/loading-button/index.js +1 -9
- package/dist/components/ui/multiple-select/index.js +1 -235
- package/dist/components/ui/otp-input/index.js +1 -62
- package/dist/components/ui/paper/index.js +1 -8
- package/dist/components/ui/paper-collapsible/index.js +1 -24
- package/dist/components/ui/popover/index.js +1 -55
- package/dist/components/ui/progress/index.js +1 -66
- package/dist/components/ui/qr-code/index.js +1 -27
- package/dist/components/ui/radio-group/index.js +1 -48
- package/dist/components/ui/scroll-area/index.js +1 -49
- package/dist/components/ui/select/index.js +1 -119
- package/dist/components/ui/separator/index.js +1 -43
- package/dist/components/ui/sheet/index.js +1 -136
- package/dist/components/ui/sidebar/index.js +1 -27
- package/dist/components/ui/sidebar/next-router.cjs +1 -119
- package/dist/components/ui/sidebar/sidebar-back-button.js +1 -8
- package/dist/components/ui/sidebar/sidebar-components.js +1 -23
- package/dist/components/ui/sidebar/sidebar-expand-button.js +1 -49
- package/dist/components/ui/sidebar/sidebar-item-button.js +1 -21
- package/dist/components/ui/sidebar/sidebar-item-collapsible.js +1 -52
- package/dist/components/ui/sidebar/sidebar-item-icon-button.js +1 -18
- package/dist/components/ui/sidebar/sidebar-item.js +1 -44
- package/dist/components/ui/sidebar/sidebar-provider.js +1 -201
- package/dist/components/ui/sidebar/sidebar-root.js +1 -130
- package/dist/components/ui/sidebar/sidebar-router.js +1 -126
- package/dist/components/ui/sidebar/sidebar-trigger.js +1 -57
- package/dist/components/ui/skeleton/index.js +1 -8
- package/dist/components/ui/stepper/index.js +1 -29
- package/dist/components/ui/switch/index.js +1 -43
- package/dist/components/ui/table/index.js +1 -56
- package/dist/components/ui/tabs/index.js +1 -55
- package/dist/components/ui/textarea/index.js +1 -8
- package/dist/components/ui/time-picker/index.js +1 -85
- package/dist/components/ui/toast/index.js +1 -3
- package/dist/components/ui/toast/toaster.js +1 -16
- package/dist/components/ui/toggle-group/index.js +1 -156
- package/dist/components/ui/tooltip/index.js +1 -81
- package/dist/domain/blotter/index.js +1 -20
- package/dist/domain/delinquency-aging/aging-buckets.js +1 -120
- package/dist/domain/delinquency-aging/index.js +1 -222
- package/dist/domain/figure/index.js +1 -19
- package/dist/domain/format.js +1 -137
- package/dist/domain/index.js +1 -43
- package/dist/domain/key-id/index.js +1 -174
- package/dist/domain/ledger-sheet/index.js +1 -28
- package/dist/domain/money-diff.js +1 -48
- package/dist/domain/money-math.js +1 -104
- package/dist/domain/money-text/index.js +1 -123
- package/dist/domain/section-label/index.js +1 -17
- package/dist/domain/status-rail/index.js +1 -76
- package/dist/domain/threshold-gauge/index.js +1 -161
- package/dist/enterprise/alert-banner/index.js +1 -24
- package/dist/enterprise/app-shell/index.js +1 -87
- package/dist/enterprise/cursor-pager/index.js +1 -26
- package/dist/enterprise/data-table/column-size.js +1 -103
- package/dist/enterprise/data-table/index.js +1 -345
- package/dist/enterprise/date-range-picker/index.js +1 -115
- package/dist/enterprise/detail-panel/index.js +1 -20
- package/dist/enterprise/empty-state/index.js +1 -14
- package/dist/enterprise/index.js +1 -39
- package/dist/enterprise/number-input/index.js +1 -252
- package/dist/enterprise/search-input/index.js +1 -121
- package/dist/enterprise/stat-card/index.js +1 -75
- package/dist/enterprise/status-badge/index.js +1 -120
- package/dist/enterprise/use-is-mobile.js +1 -68
- package/dist/enterprise/virtualized-table/index.js +1 -141
- package/dist/esm/charts/chart.js +4 -190
- package/dist/esm/charts/index.js +1 -3
- package/dist/esm/components/breadcrumb/get-breadcrumb-paths.js +1 -12
- package/dist/esm/components/breadcrumb/index.js +1 -30
- package/dist/esm/components/card/account-card/index.js +1 -53
- package/dist/esm/components/card/basic-card/index.js +1 -14
- package/dist/esm/components/card/dashboard-card/index.js +1 -14
- package/dist/esm/components/card/entity-card/index.js +1 -52
- package/dist/esm/components/card/index.js +1 -4
- package/dist/esm/components/dialog/confirmation-dialog/index.js +1 -60
- package/dist/esm/components/dialog/confirmation-dialog/use-confirm-dialog.js +1 -49
- package/dist/esm/components/dialog/index.js +1 -3
- package/dist/esm/components/dialog/large-dialog/index.js +1 -16
- package/dist/esm/components/entity-box/index.js +1 -56
- package/dist/esm/components/entity-data-table/index.js +1 -17
- package/dist/esm/components/form/combo-box-field/index.js +1 -28
- package/dist/esm/components/form/country-field/index.js +1 -7
- package/dist/esm/components/form/date-picker-field/index.js +1 -43
- package/dist/esm/components/form/date-range-field/index.js +1 -18
- package/dist/esm/components/form/date-time-picker-field/index.js +1 -74
- package/dist/esm/components/form/file-upload-field/index.js +1 -65
- package/dist/esm/components/form/index.js +1 -15
- package/dist/esm/components/form/input-field/index.js +1 -92
- package/dist/esm/components/form/otp-field/index.js +1 -15
- package/dist/esm/components/form/pagination-limit-field/index.js +1 -6
- package/dist/esm/components/form/password-field/index.js +1 -10
- package/dist/esm/components/form/radio-group-field/index.js +1 -32
- package/dist/esm/components/form/renderable-label.js +1 -54
- package/dist/esm/components/form/select-field/index.js +1 -64
- package/dist/esm/components/form/state-field/index.js +1 -35
- package/dist/esm/components/form/switch-field/index.js +1 -12
- package/dist/esm/components/form/textarea-field/index.js +1 -19
- package/dist/esm/components/page/index.js +1 -15
- package/dist/esm/components/page-header/index.js +1 -71
- package/dist/esm/components/pagination/index.js +1 -6
- package/dist/esm/components/table/id-table-cell.js +1 -105
- package/dist/esm/components/table/index.js +1 -3
- package/dist/esm/components/table/locked-table-actions.js +1 -37
- package/dist/esm/components/table/name-table-cell.js +1 -54
- package/dist/esm/components/ui/accordion/index.js +1 -24
- package/dist/esm/components/ui/alert/index.js +1 -38
- package/dist/esm/components/ui/alert-dialog/index.js +1 -39
- package/dist/esm/components/ui/autocomplete/index.js +1 -392
- package/dist/esm/components/ui/autosize-textarea/index.js +1 -51
- package/dist/esm/components/ui/avatar/index.js +1 -14
- package/dist/esm/components/ui/badge/index.js +1 -79
- package/dist/esm/components/ui/breadcrumb/index.js +1 -27
- package/dist/esm/components/ui/button/index.js +1 -60
- package/dist/esm/components/ui/calendar/index.js +1 -82
- package/dist/esm/components/ui/card/index.js +1 -24
- package/dist/esm/components/ui/checkbox/index.js +1 -9
- package/dist/esm/components/ui/collapsible/index.js +1 -13
- package/dist/esm/components/ui/command/index.js +1 -51
- package/dist/esm/components/ui/copy-field/index.js +1 -127
- package/dist/esm/components/ui/dialog/index.js +1 -36
- package/dist/esm/components/ui/dropdown-menu/index.js +1 -60
- package/dist/esm/components/ui/field/index.js +1 -71
- package/dist/esm/components/ui/file-upload/index.js +1 -536
- package/dist/esm/components/ui/form.js +1 -118
- package/dist/esm/components/ui/hover-card/index.js +1 -14
- package/dist/esm/components/ui/icon-button/index.js +1 -31
- package/dist/esm/components/ui/input/adornment.js +1 -17
- package/dist/esm/components/ui/input/index.js +1 -60
- package/dist/esm/components/ui/label/index.js +1 -10
- package/dist/esm/components/ui/lerian-wordmark/index.js +1 -4
- package/dist/esm/components/ui/loading-button/index.js +1 -7
- package/dist/esm/components/ui/multiple-select/index.js +1 -196
- package/dist/esm/components/ui/otp-input/index.js +1 -21
- package/dist/esm/components/ui/paper/index.js +1 -5
- package/dist/esm/components/ui/paper-collapsible/index.js +1 -19
- package/dist/esm/components/ui/popover/index.js +1 -17
- package/dist/esm/components/ui/progress/index.js +1 -31
- package/dist/esm/components/ui/qr-code/index.js +1 -24
- package/dist/esm/components/ui/radio-group/index.js +1 -12
- package/dist/esm/components/ui/scroll-area/index.js +1 -13
- package/dist/esm/components/ui/select/index.js +1 -74
- package/dist/esm/components/ui/separator/index.js +1 -8
- package/dist/esm/components/ui/sheet/index.js +1 -92
- package/dist/esm/components/ui/sidebar/index.js +1 -11
- package/dist/esm/components/ui/sidebar/next-router.cjs +1 -119
- package/dist/esm/components/ui/sidebar/sidebar-back-button.js +1 -5
- package/dist/esm/components/ui/sidebar/sidebar-components.js +1 -15
- package/dist/esm/components/ui/sidebar/sidebar-expand-button.js +1 -42
- package/dist/esm/components/ui/sidebar/sidebar-item-button.js +1 -18
- package/dist/esm/components/ui/sidebar/sidebar-item-collapsible.js +1 -44
- package/dist/esm/components/ui/sidebar/sidebar-item-icon-button.js +1 -14
- package/dist/esm/components/ui/sidebar/sidebar-item.js +1 -40
- package/dist/esm/components/ui/sidebar/sidebar-provider.js +1 -193
- package/dist/esm/components/ui/sidebar/sidebar-root.js +1 -126
- package/dist/esm/components/ui/sidebar/sidebar-router.js +1 -89
- package/dist/esm/components/ui/sidebar/sidebar-trigger.js +1 -53
- package/dist/esm/components/ui/skeleton/index.js +1 -6
- package/dist/esm/components/ui/stepper/index.js +1 -20
- package/dist/esm/components/ui/switch/index.js +1 -8
- package/dist/esm/components/ui/table/index.js +1 -44
- package/dist/esm/components/ui/tabs/index.js +1 -17
- package/dist/esm/components/ui/textarea/index.js +1 -6
- package/dist/esm/components/ui/time-picker/index.js +1 -49
- package/dist/esm/components/ui/toast/index.js +1 -2
- package/dist/esm/components/ui/toast/toaster.js +1 -13
- package/dist/esm/components/ui/toggle-group/index.js +1 -120
- package/dist/esm/components/ui/tooltip/index.js +1 -43
- package/dist/esm/domain/blotter/index.js +1 -16
- package/dist/esm/domain/delinquency-aging/aging-buckets.js +1 -115
- package/dist/esm/domain/delinquency-aging/index.js +1 -218
- package/dist/esm/domain/figure/index.js +1 -15
- package/dist/esm/domain/format.js +1 -128
- package/dist/esm/domain/index.js +1 -19
- package/dist/esm/domain/key-id/index.js +1 -169
- package/dist/esm/domain/ledger-sheet/index.js +1 -24
- package/dist/esm/domain/money-diff.js +1 -45
- package/dist/esm/domain/money-math.js +1 -98
- package/dist/esm/domain/money-text/index.js +1 -118
- package/dist/esm/domain/section-label/index.js +1 -14
- package/dist/esm/domain/status-rail/index.js +1 -71
- package/dist/esm/domain/threshold-gauge/index.js +1 -157
- package/dist/esm/enterprise/alert-banner/index.js +1 -21
- package/dist/esm/enterprise/app-shell/index.js +1 -51
- package/dist/esm/enterprise/cursor-pager/index.js +1 -23
- package/dist/esm/enterprise/data-table/column-size.js +1 -97
- package/dist/esm/enterprise/data-table/index.js +1 -342
- package/dist/esm/enterprise/date-range-picker/index.js +1 -112
- package/dist/esm/enterprise/detail-panel/index.js +1 -17
- package/dist/esm/enterprise/empty-state/index.js +1 -11
- package/dist/esm/enterprise/index.js +1 -22
- package/dist/esm/enterprise/number-input/index.js +1 -214
- package/dist/esm/enterprise/search-input/index.js +1 -85
- package/dist/esm/enterprise/stat-card/index.js +1 -72
- package/dist/esm/enterprise/status-badge/index.js +1 -116
- package/dist/esm/enterprise/use-is-mobile.js +1 -31
- package/dist/esm/enterprise/virtualized-table/index.js +1 -138
- package/dist/esm/hooks/use-click-away.js +1 -22
- package/dist/esm/hooks/use-pagination.js +1 -38
- package/dist/esm/hooks/use-stepper.js +1 -22
- package/dist/esm/hooks/use-time.js +1 -13
- package/dist/esm/hooks/use-toast.js +1 -107
- package/dist/esm/index.js +1 -77
- package/dist/esm/lib/storage/get-storage-object.js +1 -17
- package/dist/esm/lib/storage/get-storage.js +1 -14
- package/dist/esm/lib/storage/index.js +1 -2
- package/dist/esm/lib/typography.js +1 -31
- package/dist/esm/lib/utils.js +1 -41
- package/dist/esm/theme/get-theme-script.js +1 -41
- package/dist/esm/theme/index.js +1 -4
- package/dist/esm/theme/mode-toggle.js +1 -45
- package/dist/esm/theme/theme-provider.js +1 -122
- package/dist/esm/toast/helpers.js +1 -36
- package/dist/esm/toast/index.js +1 -4
- package/dist/esm/types/metadata-type.js +1 -1
- package/dist/esm/utils/countries.cjs +1 -17
- package/dist/esm/utils/country-utils.js +1 -18
- package/dist/esm/utils/currency-codes.js +1 -181
- package/dist/hooks/use-click-away.js +1 -29
- package/dist/hooks/use-pagination.js +1 -41
- package/dist/hooks/use-stepper.js +1 -26
- package/dist/hooks/use-time.js +1 -20
- package/dist/hooks/use-toast.js +1 -111
- package/dist/index.js +1 -96
- package/dist/lib/storage/get-storage-object.js +1 -23
- package/dist/lib/storage/get-storage.js +1 -17
- package/dist/lib/storage/index.js +1 -18
- package/dist/lib/typography.js +1 -34
- package/dist/lib/utils.js +1 -45
- package/dist/theme/get-theme-script.js +1 -44
- package/dist/theme/index.js +1 -11
- package/dist/theme/mode-toggle.js +1 -48
- package/dist/theme/theme-provider.js +1 -160
- package/dist/toast/helpers.js +1 -41
- package/dist/toast/index.js +1 -10
- package/dist/types/metadata-type.js +1 -2
- package/dist/utils/countries.cjs +1 -17
- package/dist/utils/country-utils.js +1 -25
- package/dist/utils/currency-codes.js +1 -184
- package/package.json +4 -3
|
@@ -1,392 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import * as SelectPrimitive from '@radix-ui/react-select';
|
|
5
|
-
import { ChevronDown, Loader2, X } from 'lucide-react';
|
|
6
|
-
import { Badge } from '../badge/index.js';
|
|
7
|
-
import { cn } from '../../../lib/utils.js';
|
|
8
|
-
import { Separator } from '../separator/index.js';
|
|
9
|
-
import { Command as CommandPrimitive, useCommandState } from 'cmdk';
|
|
10
|
-
import { useClickAway } from '../../../hooks/use-click-away.js';
|
|
11
|
-
import isNil from 'lodash/isNil.js';
|
|
12
|
-
const AutocompleteContext = React.createContext({
|
|
13
|
-
value: [],
|
|
14
|
-
onValueChange: (values) => values,
|
|
15
|
-
handleChange: (value) => value,
|
|
16
|
-
handleClear: () => { },
|
|
17
|
-
setOpen: () => { },
|
|
18
|
-
setOnScrollbar: () => { },
|
|
19
|
-
options: {},
|
|
20
|
-
addOption: (option) => option,
|
|
21
|
-
inputRef: React.createRef()
|
|
22
|
-
});
|
|
23
|
-
const useAutocomplete = () => {
|
|
24
|
-
const context = React.useContext(AutocompleteContext);
|
|
25
|
-
if (!context) {
|
|
26
|
-
throw new Error('useAutocomplete must be used within a AutocompleteProvider');
|
|
27
|
-
}
|
|
28
|
-
return context;
|
|
29
|
-
};
|
|
30
|
-
/**
|
|
31
|
-
* The text a value reads as.
|
|
32
|
-
*
|
|
33
|
-
* An item registers a label only when it HAS one to give: a string child, or an
|
|
34
|
-
* explicit `label` when its children are markup. Everything downstream renders
|
|
35
|
-
* this map as text (the input's value, a chip's `aria-label`), so a value with
|
|
36
|
-
* no registered label falls back to the value itself. The alternatives are both
|
|
37
|
-
* defects that shipped: `undefined` drops a controlled input to uncontrolled,
|
|
38
|
-
* and a React element interpolates into a template literal as "[object
|
|
39
|
-
* Object]".
|
|
40
|
-
*/
|
|
41
|
-
function labelOf(options, value) {
|
|
42
|
-
return options[value] ?? value;
|
|
43
|
-
}
|
|
44
|
-
export function AutocompleteTrigger({ ref, className, onClear, clearLabel = 'Clear', children }) {
|
|
45
|
-
const _ref = React.useRef(null);
|
|
46
|
-
const { open, readOnly, setOpen, disabled, value, inputRef, handleClear } = useAutocomplete();
|
|
47
|
-
React.useImperativeHandle(ref, () => _ref.current);
|
|
48
|
-
const isNoSelection = disabled || readOnly || value.length < 1;
|
|
49
|
-
return (_jsxs("div", { ref: _ref, className: cn(
|
|
50
|
-
// `border-input-border`, NOT `border-input`: `--input` is a SURFACE
|
|
51
|
-
// token and is white in light, so the border it paints is invisible
|
|
52
|
-
// against the field's own `bg-background`. This is the same edge
|
|
53
|
-
// MultipleSelect and DateRangePicker draw, and the same token.
|
|
54
|
-
'bg-background ring-offset-background placeholder:text-input-placeholder data-[disabled=true]:bg-shadcn-100 data-[read-only=true]:bg-shadcn-100 border-input-border flex rounded-md border text-sm focus:outline-hidden focus-visible:outline-hidden data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50 data-[read-only=true]:opacity-50 md:text-sm [&>span]:line-clamp-1', {
|
|
55
|
-
'h-9': value.length === 0,
|
|
56
|
-
'min-h-9': value.length > 0,
|
|
57
|
-
'cursor-text': !disabled && value.length !== 0
|
|
58
|
-
}, className), onClick: () => {
|
|
59
|
-
// Redirect focus to the input field when clicking on the container
|
|
60
|
-
if (readOnly || disabled) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
if (open) {
|
|
64
|
-
inputRef?.current?.blur();
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
inputRef?.current?.focus();
|
|
68
|
-
}
|
|
69
|
-
setOpen(!open);
|
|
70
|
-
}, "data-disabled": disabled, "data-read-only": readOnly, children: [_jsx("div", { className: "flex grow flex-wrap gap-1 px-3 py-2", children: children }), _jsxs("div", { className: "flex shrink-0 items-center justify-end", children: [_jsx("button", { type: "button", "aria-label": clearLabel, className: cn('cursor-pointer', isNoSelection && 'hidden'), onKeyDown: (event) => {
|
|
71
|
-
// cmdk's Command root calls preventDefault() on EVERY Enter that
|
|
72
|
-
// reaches it, which cancels this button's implicit activation, so
|
|
73
|
-
// the keydown must not get there. Enter only: the root's other
|
|
74
|
-
// keys (Escape, the arrows) still belong to the panel.
|
|
75
|
-
if (event.key === 'Enter') {
|
|
76
|
-
event.stopPropagation();
|
|
77
|
-
}
|
|
78
|
-
}, onClick: (event) => {
|
|
79
|
-
event.stopPropagation();
|
|
80
|
-
handleClear();
|
|
81
|
-
onClear?.();
|
|
82
|
-
}, children: _jsx(X, { "aria-hidden": true, className: "text-muted-foreground mx-2 h-4" }) }), _jsx(Separator, { orientation: "vertical", className: cn(isNoSelection && 'hidden') }), _jsx(SelectPrimitive.Icon, { className: "cursor-pointer data-[disabled=true]:cursor-not-allowed data-[read-only=true]:cursor-default", "data-disabled": disabled, "data-read-only": readOnly, children: _jsx(ChevronDown, { className: "mx-3 my-2 h-4 w-4 opacity-50" }) })] })] }));
|
|
83
|
-
}
|
|
84
|
-
export function AutocompleteValue({ ref, className, value: valueProp, onValueChange, onBlur, ...props }) {
|
|
85
|
-
const [search, setSearch] = React.useState(valueProp);
|
|
86
|
-
const { value, showValue, options, readOnly, disabled, inputRef } = useAutocomplete();
|
|
87
|
-
React.useImperativeHandle(ref, () => inputRef.current);
|
|
88
|
-
const updateSearch = (value) => {
|
|
89
|
-
if (isNil(value)) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
const v = typeof value === 'string' ? value : value[0];
|
|
93
|
-
if (v === '') {
|
|
94
|
-
handleValueChange('');
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
handleValueChange(showValue ? v : labelOf(options, v));
|
|
98
|
-
};
|
|
99
|
-
const handleValueChange = (value) => {
|
|
100
|
-
setSearch(value);
|
|
101
|
-
onValueChange?.(value);
|
|
102
|
-
};
|
|
103
|
-
const handleBlur = (event) => {
|
|
104
|
-
updateSearch(value);
|
|
105
|
-
onBlur?.(event);
|
|
106
|
-
};
|
|
107
|
-
// If options changes, update only the internal value
|
|
108
|
-
React.useEffect(() => {
|
|
109
|
-
if (isNil(value)) {
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
const v = typeof value === 'string' ? value : value[0];
|
|
113
|
-
if (v === '') {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
setSearch(showValue ? v : labelOf(options, v));
|
|
117
|
-
}, [options]);
|
|
118
|
-
React.useEffect(() => {
|
|
119
|
-
updateSearch(value);
|
|
120
|
-
}, [value]);
|
|
121
|
-
return (_jsx(CommandPrimitive.Input, { ...props, ref: inputRef, value: search, onValueChange: handleValueChange, disabled: disabled, readOnly: readOnly, className: cn('placeholder:text-muted-foreground w-full bg-transparent outline-hidden read-only:opacity-50 read-only:placeholder:opacity-0 focus:outline-hidden disabled:cursor-not-allowed disabled:opacity-50 disabled:placeholder:opacity-0', className), onBlur: handleBlur }));
|
|
122
|
-
}
|
|
123
|
-
export function AutocompleteMultipleValue({ ref, className, clearLabel = 'Clear', ...props }) {
|
|
124
|
-
const { value, disabled, handleChange, options, showValue, inputRef } = useAutocomplete();
|
|
125
|
-
React.useImperativeHandle(ref, () => inputRef.current);
|
|
126
|
-
return (_jsxs(_Fragment, { children: [options &&
|
|
127
|
-
value?.map((value) => (_jsxs(Badge, { variant: "secondary", className: cn('data-disabled:bg-muted-foreground data-fixed:bg-muted-foreground data-disabled:text-muted data-fixed:text-muted data-disabled:hover:bg-muted-foreground data-fixed:hover:bg-muted-foreground'), children: [showValue ? value : labelOf(options, value), _jsx("button", { type: "button", "aria-label": `${clearLabel} ${showValue ? value : labelOf(options, value)}`, className: cn('ring-offset-background focus:ring-ring ml-1 rounded-full outline-hidden focus:ring-2 focus:ring-offset-2', disabled && 'hidden'), onKeyDown: (event) => {
|
|
128
|
-
// cmdk's Command root calls preventDefault() on EVERY Enter that
|
|
129
|
-
// reaches it, which cancels this button's implicit activation, so
|
|
130
|
-
// the keydown must not get there. Enter only: the root's other
|
|
131
|
-
// keys (Escape, the arrows) still belong to the panel.
|
|
132
|
-
if (event.key === 'Enter') {
|
|
133
|
-
event.stopPropagation();
|
|
134
|
-
}
|
|
135
|
-
}, onClick: (event) => {
|
|
136
|
-
event.stopPropagation();
|
|
137
|
-
handleChange(value);
|
|
138
|
-
}, children: _jsx(X, { "aria-hidden": true, className: "text-muted-foreground hover:text-foreground h-3 w-3" }) })] }, value))), _jsx(CommandPrimitive.Input, { ...props, ref: inputRef, disabled: disabled, className: cn('placeholder:text-muted-foreground w-full bg-transparent outline-hidden focus:outline-hidden disabled:cursor-not-allowed disabled:opacity-50 disabled:placeholder:opacity-0', className) })] }));
|
|
139
|
-
}
|
|
140
|
-
export function AutocompleteEmpty({ className, ...props }) {
|
|
141
|
-
const render = useCommandState((state) => state.filtered.count === 0);
|
|
142
|
-
if (!render)
|
|
143
|
-
return null;
|
|
144
|
-
return (_jsx("div", { "data-slot": "autocomplete-empty", className: cn('py-6 text-center text-sm', className), "cmdk-empty": "", role: "presentation", ...props }));
|
|
145
|
-
}
|
|
146
|
-
export function AutocompleteLoading({ className, ref, ...props }) {
|
|
147
|
-
return (_jsx(CommandPrimitive.Loading, { ref: ref, "data-slot": "autocomplete-loading", className: cn('flex items-center justify-center py-6 text-center text-sm', className), ...props, children: _jsx(Loader2, { className: "text-muted-foreground h-5 w-5 motion-safe:animate-spin" }) }));
|
|
148
|
-
}
|
|
149
|
-
export const SIDE_OPTIONS = ['top', 'right', 'bottom', 'left'];
|
|
150
|
-
export function AutocompleteContent({ className, position = 'popper', side = 'bottom', ref, children, onMouseEnter, onMouseLeave, onPointerDownOutside, ...props }) {
|
|
151
|
-
const _ref = React.useRef(null);
|
|
152
|
-
const { open, addOption, setOpen, onScrollbar, setOnScrollbar, inputRef } = useAutocomplete();
|
|
153
|
-
React.useImperativeHandle(ref, () => _ref.current);
|
|
154
|
-
useClickAway(_ref, (event) => {
|
|
155
|
-
/**
|
|
156
|
-
* ⛔ THE `open` GUARD IS LOAD-BEARING SINCE THIS LIST STOPPED UNMOUNTING.
|
|
157
|
-
* While the panel returned `null` this handler was inert by accident: its
|
|
158
|
-
* ref pointed at nothing. Now that the list stays in the DOM (see the return
|
|
159
|
-
* below), every click anywhere on the page reaches here — and without this
|
|
160
|
-
* line each one would call `setOpen(false)` and blur the input. A consumer
|
|
161
|
-
* form carrying ten of these would run ten handlers per click.
|
|
162
|
-
*/
|
|
163
|
-
if (!open) {
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
// Should not close when clicking on the scrollbar
|
|
167
|
-
if (onScrollbar) {
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
setOpen(false);
|
|
171
|
-
inputRef.current?.blur();
|
|
172
|
-
onPointerDownOutside?.(event);
|
|
173
|
-
});
|
|
174
|
-
/**
|
|
175
|
-
* Iterates recursively into react children to find valid items options
|
|
176
|
-
* Adds the valid ones into the options object
|
|
177
|
-
* @param children
|
|
178
|
-
*/
|
|
179
|
-
const _searchChildren = (children) => {
|
|
180
|
-
React.Children.forEach(React.Children.toArray(children), (child) => {
|
|
181
|
-
// If child is already invalid, like pure string, dismiss
|
|
182
|
-
if (!React.isValidElement(child)) {
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
// If child is recognized as an AutocompleteItem
|
|
186
|
-
if (child.type &&
|
|
187
|
-
child.type.displayName === 'AutocompleteItem') {
|
|
188
|
-
// Check if the item was proper filled with a value prop
|
|
189
|
-
if (child.props.value) {
|
|
190
|
-
// NOT `children as string`. That cast is how a React ELEMENT got into
|
|
191
|
-
// a map every reader treats as text. An item with markup children
|
|
192
|
-
// registers nothing unless it declares a `label`, and `labelOf` reads
|
|
193
|
-
// the absence as "use the value".
|
|
194
|
-
const { label, children: itemChildren } = child.props;
|
|
195
|
-
const text = label ??
|
|
196
|
-
(typeof itemChildren === 'string' ? itemChildren : undefined);
|
|
197
|
-
if (text !== undefined) {
|
|
198
|
-
addOption({ [child.props.value]: text });
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
// If not, search recursively into the childrens
|
|
204
|
-
if (child.props.children) {
|
|
205
|
-
_searchChildren(child.props.children);
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
};
|
|
209
|
-
// Since this component is not going to be rendered in the DOM until open is true,
|
|
210
|
-
// we need to register the options when the component mounts
|
|
211
|
-
// and when the children changes.
|
|
212
|
-
React.useEffect(() => {
|
|
213
|
-
_searchChildren(children);
|
|
214
|
-
}, [children]);
|
|
215
|
-
/**
|
|
216
|
-
* ⛔ THE LIST STAYS IN THE DOM, THE OPTIONS DO NOT — and the split is the whole
|
|
217
|
-
* fix (#150).
|
|
218
|
-
*
|
|
219
|
-
* cmdk puts `aria-controls={listId}` on the input it renders and `id={listId}`
|
|
220
|
-
* on this list. Returning `null` while closed therefore left the input naming
|
|
221
|
-
* an element that did not exist, which axe-core reports as a CRITICAL
|
|
222
|
-
* `aria-valid-attr-value` violation — measured as 10 failing cases across five
|
|
223
|
-
* forms in a consumer, in both the populated and the empty state. A screen
|
|
224
|
-
* reader following the reference resolved it to nothing.
|
|
225
|
-
*
|
|
226
|
-
* ⛔ AND NOT "KEEP EVERYTHING MOUNTED", which is the obvious reading of the
|
|
227
|
-
* fix and is too expensive. Only the LIST carries the id; the options carry
|
|
228
|
-
* the cost. One consumer form puts up to ten of these on screen, each holding
|
|
229
|
-
* a page of up to a hundred options — roughly a thousand permanently present
|
|
230
|
-
* nodes for an id that is one element. `{open ? children : null}` keeps the
|
|
231
|
-
* reference resolvable and the DOM the size it was.
|
|
232
|
-
*
|
|
233
|
-
* ⚠️ `hidden` AND NOT A CLASS. It removes the subtree from the accessibility
|
|
234
|
-
* tree as well as from view, so a closed panel is not an empty `listbox` that
|
|
235
|
-
* a screen reader can reach into.
|
|
236
|
-
*
|
|
237
|
-
* ⚠️ THE ENTRY ANIMATION IS NOT LOST, because there was none to lose: the
|
|
238
|
-
* className carries `animate-in` with no `fade-in-*` / `zoom-in-*` / `slide-in-*`
|
|
239
|
-
* companion, so every `--tw-enter-*` variable sits at its default and the
|
|
240
|
-
* keyframe is a no-op today. Should a real one be added later, it belongs on a
|
|
241
|
-
* wrapper INSIDE this list — that subtree still mounts with the children.
|
|
242
|
-
*/
|
|
243
|
-
return (_jsx("div", { className: "relative", hidden: !open, children: _jsx(CommandPrimitive.List, { ref: _ref, className: cn('bg-popover text-popover-foreground motion-safe:animate-in absolute top-1 z-50 max-h-96 w-full min-w-32 overflow-x-hidden overflow-y-auto rounded-md border shadow-md outline-hidden', position === 'popper' &&
|
|
244
|
-
'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1', className), "data-side": side, ...props, onMouseEnter: (e) => {
|
|
245
|
-
onMouseEnter?.(e);
|
|
246
|
-
setOnScrollbar(true);
|
|
247
|
-
}, onMouseLeave: (e) => {
|
|
248
|
-
onMouseLeave?.(e);
|
|
249
|
-
setOnScrollbar(false);
|
|
250
|
-
}, children: open ? children : null }) }));
|
|
251
|
-
}
|
|
252
|
-
export function AutocompleteGroup({ className, ...props }) {
|
|
253
|
-
return (_jsx(CommandPrimitive.Group, { "data-slot": "autocomplete-group", className: cn('text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium', className), ...props }));
|
|
254
|
-
}
|
|
255
|
-
export function AutocompleteItem({ className, value,
|
|
256
|
-
// Read off the element by `AutocompleteContent._searchChildren`, never
|
|
257
|
-
// rendered: destructured here only to keep it out of `...props` and off the
|
|
258
|
-
// div cmdk spreads them onto.
|
|
259
|
-
label: _label, onSelect, ...props }) {
|
|
260
|
-
const { handleChange } = useAutocomplete();
|
|
261
|
-
return (_jsx(CommandPrimitive.Item, { "data-slot": "autocomplete-item", value: value, className: cn("data-[selected='true']:bg-accent data-[selected=true]:text-accent-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", className), ...props, onMouseDown: (e) => {
|
|
262
|
-
e.preventDefault();
|
|
263
|
-
e.stopPropagation();
|
|
264
|
-
}, onSelect: (value) => {
|
|
265
|
-
handleChange(value);
|
|
266
|
-
onSelect?.(value);
|
|
267
|
-
} }));
|
|
268
|
-
}
|
|
269
|
-
/**
|
|
270
|
-
* ⛔ LOAD-BEARING, NOT A DEBUG LABEL. `AutocompleteContent._searchChildren`
|
|
271
|
-
* recognises an option by `child.type.displayName === 'AutocompleteItem'`, and
|
|
272
|
-
* a function component carries no displayName unless it is assigned one. It
|
|
273
|
-
* never was, so the walk matched nothing and the option registry stayed empty
|
|
274
|
-
* for every consumer: a multiple-select chip rendered `options[value]` as
|
|
275
|
-
* `undefined` (an empty chip), and `AutocompleteValue.updateSearch` set the
|
|
276
|
-
* input to `undefined` on every selection outside `showValue` mode.
|
|
277
|
-
*/
|
|
278
|
-
AutocompleteItem.displayName = 'AutocompleteItem';
|
|
279
|
-
export function Autocomplete({ ref, value, defaultValue, onValueChange, onClear, className, open: openProp, onOpenChange, showValue, readOnly, disabled, multiple, onKeyDown, children, ...props }) {
|
|
280
|
-
const _ref = React.useRef(null);
|
|
281
|
-
const [open, _setOpen] = React.useState(openProp);
|
|
282
|
-
const inputRef = React.useRef(null);
|
|
283
|
-
const [onScrollbar, setOnScrollbar] = React.useState(false);
|
|
284
|
-
const [selected, setSelected] = React.useState(defaultValue ?? value ?? (multiple ? [] : ''));
|
|
285
|
-
const [options, addOption] = React.useReducer((prev, state) => ({
|
|
286
|
-
...prev,
|
|
287
|
-
...state
|
|
288
|
-
}), {});
|
|
289
|
-
React.useImperativeHandle(ref, () => _ref.current);
|
|
290
|
-
const setOpen = (open) => {
|
|
291
|
-
_setOpen(open);
|
|
292
|
-
onOpenChange?.(open);
|
|
293
|
-
};
|
|
294
|
-
const handleClear = () => {
|
|
295
|
-
onClear?.();
|
|
296
|
-
if (!multiple) {
|
|
297
|
-
setSelected('');
|
|
298
|
-
onValueChange?.('');
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
setSelected([]);
|
|
302
|
-
onValueChange?.([]);
|
|
303
|
-
};
|
|
304
|
-
const handleChange = React.useCallback((value) => {
|
|
305
|
-
if (!value) {
|
|
306
|
-
return;
|
|
307
|
-
}
|
|
308
|
-
if (!multiple) {
|
|
309
|
-
setSelected(value);
|
|
310
|
-
onValueChange?.(value);
|
|
311
|
-
setOpen(false);
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
const newSelected = selected.includes(value)
|
|
315
|
-
? selected.filter((item) => item !== value)
|
|
316
|
-
: [...selected, value];
|
|
317
|
-
setSelected(newSelected);
|
|
318
|
-
onValueChange?.(newSelected);
|
|
319
|
-
}, [selected, onValueChange]);
|
|
320
|
-
const handleKeyDown = React.useCallback((e) => {
|
|
321
|
-
const input = inputRef.current;
|
|
322
|
-
if (input) {
|
|
323
|
-
if (e.key === 'Delete' || e.key === 'Backspace') {
|
|
324
|
-
if (multiple) {
|
|
325
|
-
if (input.value === '' && selected.length > 0) {
|
|
326
|
-
handleChange(selected[selected.length - 1]);
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
// This is not a default behavior of the <input /> field
|
|
331
|
-
if (e.key === 'Escape') {
|
|
332
|
-
e.stopPropagation();
|
|
333
|
-
input.blur();
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
}, [selected, handleChange]);
|
|
337
|
-
// Keeps the selected value in sync with the value prop
|
|
338
|
-
React.useEffect(() => {
|
|
339
|
-
if (!isNil(value)) {
|
|
340
|
-
setSelected(value);
|
|
341
|
-
}
|
|
342
|
-
}, [value]);
|
|
343
|
-
// Keeps the open state in sync with the open prop
|
|
344
|
-
React.useEffect(() => {
|
|
345
|
-
if (openProp !== undefined) {
|
|
346
|
-
setOpen(openProp);
|
|
347
|
-
}
|
|
348
|
-
}, [openProp]);
|
|
349
|
-
return (_jsx(AutocompleteContext.Provider, { value: {
|
|
350
|
-
value: selected,
|
|
351
|
-
onValueChange: setSelected,
|
|
352
|
-
showValue,
|
|
353
|
-
readOnly,
|
|
354
|
-
disabled,
|
|
355
|
-
handleChange,
|
|
356
|
-
handleClear,
|
|
357
|
-
onScrollbar,
|
|
358
|
-
setOnScrollbar,
|
|
359
|
-
open,
|
|
360
|
-
setOpen,
|
|
361
|
-
options,
|
|
362
|
-
addOption,
|
|
363
|
-
inputRef
|
|
364
|
-
}, children: _jsx(CommandPrimitive, { ref: _ref, className: cn('text-foreground flex h-auto w-full flex-col overflow-visible rounded-md bg-transparent', className), "data-disabled": disabled, "aria-disabled": disabled, "data-read-only": readOnly, "aria-readonly": readOnly, ...props, onKeyDown: (e) => {
|
|
365
|
-
handleKeyDown(e);
|
|
366
|
-
onKeyDown?.(e);
|
|
367
|
-
}, children: children }) }));
|
|
368
|
-
}
|
|
369
|
-
/**
|
|
370
|
-
* ⛔ THE REST OF THE SET, FOR THE SAME REASON AS `AutocompleteItem` ABOVE.
|
|
371
|
-
*
|
|
372
|
-
* A function component's `name` is whatever the bundler left it — one letter in
|
|
373
|
-
* a production build — so any lookup written against `child.type` needs an
|
|
374
|
-
* explicit string to compare. `AutocompleteItem` is the only part the walk
|
|
375
|
-
* reads TODAY, and it is the part that shipped an empty option registry to
|
|
376
|
-
* every consumer while it was anonymous. Naming the whole set costs a line each
|
|
377
|
-
* and removes the next instance of that defect before it is written; it also
|
|
378
|
-
* makes these parts legible in a React tree, which `MultipleSelect` next door
|
|
379
|
-
* has always done.
|
|
380
|
-
*
|
|
381
|
-
* `__tests__`-style enumeration lives in `autocomplete.test.tsx`: it reads the
|
|
382
|
-
* module's exports rather than a list, so a new part added without a name fails
|
|
383
|
-
* without anyone remembering to extend anything.
|
|
384
|
-
*/
|
|
385
|
-
Autocomplete.displayName = 'Autocomplete';
|
|
386
|
-
AutocompleteTrigger.displayName = 'AutocompleteTrigger';
|
|
387
|
-
AutocompleteValue.displayName = 'AutocompleteValue';
|
|
388
|
-
AutocompleteMultipleValue.displayName = 'AutocompleteMultipleValue';
|
|
389
|
-
AutocompleteContent.displayName = 'AutocompleteContent';
|
|
390
|
-
AutocompleteGroup.displayName = 'AutocompleteGroup';
|
|
391
|
-
AutocompleteEmpty.displayName = 'AutocompleteEmpty';
|
|
392
|
-
AutocompleteLoading.displayName = 'AutocompleteLoading';
|
|
1
|
+
"use client";import{jsx as s,jsxs as O,Fragment as T}from"react/jsx-runtime";import t from"react";import*as z from"@radix-ui/react-select";import{ChevronDown as F,Loader2 as $,X as j}from"lucide-react";import{Badge as X}from"../badge/index.js";import{cn as b}from"../../../lib/utils.js";import{Separator as q}from"../separator/index.js";import{Command as A,useCommandState as J}from"cmdk";import{useClickAway as Q}from"../../../hooks/use-click-away.js";import V from"lodash/isNil.js";const L=t.createContext({value:[],onValueChange:e=>e,handleChange:e=>e,handleClear:()=>{},setOpen:()=>{},setOnScrollbar:()=>{},options:{},addOption:e=>e,inputRef:t.createRef()});const _=()=>{const e=t.useContext(L);if(!e){throw new Error("useAutocomplete must be used within a AutocompleteProvider")}return e};function I(e,o){return e[o]??o}export function AutocompleteTrigger({ref:e,className:o,onClear:f,clearLabel:i="Clear",children:h}){const g=t.useRef(null);const{open:a,readOnly:p,setOpen:u,disabled:d,value:r,inputRef:c,handleClear:C}=_();t.useImperativeHandle(e,()=>g.current);const N=d||p||r.length<1;return O("div",{ref:g,className:b("bg-background ring-offset-background placeholder:text-input-placeholder data-[disabled=true]:bg-shadcn-100 data-[read-only=true]:bg-shadcn-100 border-input-border flex rounded-md border text-sm focus:outline-hidden focus-visible:outline-hidden data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50 data-[read-only=true]:opacity-50 md:text-sm [&>span]:line-clamp-1",{"h-9":r.length===0,"min-h-9":r.length>0,"cursor-text":!d&&r.length!==0},o),onClick:()=>{if(p||d){return}if(a){c?.current?.blur()}else{c?.current?.focus()}u(!a)},"data-disabled":d,"data-read-only":p,children:[s("div",{className:"flex grow flex-wrap gap-1 px-3 py-2",children:h}),O("div",{className:"flex shrink-0 items-center justify-end",children:[s("button",{type:"button","aria-label":i,className:b("cursor-pointer",N&&"hidden"),onKeyDown:y=>{if(y.key==="Enter"){y.stopPropagation()}},onClick:y=>{y.stopPropagation();C();f?.()},children:s(j,{"aria-hidden":true,className:"text-muted-foreground mx-2 h-4"})}),s(q,{orientation:"vertical",className:b(N&&"hidden")}),s(z.Icon,{className:"cursor-pointer data-[disabled=true]:cursor-not-allowed data-[read-only=true]:cursor-default","data-disabled":d,"data-read-only":p,children:s(F,{className:"mx-3 my-2 h-4 w-4 opacity-50"})})]})]})}export function AutocompleteValue({ref:e,className:o,value:f,onValueChange:i,onBlur:h,...g}){const[a,p]=t.useState(f);const{value:u,showValue:d,options:r,readOnly:c,disabled:C,inputRef:N}=_();t.useImperativeHandle(e,()=>N.current);const y=n=>{if(V(n)){return}const m=typeof n==="string"?n:n[0];if(m===""){w("");return}w(d?m:I(r,m))};const w=n=>{p(n);i?.(n)};const k=n=>{y(u);h?.(n)};t.useEffect(()=>{if(V(u)){return}const n=typeof u==="string"?u:u[0];if(n===""){return}p(d?n:I(r,n))},[r]);t.useEffect(()=>{y(u)},[u]);return s(A.Input,{...g,ref:N,value:a,onValueChange:w,disabled:C,readOnly:c,className:b("placeholder:text-muted-foreground w-full bg-transparent outline-hidden read-only:opacity-50 read-only:placeholder:opacity-0 focus:outline-hidden disabled:cursor-not-allowed disabled:opacity-50 disabled:placeholder:opacity-0",o),onBlur:k})}export function AutocompleteMultipleValue({ref:e,className:o,clearLabel:f="Clear",...i}){const{value:h,disabled:g,handleChange:a,options:p,showValue:u,inputRef:d}=_();t.useImperativeHandle(e,()=>d.current);return O(T,{children:[p&&h?.map(r=>O(X,{variant:"secondary",className:b("data-disabled:bg-muted-foreground data-fixed:bg-muted-foreground data-disabled:text-muted data-fixed:text-muted data-disabled:hover:bg-muted-foreground data-fixed:hover:bg-muted-foreground"),children:[u?r:I(p,r),s("button",{type:"button","aria-label":`${f} ${u?r:I(p,r)}`,className:b("ring-offset-background focus:ring-ring ml-1 rounded-full outline-hidden focus:ring-2 focus:ring-offset-2",g&&"hidden"),onKeyDown:c=>{if(c.key==="Enter"){c.stopPropagation()}},onClick:c=>{c.stopPropagation();a(r)},children:s(j,{"aria-hidden":true,className:"text-muted-foreground hover:text-foreground h-3 w-3"})})]},r)),s(A.Input,{...i,ref:d,disabled:g,className:b("placeholder:text-muted-foreground w-full bg-transparent outline-hidden focus:outline-hidden disabled:cursor-not-allowed disabled:opacity-50 disabled:placeholder:opacity-0",o)})]})}export function AutocompleteEmpty({className:e,...o}){const f=J(i=>i.filtered.count===0);if(!f)return null;return s("div",{"data-slot":"autocomplete-empty",className:b("py-6 text-center text-sm",e),"cmdk-empty":"",role:"presentation",...o})}export function AutocompleteLoading({className:e,ref:o,...f}){return s(A.Loading,{ref:o,"data-slot":"autocomplete-loading",className:b("flex items-center justify-center py-6 text-center text-sm",e),...f,children:s($,{className:"text-muted-foreground h-5 w-5 motion-safe:animate-spin"})})}export const SIDE_OPTIONS=["top","right","bottom","left"];export function AutocompleteContent({className:e,position:o="popper",side:f="bottom",ref:i,children:h,onMouseEnter:g,onMouseLeave:a,onPointerDownOutside:p,...u}){const d=t.useRef(null);const{open:r,addOption:c,setOpen:C,onScrollbar:N,setOnScrollbar:y,inputRef:w}=_();t.useImperativeHandle(i,()=>d.current);Q(d,n=>{if(!r){return}if(N){return}C(false);w.current?.blur();p?.(n)});const k=n=>{t.Children.forEach(t.Children.toArray(n),m=>{if(!t.isValidElement(m)){return}if(m.type&&m.type.displayName==="AutocompleteItem"){if(m.props.value){const{label:R,children:E}=m.props;const x=R??(typeof E==="string"?E:void 0);if(x!==void 0){c({[m.props.value]:x})}}return}if(m.props.children){k(m.props.children)}})};t.useEffect(()=>{k(h)},[h]);return s("div",{className:"relative",hidden:!r,children:s(A.List,{ref:d,className:b("bg-popover text-popover-foreground motion-safe:animate-in absolute top-1 z-50 max-h-96 w-full min-w-32 overflow-x-hidden overflow-y-auto rounded-md border shadow-md outline-hidden",o==="popper"&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",e),"data-side":f,...u,onMouseEnter:n=>{g?.(n);y(true)},onMouseLeave:n=>{a?.(n);y(false)},children:r?h:null})})}export function AutocompleteGroup({className:e,...o}){return s(A.Group,{"data-slot":"autocomplete-group",className:b("text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium",e),...o})}export function AutocompleteItem({className:e,value:o,label:f,onSelect:i,...h}){const{handleChange:g}=_();return s(A.Item,{"data-slot":"autocomplete-item",value:o,className:b("data-[selected='true']:bg-accent data-[selected=true]:text-accent-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",e),...h,onMouseDown:a=>{a.preventDefault();a.stopPropagation()},onSelect:a=>{g(a);i?.(a)}})}AutocompleteItem.displayName="AutocompleteItem";export function Autocomplete({ref:e,value:o,defaultValue:f,onValueChange:i,onClear:h,className:g,open:a,onOpenChange:p,showValue:u,readOnly:d,disabled:r,multiple:c,onKeyDown:C,children:N,...y}){const w=t.useRef(null);const[k,n]=t.useState(a);const m=t.useRef(null);const[R,E]=t.useState(false);const[x,S]=t.useState(f??o??(c?[]:""));const[H,M]=t.useReducer((l,v)=>({...l,...v}),{});t.useImperativeHandle(e,()=>w.current);const D=l=>{n(l);p?.(l)};const B=()=>{h?.();if(!c){S("");i?.("");return}S([]);i?.([])};const P=t.useCallback(l=>{if(!l){return}if(!c){S(l);i?.(l);D(false);return}const v=x.includes(l)?x.filter(G=>G!==l):[...x,l];S(v);i?.(v)},[x,i]);const K=t.useCallback(l=>{const v=m.current;if(v){if(l.key==="Delete"||l.key==="Backspace"){if(c){if(v.value===""&&x.length>0){P(x[x.length-1])}}}if(l.key==="Escape"){l.stopPropagation();v.blur()}}},[x,P]);t.useEffect(()=>{if(!V(o)){S(o)}},[o]);t.useEffect(()=>{if(a!==void 0){D(a)}},[a]);return s(L.Provider,{value:{value:x,onValueChange:S,showValue:u,readOnly:d,disabled:r,handleChange:P,handleClear:B,onScrollbar:R,setOnScrollbar:E,open:k,setOpen:D,options:H,addOption:M,inputRef:m},children:s(A,{ref:w,className:b("text-foreground flex h-auto w-full flex-col overflow-visible rounded-md bg-transparent",g),"data-disabled":r,"aria-disabled":r,"data-read-only":d,"aria-readonly":d,...y,onKeyDown:l=>{K(l);C?.(l)},children:N})})}Autocomplete.displayName="Autocomplete";AutocompleteTrigger.displayName="AutocompleteTrigger";AutocompleteValue.displayName="AutocompleteValue";AutocompleteMultipleValue.displayName="AutocompleteMultipleValue";AutocompleteContent.displayName="AutocompleteContent";AutocompleteGroup.displayName="AutocompleteGroup";AutocompleteEmpty.displayName="AutocompleteEmpty";AutocompleteLoading.displayName="AutocompleteLoading";
|
|
@@ -1,51 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import * as React from 'react';
|
|
4
|
-
import { cn } from '../../../lib/utils.js';
|
|
5
|
-
import { useImperativeHandle } from 'react';
|
|
6
|
-
export const useAutosizeTextArea = ({ textAreaRef, triggerAutoSize, maxHeight = Number.MAX_SAFE_INTEGER, minHeight = 0 }) => {
|
|
7
|
-
const [init, setInit] = React.useState(true);
|
|
8
|
-
React.useEffect(() => {
|
|
9
|
-
// We need to reset the height momentarily to get the correct scrollHeight for the textarea
|
|
10
|
-
const textAreaElement = textAreaRef.current;
|
|
11
|
-
if (textAreaElement) {
|
|
12
|
-
if (init) {
|
|
13
|
-
textAreaElement.style.minHeight = `${minHeight}px`;
|
|
14
|
-
if (maxHeight > minHeight) {
|
|
15
|
-
textAreaElement.style.maxHeight = `${maxHeight}px`;
|
|
16
|
-
}
|
|
17
|
-
setInit(false);
|
|
18
|
-
}
|
|
19
|
-
textAreaElement.style.height = `${minHeight}px`;
|
|
20
|
-
const scrollHeight = textAreaElement.scrollHeight;
|
|
21
|
-
// We then set the height directly, outside of the render loop
|
|
22
|
-
// Trying to set this with state or a ref will segment an incorrect value.
|
|
23
|
-
if (scrollHeight > maxHeight) {
|
|
24
|
-
textAreaElement.style.height = `${maxHeight}px`;
|
|
25
|
-
textAreaElement.style.overflowY = 'auto';
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
textAreaElement.style.height = `${scrollHeight}px`;
|
|
29
|
-
textAreaElement.style.overflowY = 'hidden';
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}, [textAreaRef.current, triggerAutoSize]);
|
|
33
|
-
};
|
|
34
|
-
export function AutosizeTextarea({ maxHeight = Number.MAX_SAFE_INTEGER, minHeight = 36, className, onChange, value, ref, ...props }) {
|
|
35
|
-
const textAreaRef = React.useRef(null);
|
|
36
|
-
const [triggerAutoSize, setTriggerAutoSize] = React.useState('');
|
|
37
|
-
useAutosizeTextArea({
|
|
38
|
-
textAreaRef,
|
|
39
|
-
triggerAutoSize: triggerAutoSize,
|
|
40
|
-
maxHeight,
|
|
41
|
-
minHeight
|
|
42
|
-
});
|
|
43
|
-
useImperativeHandle(ref, () => textAreaRef.current);
|
|
44
|
-
React.useEffect(() => {
|
|
45
|
-
setTriggerAutoSize(value);
|
|
46
|
-
}, [props?.defaultValue, value]);
|
|
47
|
-
return (_jsx("textarea", { ...props, value: value, ref: textAreaRef, className: cn('border-input-border aria-invalid:border-destructive ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full overflow-y-hidden rounded-md border bg-transparent px-3 py-2 text-sm focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden', 'read-only:bg-muted read-only:cursor-default read-only:caret-transparent read-only:opacity-50 read-only:select-text read-only:focus:ring-0 read-only:focus:ring-offset-0 read-only:focus:outline-hidden', 'disabled:cursor-not-allowed disabled:opacity-50', className), onChange: (e) => {
|
|
48
|
-
setTriggerAutoSize(e.target.value);
|
|
49
|
-
onChange?.(e);
|
|
50
|
-
} }));
|
|
51
|
-
}
|
|
1
|
+
"use client";import{jsx as c}from"react/jsx-runtime";import*as i from"react";import{cn as g}from"../../../lib/utils.js";import{useImperativeHandle as y}from"react";export const useAutosizeTextArea=({textAreaRef:n,triggerAutoSize:l,maxHeight:t=Number.MAX_SAFE_INTEGER,minHeight:o=0})=>{const[s,u]=i.useState(true);i.useEffect(()=>{const e=n.current;if(e){if(s){e.style.minHeight=`${o}px`;if(t>o){e.style.maxHeight=`${t}px`}u(false)}e.style.height=`${o}px`;const r=e.scrollHeight;if(r>t){e.style.height=`${t}px`;e.style.overflowY="auto"}else{e.style.height=`${r}px`;e.style.overflowY="hidden"}}},[n.current,l])};export function AutosizeTextarea({maxHeight:n=Number.MAX_SAFE_INTEGER,minHeight:l=36,className:t,onChange:o,value:s,ref:u,...e}){const r=i.useRef(null);const[f,a]=i.useState("");useAutosizeTextArea({textAreaRef:r,triggerAutoSize:f,maxHeight:n,minHeight:l});y(u,()=>r.current);i.useEffect(()=>{a(s)},[e?.defaultValue,s]);return c("textarea",{...e,value:s,ref:r,className:g("border-input-border aria-invalid:border-destructive ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full overflow-y-hidden rounded-md border bg-transparent px-3 py-2 text-sm focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden","read-only:bg-muted read-only:cursor-default read-only:caret-transparent read-only:opacity-50 read-only:select-text read-only:focus:ring-0 read-only:focus:ring-offset-0 read-only:focus:outline-hidden","disabled:cursor-not-allowed disabled:opacity-50",t),onChange:d=>{a(d.target.value);o?.(d)}})}
|
|
@@ -1,14 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
4
|
-
import { cn } from '../../../lib/utils.js';
|
|
5
|
-
function Avatar({ className, ...props }) {
|
|
6
|
-
return (_jsx(AvatarPrimitive.Root, { "data-slot": "avatar", className: cn('relative flex size-10 shrink-0 overflow-hidden rounded-full', className), ...props }));
|
|
7
|
-
}
|
|
8
|
-
function AvatarImage({ className, ...props }) {
|
|
9
|
-
return (_jsx(AvatarPrimitive.Image, { "data-slot": "avatar-image", className: cn('aspect-square size-full', className), ...props }));
|
|
10
|
-
}
|
|
11
|
-
function AvatarFallback({ className, ...props }) {
|
|
12
|
-
return (_jsx(AvatarPrimitive.Fallback, { "data-slot": "avatar-fallback", className: cn('bg-muted flex size-full items-center justify-center rounded-full', className), ...props }));
|
|
13
|
-
}
|
|
14
|
-
export { Avatar, AvatarImage, AvatarFallback };
|
|
1
|
+
"use client";import{jsx as e}from"react/jsx-runtime";import*as r from"@radix-ui/react-avatar";import{cn as l}from"../../../lib/utils.js";function s({className:a,...t}){return e(r.Root,{"data-slot":"avatar",className:l("relative flex size-10 shrink-0 overflow-hidden rounded-full",a),...t})}function i({className:a,...t}){return e(r.Image,{"data-slot":"avatar-image",className:l("aspect-square size-full",a),...t})}function o({className:a,...t}){return e(r.Fallback,{"data-slot":"avatar-fallback",className:l("bg-muted flex size-full items-center justify-center rounded-full",a),...t})}export{s as Avatar,i as AvatarImage,o as AvatarFallback};
|
|
@@ -1,79 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { cva } from 'class-variance-authority';
|
|
3
|
-
import { cn } from '../../../lib/utils.js';
|
|
4
|
-
import { Slot } from '@radix-ui/react-slot';
|
|
5
|
-
/**
|
|
6
|
-
* `gap-1` is load-bearing, not decoration: a badge holding a label AND an
|
|
7
|
-
* element child (`ID<code>ctx-123</code>`) has nothing between them otherwise —
|
|
8
|
-
* JSX drops the newline-only text node and CSS drops the whitespace-only
|
|
9
|
-
* anonymous flex item — so the screen reads `IDctx-123`. Consumers were pasting
|
|
10
|
-
* `className="gap-1"` per call site; `cn` runs tailwind-merge, so an explicit
|
|
11
|
-
* `gap-2` still wins. Single-child badges are unaffected: gap needs two items.
|
|
12
|
-
*
|
|
13
|
-
* `whitespace-nowrap` keeps the pill a pill. `rounded-full` draws the ends as
|
|
14
|
-
* semicircles sized to ONE line box, so a label that wraps stretches those caps
|
|
15
|
-
* over two lines and the shape reads as a rounded blob, not a token. It bit a
|
|
16
|
-
* consumer table whose column was sized to its content: `min-content` on
|
|
17
|
-
* wrappable text resolves to the WIDEST WORD, so a three-word group name landed
|
|
18
|
-
* at 112px wide and 46px tall against the 26px of a single-line badge. Nowrap
|
|
19
|
-
* also pins `min-content` to the full label, which is what lets a caller cap the
|
|
20
|
-
* box with `max-w-*` plus a truncating child and get an ellipsis. A caller that
|
|
21
|
-
* genuinely wants a wrapping badge passes `whitespace-normal`; tailwind-merge
|
|
22
|
-
* lets it win.
|
|
23
|
-
*/
|
|
24
|
-
const badgeVariants = cva('inline-flex items-center gap-1 whitespace-nowrap rounded-full border border-border px-2.5 py-0.5 text-sm font-medium transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2', {
|
|
25
|
-
variants: {
|
|
26
|
-
variant: {
|
|
27
|
-
default: 'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/80',
|
|
28
|
-
active: 'bg-system-success-surface text-system-success-h1a border-system-success-border py-[2px] px-3',
|
|
29
|
-
inactive: 'bg-muted text-foreground border-muted-foreground/40 py-[2px] px-3',
|
|
30
|
-
secondary: 'border-transparent bg-muted-foreground text-white dark:text-black',
|
|
31
|
-
destructive: 'border-transparent bg-destructive text-destructive-foreground [a&]:hover:bg-destructive/80',
|
|
32
|
-
/**
|
|
33
|
-
* The accounting reading of a credit amount, NOT an alias of
|
|
34
|
-
* `destructive` (an error/alarm). The credit role is a tint-and-ink
|
|
35
|
-
* pair: `--credit-foreground` mirrors `--credit` by contract, so the
|
|
36
|
-
* red carries the role as text over a tinted surface. Do not "fix"
|
|
37
|
-
* this into a solid `bg-credit` fill — that renders red-on-red and is
|
|
38
|
-
* invisible.
|
|
39
|
-
*/
|
|
40
|
-
credit: 'border-credit/30 bg-credit/10 text-credit-foreground px-[10px] py-1',
|
|
41
|
-
error: 'border-system-error-border bg-system-error-surface text-system-error-text px-[10px] py-1',
|
|
42
|
-
success: 'border-system-success-border bg-system-success-surface text-system-success-text px-[10px] py-1',
|
|
43
|
-
info: 'border-system-info-border bg-system-info-surface text-system-info-text px-[10px] py-1',
|
|
44
|
-
alert: 'border-system-alert-border bg-system-alert-surface text-system-alert-text px-[10px] py-1',
|
|
45
|
-
purple: 'border-system-purple-border bg-system-purple-surface text-system-purple-text px-[10px] py-1',
|
|
46
|
-
outline: 'text-foreground'
|
|
47
|
-
},
|
|
48
|
-
/**
|
|
49
|
-
* Font size only. Padding is baked per-variant above, so a `sm` that also
|
|
50
|
-
* shrank the box would fight every variant that sets its own; scoping the
|
|
51
|
-
* axis to type keeps `sm` composable with all of them. 11px is the canon
|
|
52
|
-
* for fine print — the one micro-badge size, replacing the per-consumer
|
|
53
|
-
* 0.7rem/10px/11px anarchy.
|
|
54
|
-
*/
|
|
55
|
-
size: {
|
|
56
|
-
default: '',
|
|
57
|
-
sm: 'text-[11px]'
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
defaultVariants: {
|
|
61
|
-
variant: 'default',
|
|
62
|
-
size: 'default'
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
function Badge({ className, variant, size, asChild, ...props }) {
|
|
66
|
-
const Comp = asChild ? Slot : 'span';
|
|
67
|
-
/**
|
|
68
|
-
* A bare `span` is generic, and ARIA prohibits an accessible name on a
|
|
69
|
-
* generic element: a caller's `aria-label` was dropped by assistive tech and
|
|
70
|
-
* flagged by axe as `aria-prohibited-attr`. `role="img"` is the smallest role
|
|
71
|
-
* that permits the name and lets it stand in for the visible text, which is
|
|
72
|
-
* exactly what a labelled span badge wants. Unlabelled badges stay generic;
|
|
73
|
-
* `asChild` keeps the child's native role; and a caller's own `role` still wins
|
|
74
|
-
* because it arrives with the spread below.
|
|
75
|
-
*/
|
|
76
|
-
const labelled = props['aria-label'] !== undefined || props['aria-labelledby'] !== undefined;
|
|
77
|
-
return (_jsx(Comp, { "data-slot": "badge", role: !asChild && labelled ? 'img' : undefined, className: cn(badgeVariants({ variant, size }), className), ...props }));
|
|
78
|
-
}
|
|
79
|
-
export { Badge, badgeVariants };
|
|
1
|
+
import{jsx as i}from"react/jsx-runtime";import{cva as u}from"class-variance-authority";import{cn as p}from"../../../lib/utils.js";import{Slot as c}from"@radix-ui/react-slot";const t=u("inline-flex items-center gap-1 whitespace-nowrap rounded-full border border-border px-2.5 py-0.5 text-sm font-medium transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2",{variants:{variant:{default:"border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/80",active:"bg-system-success-surface text-system-success-h1a border-system-success-border py-[2px] px-3",inactive:"bg-muted text-foreground border-muted-foreground/40 py-[2px] px-3",secondary:"border-transparent bg-muted-foreground text-white dark:text-black",destructive:"border-transparent bg-destructive text-destructive-foreground [a&]:hover:bg-destructive/80",credit:"border-credit/30 bg-credit/10 text-credit-foreground px-[10px] py-1",error:"border-system-error-border bg-system-error-surface text-system-error-text px-[10px] py-1",success:"border-system-success-border bg-system-success-surface text-system-success-text px-[10px] py-1",info:"border-system-info-border bg-system-info-surface text-system-info-text px-[10px] py-1",alert:"border-system-alert-border bg-system-alert-surface text-system-alert-text px-[10px] py-1",purple:"border-system-purple-border bg-system-purple-surface text-system-purple-text px-[10px] py-1",outline:"text-foreground"},size:{default:"",sm:"text-[11px]"}},defaultVariants:{variant:"default",size:"default"}});function x({className:s,variant:o,size:a,asChild:r,...e}){const d=r?c:"span";const n=e["aria-label"]!==void 0||e["aria-labelledby"]!==void 0;return i(d,{"data-slot":"badge",role:!r&&n?"img":void 0,className:p(t({variant:o,size:a}),s),...e})}export{x as Badge,t as badgeVariants};
|
|
@@ -1,27 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Slot } from '@radix-ui/react-slot';
|
|
3
|
-
import { MoreHorizontal, Slash } from 'lucide-react';
|
|
4
|
-
import { cn } from '../../../lib/utils.js';
|
|
5
|
-
function Breadcrumb({ ...props }) {
|
|
6
|
-
return _jsx("nav", { "aria-label": "breadcrumb", "data-slot": "breadcrumb", ...props });
|
|
7
|
-
}
|
|
8
|
-
function BreadcrumbList({ className, ...props }) {
|
|
9
|
-
return (_jsx("ol", { "data-slot": "breadcrumb-list", className: cn('breadcrumb-list', className), ...props }));
|
|
10
|
-
}
|
|
11
|
-
function BreadcrumbItem({ className, ...props }) {
|
|
12
|
-
return (_jsx("li", { "data-slot": "breadcrumb-item", className: cn('breadcrumb-item', className), ...props }));
|
|
13
|
-
}
|
|
14
|
-
function BreadcrumbLink({ asChild, className, ...props }) {
|
|
15
|
-
const Comp = asChild ? Slot : 'a';
|
|
16
|
-
return (_jsx(Comp, { "data-slot": "breadcrumb-link", className: cn('breadcrumb-link', className), ...props }));
|
|
17
|
-
}
|
|
18
|
-
function BreadcrumbPage({ className, ...props }) {
|
|
19
|
-
return (_jsx("span", { "data-slot": "breadcrumb-page", role: "link", "aria-disabled": "true", "aria-current": "page", className: cn('breadcrumb-page', className), ...props }));
|
|
20
|
-
}
|
|
21
|
-
function BreadcrumbSeparator({ children, className, ...props }) {
|
|
22
|
-
return (_jsx("li", { "data-slot": "breadcrumb-separator", role: "presentation", "aria-hidden": "true", className: cn('breadcrumb-separator', className), ...props, children: children ?? _jsx(Slash, {}) }));
|
|
23
|
-
}
|
|
24
|
-
function BreadcrumbEllipsis({ className, ...props }) {
|
|
25
|
-
return (_jsxs("span", { "data-slot": "breadcrumb-ellipsis", role: "presentation", "aria-hidden": "true", className: cn('flex h-9 w-9 items-center justify-center', className), ...props, children: [_jsx(MoreHorizontal, { className: "h-4 w-4" }), _jsx("span", { className: "sr-only", children: "More" })] }));
|
|
26
|
-
}
|
|
27
|
-
export { Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbEllipsis };
|
|
1
|
+
import{jsx as e,jsxs as c}from"react/jsx-runtime";import{Slot as i}from"@radix-ui/react-slot";import{MoreHorizontal as l,Slash as m}from"lucide-react";import{cn as t}from"../../../lib/utils.js";function o({...r}){return e("nav",{"aria-label":"breadcrumb","data-slot":"breadcrumb",...r})}function u({className:r,...a}){return e("ol",{"data-slot":"breadcrumb-list",className:t("breadcrumb-list",r),...a})}function d({className:r,...a}){return e("li",{"data-slot":"breadcrumb-item",className:t("breadcrumb-item",r),...a})}function b({asChild:r,className:a,...s}){const n=r?i:"a";return e(n,{"data-slot":"breadcrumb-link",className:t("breadcrumb-link",a),...s})}function p({className:r,...a}){return e("span",{"data-slot":"breadcrumb-page",role:"link","aria-disabled":"true","aria-current":"page",className:t("breadcrumb-page",r),...a})}function f({children:r,className:a,...s}){return e("li",{"data-slot":"breadcrumb-separator",role:"presentation","aria-hidden":"true",className:t("breadcrumb-separator",a),...s,children:r??e(m,{})})}function h({className:r,...a}){return c("span",{"data-slot":"breadcrumb-ellipsis",role:"presentation","aria-hidden":"true",className:t("flex h-9 w-9 items-center justify-center",r),...a,children:[e(l,{className:"h-4 w-4"}),e("span",{className:"sr-only",children:"More"})]})}export{o as Breadcrumb,u as BreadcrumbList,d as BreadcrumbItem,b as BreadcrumbLink,p as BreadcrumbPage,f as BreadcrumbSeparator,h as BreadcrumbEllipsis};
|