@dev-dga/react 0.8.3 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/dist/{chunk-EFKAKU2X.js → chunk-66EVFQVL.js} +2 -2
- package/dist/{chunk-SOIZIH7F.js → chunk-6DN3JE3P.js} +10 -1
- package/dist/chunk-6DN3JE3P.js.map +1 -0
- package/dist/{chunk-D7BZ6L4Z.cjs → chunk-BBGCS5PZ.cjs} +7 -2
- package/dist/chunk-BBGCS5PZ.cjs.map +1 -0
- package/dist/{chunk-MUM6HKPT.js → chunk-BTP7G7WR.js} +7 -2
- package/dist/chunk-BTP7G7WR.js.map +1 -0
- package/dist/{chunk-LES7CZSC.cjs → chunk-CISRE6BC.cjs} +14 -3
- package/dist/chunk-CISRE6BC.cjs.map +1 -0
- package/dist/{chunk-4ZCLTLVC.cjs → chunk-CVQFSXRR.cjs} +10 -1
- package/dist/chunk-CVQFSXRR.cjs.map +1 -0
- package/dist/{chunk-BNULFLPC.js → chunk-HBAHWCBK.js} +14 -3
- package/dist/chunk-HBAHWCBK.js.map +1 -0
- package/dist/{chunk-54GIEP6E.cjs → chunk-I6BOBHO6.cjs} +7 -2
- package/dist/chunk-I6BOBHO6.cjs.map +1 -0
- package/dist/{chunk-DBB47IAX.js → chunk-IFB53HNO.js} +1 -1
- package/dist/chunk-IFB53HNO.js.map +1 -0
- package/dist/{chunk-TWCX4EZR.js → chunk-JOJ23OD4.js} +6 -1
- package/dist/{chunk-TWCX4EZR.js.map → chunk-JOJ23OD4.js.map} +1 -1
- package/dist/{chunk-PI4OPECU.cjs → chunk-LG2IADSZ.cjs} +1 -1
- package/dist/{chunk-PI4OPECU.cjs.map → chunk-LG2IADSZ.cjs.map} +1 -1
- package/dist/{chunk-CHE75QHA.js → chunk-MCHL23CE.js} +1 -1
- package/dist/{chunk-CHE75QHA.js.map → chunk-MCHL23CE.js.map} +1 -1
- package/dist/{chunk-MWOGVEQB.cjs → chunk-NUC6WJU4.cjs} +5 -5
- package/dist/{chunk-MWOGVEQB.cjs.map → chunk-NUC6WJU4.cjs.map} +1 -1
- package/dist/{chunk-JQO3EFLX.cjs → chunk-PAUY27WX.cjs} +3 -14
- package/dist/chunk-PAUY27WX.cjs.map +1 -0
- package/dist/{chunk-6A73DWVA.js → chunk-UAECZXU5.js} +3 -14
- package/dist/chunk-UAECZXU5.js.map +1 -0
- package/dist/{chunk-43763K2A.cjs → chunk-WI4WQGF6.cjs} +1 -1
- package/dist/{chunk-43763K2A.cjs.map → chunk-WI4WQGF6.cjs.map} +1 -1
- package/dist/components/Combobox/Combobox.cjs +2 -2
- package/dist/components/Combobox/Combobox.js +1 -1
- package/dist/components/Combobox/index.cjs +2 -2
- package/dist/components/Combobox/index.js +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.cjs +2 -2
- package/dist/components/DateRangePicker/DateRangePicker.js +1 -1
- package/dist/components/DateRangePicker/index.cjs +2 -2
- package/dist/components/DateRangePicker/index.js +1 -1
- package/dist/components/Modal/Modal.cjs +4 -2
- package/dist/components/Modal/Modal.cjs.map +1 -1
- package/dist/components/Modal/Modal.js +3 -1
- package/dist/components/Modal/index.cjs +4 -2
- package/dist/components/Modal/index.cjs.map +1 -1
- package/dist/components/Modal/index.js +3 -1
- package/dist/components/ScrollArea/ScrollArea.cjs +2 -2
- package/dist/components/ScrollArea/ScrollArea.js +1 -1
- package/dist/components/ScrollArea/index.cjs +2 -2
- package/dist/components/ScrollArea/index.js +1 -1
- package/dist/components/Sidebar/Sidebar.cjs +2 -2
- package/dist/components/Sidebar/Sidebar.js +1 -1
- package/dist/components/Sidebar/SidebarMenu.cjs +3 -3
- package/dist/components/Sidebar/SidebarMenu.js +2 -2
- package/dist/components/Sidebar/index.cjs +4 -4
- package/dist/components/Sidebar/index.js +3 -3
- package/dist/components/TagInput/TagInput.cjs +2 -2
- package/dist/components/TagInput/TagInput.js +1 -1
- package/dist/components/TagInput/index.cjs +2 -2
- package/dist/components/TagInput/index.js +1 -1
- package/dist/components/Tooltip/Tooltip.cjs +2 -2
- package/dist/components/Tooltip/Tooltip.js +1 -1
- package/dist/components/Tooltip/index.cjs +2 -2
- package/dist/components/Tooltip/index.js +1 -1
- package/dist/index.cjs +23 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -6
- package/dist/index.d.ts +20 -6
- package/dist/index.js +35 -33
- package/package.json +3 -3
- package/dist/chunk-4ZCLTLVC.cjs.map +0 -1
- package/dist/chunk-54GIEP6E.cjs.map +0 -1
- package/dist/chunk-6A73DWVA.js.map +0 -1
- package/dist/chunk-BNULFLPC.js.map +0 -1
- package/dist/chunk-D7BZ6L4Z.cjs.map +0 -1
- package/dist/chunk-DBB47IAX.js.map +0 -1
- package/dist/chunk-JQO3EFLX.cjs.map +0 -1
- package/dist/chunk-LES7CZSC.cjs.map +0 -1
- package/dist/chunk-MUM6HKPT.js.map +0 -1
- package/dist/chunk-SOIZIH7F.js.map +0 -1
- /package/dist/{chunk-EFKAKU2X.js.map → chunk-66EVFQVL.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @dev-dga/react
|
|
2
2
|
|
|
3
|
+
## 0.9.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Rides the `@dev-dga/css` collapsed-rail fix in lockstep — a `SidebarMenu` placed inside `SidebarHeader`/`SidebarFooter` no longer clips its icon when collapsed to the rail. No `@dev-dga/react` runtime change (new Sidebar story + e2e coverage only). Released in lockstep with `@dev-dga/css` and `@dev-dga/tokens`.
|
|
8
|
+
|
|
9
|
+
## 0.9.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- **Modal — new `<ModalBody>` scroll region.** A scrollable middle slot (mirrors `<DrawerBody>`): tall modal content scrolls inside it while the header and footer stay pinned, capped at the viewport with **zero consumer config** — no hand-rolled `<div style={{ maxHeight, overflow }}>` wrapper. Short, non-scrolling bodies can still drop content directly under `ModalContent`. Additive export; existing modals are unaffected.
|
|
14
|
+
- **Sidebar — `<SidebarInset scrollable>` opt-in.** Pass `scrollable` to make the inset its own vertical scroll region (tall content scrolls inside it; the sidebar + footer stay put) with **no consumer `flex`/`min-block-size`/`overflow` CSS**. The whole inset scrolls (header included); for a fixed header with only the body scrolling, leave it off and compose a nested scroll region (the App-shell pattern). Additive prop; default behavior unchanged.
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- **TagInput — required indicator.** `required` now renders the same `*` asterisk as every other text-entry control (Input/Textarea/…) and sets `aria-required` on the field. It deliberately does **not** set the native `required` attribute on the inner input — that holds the draft text, so native `required` would block form submit while committed tags exist.
|
|
19
|
+
- **Combobox — a11y dev-warning.** When `label` is a non-string node and no `aria-label`/`aria-labelledby` is given (the options popover then falls back to the untranslated name "Options"), a dev-only `console.warn` points to the fix. No production/runtime change.
|
|
20
|
+
- **Tooltip — docs.** JSDoc now states `Tooltip` must be rendered inside `<DgaProvider>` (which supplies the required Radix `TooltipProvider`).
|
|
21
|
+
- **ScrollArea — dead-class cleanup.** Stopped emitting the unused `--vertical` / `--horizontal` / `--both` modifier classes (no stylesheet matched them; orientation is driven by which scrollbar renders). `scrollAreaVariants` stays exported.
|
|
22
|
+
- Rides the `@dev-dga/css` Sidebar full-height + collapsed-rail + Skeleton + disabled-opacity changes in lockstep (see that changelog). Released in lockstep with `@dev-dga/css` and `@dev-dga/tokens`.
|
|
23
|
+
|
|
3
24
|
## 0.8.3
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
Tooltip,
|
|
3
3
|
TooltipContent,
|
|
4
4
|
TooltipTrigger
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-IFB53HNO.js";
|
|
6
6
|
import {
|
|
7
7
|
useSidebar
|
|
8
8
|
} from "./chunk-F7NPGAKU.js";
|
|
@@ -174,4 +174,4 @@ export {
|
|
|
174
174
|
sidebarMenuSubButtonVariants,
|
|
175
175
|
SidebarMenuSubButton
|
|
176
176
|
};
|
|
177
|
-
//# sourceMappingURL=chunk-
|
|
177
|
+
//# sourceMappingURL=chunk-66EVFQVL.js.map
|
|
@@ -53,6 +53,14 @@ function useComboboxContext(component) {
|
|
|
53
53
|
}
|
|
54
54
|
return ctx;
|
|
55
55
|
}
|
|
56
|
+
function warnRichLabelNeedsAriaLabel(label, ariaLabel, ariaLabelledBy) {
|
|
57
|
+
if (process.env.NODE_ENV === "production") return;
|
|
58
|
+
if (ariaLabel || ariaLabelledBy) return;
|
|
59
|
+
if (label === void 0 || label === null || typeof label === "string") return;
|
|
60
|
+
console.warn(
|
|
61
|
+
'[dga/Combobox] `label` is a non-string node and no `aria-label`/`aria-labelledby` was given, so the options popover falls back to the untranslated name "Options". Pass a localized `aria-label` to name the popover for screen-reader users.'
|
|
62
|
+
);
|
|
63
|
+
}
|
|
56
64
|
function Combobox({
|
|
57
65
|
value: controlledValue,
|
|
58
66
|
defaultValue,
|
|
@@ -77,6 +85,7 @@ function Combobox({
|
|
|
77
85
|
"aria-label": ariaLabel,
|
|
78
86
|
"aria-labelledby": ariaLabelledBy
|
|
79
87
|
}) {
|
|
88
|
+
warnRichLabelNeedsAriaLabel(label, ariaLabel, ariaLabelledBy);
|
|
80
89
|
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
81
90
|
const isControlled = controlledValue !== void 0;
|
|
82
91
|
const value = isControlled ? controlledValue : internalValue;
|
|
@@ -259,4 +268,4 @@ export {
|
|
|
259
268
|
ComboboxGroup,
|
|
260
269
|
ComboboxSeparator
|
|
261
270
|
};
|
|
262
|
-
//# sourceMappingURL=chunk-
|
|
271
|
+
//# sourceMappingURL=chunk-6DN3JE3P.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Combobox/Combobox.tsx"],"sourcesContent":["'use client';\n\nimport {\n Children,\n createContext,\n isValidElement,\n useCallback,\n useContext,\n useId,\n useMemo,\n useState,\n type ReactNode,\n} from 'react';\nimport { Command } from 'cmdk';\nimport { Popover as PopoverPrimitive } from 'radix-ui';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\nimport { Check, ChevronDown } from '../../internal/icons';\nimport { useFieldA11y, FieldMessage } from '../../field';\nimport { DgaContext } from '../../providers/DgaContext';\n\n// ─── 1. Variants ─── //\n\n// Trigger height matches Input/Select so a Combobox lines up in a form row.\nconst comboboxTriggerVariants = cva('ddga-combobox-trigger', {\n variants: {\n size: {\n sm: 'ddga-combobox-trigger--sm',\n md: 'ddga-combobox-trigger--md',\n },\n error: {\n true: 'ddga-combobox-trigger--error',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\n// Keep a no-op `comboboxVariants` for parity with the project's barrel\n// convention (every component re-exports a *Variants from its barrel).\nconst comboboxVariants = comboboxTriggerVariants;\n\n// ─── 2. Context (bridges Root state to Items + label lookup) ─── //\n//\n// Items register `value → label` on mount so the trigger can render the\n// selected option's human-readable label without consumers having to thread\n// a separate `displayValue` function in the common case. Async-loaded\n// options can still override via `<Combobox getLabel={...}>` below.\n\ninterface ComboboxContextValue {\n value?: string;\n select: (value: string) => void;\n}\n\nconst ComboboxContext = createContext<ComboboxContextValue | null>(null);\n\nfunction useComboboxContext(component: string): ComboboxContextValue {\n const ctx = useContext(ComboboxContext);\n if (!ctx) {\n throw new Error(`<${component}> must be rendered inside <Combobox>.`);\n }\n return ctx;\n}\n\n// ─── 3. Types ─── //\n\ninterface ComboboxProps extends VariantProps<typeof comboboxTriggerVariants> {\n /** Currently selected option value (controlled). */\n value?: string;\n /** Initial value when uncontrolled. */\n defaultValue?: string;\n /** Fires whenever the selection changes (controlled or uncontrolled). */\n onValueChange?: (value: string) => void;\n /** Controlled popover open state. */\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Visible label above the trigger. */\n label?: ReactNode;\n /** Hint shown below the trigger when there's no error. */\n helperText?: ReactNode;\n /** Message shown below the trigger when `error` is true. */\n errorMessage?: ReactNode;\n /** Marks the field invalid — sets `aria-invalid` and the error border. */\n error?: boolean;\n /** Marks the field required — adds the asterisk + `aria-required`. */\n required?: boolean;\n /** Disables the trigger entirely. */\n disabled?: boolean;\n /** Placeholder shown in the trigger when no value is selected. */\n placeholder?: ReactNode;\n /** Placeholder for the search input inside the panel. Defaults to `\"Search…\"`. */\n searchPlaceholder?: string;\n /** Shown when no item matches the search query. Defaults to `\"No results.\"`. */\n emptyMessage?: ReactNode;\n /**\n * Override the trigger label resolver — useful when items are loaded async\n * after the value is set, or when the trigger should show a richer label\n * than the item's rendered children. Receives the current value, returns\n * the node to display. Falls back to the registered item's label.\n */\n getLabel?: (value: string) => ReactNode;\n /** Caller-supplied id for the trigger; falls back to a generated one. */\n id?: string;\n /** Forwarded to the trigger (the focusable button). */\n className?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n /** `<ComboboxItem>` (+ optional Group / Separator) children. */\n children: ReactNode;\n}\n\ninterface ComboboxItemProps extends Omit<\n React.ComponentProps<typeof Command.Item>,\n 'value' | 'onSelect'\n> {\n /** Stable value for filtering + selection. */\n value: string;\n /** Extra search terms cmdk should match against the input. */\n keywords?: string[];\n /** Disable this item from selection. */\n disabled?: boolean;\n /** Optional select handler — fires alongside the root's `onValueChange`. */\n onSelect?: (value: string) => void;\n}\n\ninterface ComboboxGroupProps extends React.ComponentProps<typeof Command.Group> {\n /** Group heading rendered above its items. */\n heading?: ReactNode;\n}\n\ntype ComboboxSeparatorProps = React.ComponentProps<typeof Command.Separator>;\n\n// ─── 4. Root ─── //\n\n// Dev-only nudge: when `label` is a rich (non-string) node and no\n// `aria-label`/`aria-labelledby` is given, the options popover (role=\"dialog\")\n// falls back to the untranslated name \"Options\". Point i18n-conscious consumers\n// at the fix. Mirrors the ScrollArea/Popover a11y warnings.\nfunction warnRichLabelNeedsAriaLabel(\n label: ReactNode,\n ariaLabel?: string,\n ariaLabelledBy?: string,\n) {\n if (process.env.NODE_ENV === 'production') return;\n if (ariaLabel || ariaLabelledBy) return;\n if (label === undefined || label === null || typeof label === 'string') return;\n console.warn(\n '[dga/Combobox] `label` is a non-string node and no `aria-label`/`aria-labelledby` was ' +\n 'given, so the options popover falls back to the untranslated name \"Options\". Pass a ' +\n 'localized `aria-label` to name the popover for screen-reader users.',\n );\n}\n\nfunction Combobox({\n value: controlledValue,\n defaultValue,\n onValueChange,\n open: controlledOpen,\n defaultOpen,\n onOpenChange,\n label,\n helperText,\n errorMessage,\n error,\n required,\n disabled,\n size,\n placeholder,\n searchPlaceholder = 'Search…',\n emptyMessage = 'No results.',\n getLabel,\n id: externalId,\n className,\n children,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n}: ComboboxProps) {\n warnRichLabelNeedsAriaLabel(label, ariaLabel, ariaLabelledBy);\n\n // Uncontrolled fallbacks.\n const [internalValue, setInternalValue] = useState<string | undefined>(defaultValue);\n const isControlled = controlledValue !== undefined;\n const value = isControlled ? controlledValue : internalValue;\n\n const [internalOpen, setInternalOpen] = useState(defaultOpen ?? false);\n const isOpenControlled = controlledOpen !== undefined;\n const open = isOpenControlled ? controlledOpen : internalOpen;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (!isOpenControlled) setInternalOpen(next);\n onOpenChange?.(next);\n },\n [isOpenControlled, onOpenChange],\n );\n\n const select = useCallback(\n (next: string) => {\n if (!isControlled) setInternalValue(next);\n onValueChange?.(next);\n setOpen(false);\n },\n [isControlled, onValueChange, setOpen],\n );\n\n const ctx = useMemo<ComboboxContextValue>(() => ({ value, select }), [value, select]);\n\n // Walk `children` once to build a value → label map. Synchronous so the\n // trigger shows the right label on first render — registration via\n // useEffect would only fire when items mount, and items don't mount until\n // the popover opens (Radix Portal lazy-mounts). Recurses through\n // `ComboboxGroup` so grouped items still resolve. Bare children only —\n // doesn't dive into arbitrary nested DOM.\n const itemLabels = useMemo<Map<string, ReactNode>>(() => {\n const map = new Map<string, ReactNode>();\n const visit = (nodes: ReactNode): void => {\n Children.forEach(nodes, (child) => {\n if (!isValidElement(child)) return;\n const childProps = child.props as { value?: unknown; children?: ReactNode };\n if (typeof childProps.value === 'string') {\n map.set(childProps.value, childProps.children);\n } else if (childProps.children) {\n visit(childProps.children);\n }\n });\n };\n visit(children);\n return map;\n }, [children]);\n\n // Field a11y wiring — same primitive as Select.\n const { fieldId, errorId, helperId, hasError, hasErrorMessage, hasHelper, controlProps } =\n useFieldA11y({\n name: 'Combobox',\n id: externalId,\n label,\n error,\n errorMessage,\n helperText,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n });\n\n // Portal anchored to DgaProvider root (mirrors Select/Modal/DropdownMenu).\n const providerCtx = useContext(DgaContext);\n // Body-mounted portal target (see DgaProvider) — escapes ancestor\n // clipping while keeping theme inheritance via mirrored data-theme/vars.\n const portalContainer = providerCtx?.portalEl ?? providerCtx?.rootEl ?? undefined;\n\n // Trigger label — explicit override wins; otherwise look up from the\n // children-derived map; otherwise fall back to the placeholder.\n const triggerLabel = useMemo<ReactNode>(() => {\n if (value === undefined) return null;\n if (getLabel) return getLabel(value);\n return itemLabels.get(value) ?? null;\n }, [value, getLabel, itemLabels]);\n\n const searchId = useId();\n\n return (\n <ComboboxContext.Provider value={ctx}>\n <div data-slot=\"combobox-field\" className=\"ddga-field\">\n {label && (\n <label htmlFor={fieldId} className=\"ddga-combobox__label\">\n {label}\n {required && (\n <span aria-hidden=\"true\" className=\"ddga-combobox__required\">\n *\n </span>\n )}\n </label>\n )}\n <PopoverPrimitive.Root open={open} onOpenChange={setOpen}>\n <PopoverPrimitive.Trigger asChild>\n <button\n type=\"button\"\n {...controlProps}\n // Trigger stays a plain button — Radix Popover.Trigger sets\n // aria-haspopup + aria-expanded + aria-controls so AT users\n // hear \"Pick a fruit, button, has popup\". We declared role=\"combobox\"\n // earlier but it requires aria-controls pointing to the listbox,\n // which Radix wires for dialog semantics — axe flagged the mismatch.\n aria-required={required || undefined}\n disabled={disabled}\n data-slot=\"combobox-trigger\"\n className={cn(comboboxTriggerVariants({ size, error: hasError }), className)}\n >\n <span className=\"ddga-combobox__value\">\n {triggerLabel ?? <span className=\"ddga-combobox__placeholder\">{placeholder}</span>}\n </span>\n <ChevronDown aria-hidden=\"true\" className=\"ddga-combobox__icon\" />\n </button>\n </PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={portalContainer}>\n <PopoverPrimitive.Content\n data-slot=\"combobox-content\"\n className=\"ddga-combobox-content\"\n sideOffset={4}\n align=\"start\"\n // Popover.Content is role=\"dialog\" → axe requires an accessible\n // name. Use the field label when it's a string; otherwise fall\n // back to a generic \"Options\" so a11y stays valid even when the\n // consumer composes a rich React node as the label.\n aria-label={ariaLabel ?? (typeof label === 'string' ? label : 'Options')}\n aria-labelledby={ariaLabelledBy}\n // Match trigger width so the panel doesn't visually float over.\n style={{ inlineSize: 'var(--radix-popover-trigger-width)' }}\n onOpenAutoFocus={(event) => {\n // cmdk handles its own focus management (Input gets focused on\n // mount via autoFocus below). Prevent Radix from also moving\n // focus or we lose the search input as the auto-focus target.\n event.preventDefault();\n }}\n >\n <Command\n id={searchId}\n data-slot=\"combobox-command\"\n className=\"ddga-combobox-command\"\n // cmdk's default filter matches if the input is a substring of\n // the item value OR any keyword — fine for our v1 use case.\n >\n <Command.Input\n autoFocus\n placeholder={searchPlaceholder}\n data-slot=\"combobox-input\"\n className=\"ddga-combobox-input\"\n />\n <Command.List data-slot=\"combobox-list\" className=\"ddga-combobox-list\">\n <Command.Empty data-slot=\"combobox-empty\" className=\"ddga-combobox-empty\">\n {emptyMessage}\n </Command.Empty>\n {children}\n </Command.List>\n </Command>\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n {hasErrorMessage && (\n <FieldMessage id={errorId} variant=\"error\">\n {errorMessage}\n </FieldMessage>\n )}\n {hasHelper && (\n <FieldMessage id={helperId} variant=\"helper\">\n {helperText}\n </FieldMessage>\n )}\n </div>\n </ComboboxContext.Provider>\n );\n}\n\n// ─── 5. Item ─── //\n\nfunction ComboboxItem({\n value,\n keywords,\n disabled,\n onSelect,\n className,\n children,\n ...props\n}: ComboboxItemProps) {\n const { value: selectedValue, select } = useComboboxContext('ComboboxItem');\n\n const isSelected = selectedValue === value;\n\n return (\n <Command.Item\n value={value}\n keywords={keywords}\n disabled={disabled}\n onSelect={(v) => {\n onSelect?.(v);\n select(v);\n }}\n data-slot=\"combobox-item\"\n // cmdk owns `data-selected` for keyboard highlight — use a separate\n // attribute for the chosen value so the two don't collide.\n data-active={isSelected ? '' : undefined}\n className={cn('ddga-combobox-item', className)}\n {...props}\n >\n <span className=\"ddga-combobox-item__check\" aria-hidden=\"true\">\n {isSelected ? <Check /> : null}\n </span>\n <span className=\"ddga-combobox-item__label\">{children}</span>\n </Command.Item>\n );\n}\n\n// ─── 6. Group + Separator (cmdk passthroughs) ─── //\n\nfunction ComboboxGroup({ className, heading, ...props }: ComboboxGroupProps) {\n return (\n <Command.Group\n heading={heading}\n data-slot=\"combobox-group\"\n className={cn('ddga-combobox-group', className)}\n {...props}\n />\n );\n}\n\nfunction ComboboxSeparator({ className, ...props }: ComboboxSeparatorProps) {\n return (\n <Command.Separator\n data-slot=\"combobox-separator\"\n className={cn('ddga-combobox-separator', className)}\n {...props}\n />\n );\n}\n\n// ─── 7. Exports ─── //\n\nexport {\n Combobox,\n ComboboxItem,\n ComboboxGroup,\n ComboboxSeparator,\n comboboxTriggerVariants,\n comboboxVariants,\n};\nexport type { ComboboxProps, ComboboxItemProps, ComboboxGroupProps, ComboboxSeparatorProps };\n"],"mappings":"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","names":[]}
|
|
@@ -41,6 +41,7 @@ function TagInput({
|
|
|
41
41
|
error,
|
|
42
42
|
size,
|
|
43
43
|
disabled,
|
|
44
|
+
required,
|
|
44
45
|
placeholder,
|
|
45
46
|
max,
|
|
46
47
|
allowDuplicates = false,
|
|
@@ -144,7 +145,10 @@ function TagInput({
|
|
|
144
145
|
};
|
|
145
146
|
const chipSize = size === "lg" ? "md" : "sm";
|
|
146
147
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { "data-slot": "tag-input-field", className: "ddga-field", children: [
|
|
147
|
-
label && /* @__PURE__ */ _jsxruntime.
|
|
148
|
+
label && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "label", { htmlFor: fieldId, className: "ddga-tag-input__label", children: [
|
|
149
|
+
label,
|
|
150
|
+
required && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { "aria-hidden": "true", className: "ddga-tag-input__required", children: "*" })
|
|
151
|
+
] }),
|
|
148
152
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
149
153
|
"div",
|
|
150
154
|
{
|
|
@@ -185,6 +189,7 @@ function TagInput({
|
|
|
185
189
|
type: "text",
|
|
186
190
|
value: draft,
|
|
187
191
|
disabled,
|
|
192
|
+
"aria-required": required || void 0,
|
|
188
193
|
placeholder: tags.length === 0 ? placeholder : void 0,
|
|
189
194
|
onChange: (event) => setDraft(event.target.value),
|
|
190
195
|
onKeyDown: handleKeyDown,
|
|
@@ -204,4 +209,4 @@ function TagInput({
|
|
|
204
209
|
|
|
205
210
|
|
|
206
211
|
exports.tagInputVariants = tagInputVariants; exports.TagInput = TagInput;
|
|
207
|
-
//# sourceMappingURL=chunk-
|
|
212
|
+
//# sourceMappingURL=chunk-BBGCS5PZ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-BBGCS5PZ.cjs","../src/components/TagInput/TagInput.tsx"],"names":[],"mappings":"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","file":"/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-BBGCS5PZ.cjs","sourcesContent":[null,"'use client';\n\nimport { useRef, useState, type ReactNode } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\nimport { useFieldA11y, FieldMessage } from '../../field';\nimport { Badge, type BadgeProps } from '../Badge';\n\n// ─── 1. Variants (cva) ─── //\n\n// Applied to the *control* (the bordered box), not the raw <input> — the box\n// owns the border, sizing, focus ring and disabled/error styling so the chips\n// and the text input wrap inside the field. Mirrors Input's box, but the box\n// grows vertically as chips wrap (min-block-size, not a fixed height).\nconst tagInputVariants = cva('ddga-tag-input', {\n variants: {\n size: {\n sm: 'ddga-tag-input--sm',\n md: 'ddga-tag-input--md',\n lg: 'ddga-tag-input--lg',\n },\n error: {\n true: 'ddga-tag-input--error',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\n// ─── 2. Types ─── //\n\n// We own `value` / `defaultValue` (string[] tags, not strings), `onChange`\n// (fires with the tag array), and the design-system `size` variant — so they\n// are stripped from the native input props the rest are spread onto.\ntype NativeInputProps = Omit<\n React.ComponentProps<'input'>,\n 'value' | 'defaultValue' | 'onChange' | 'size'\n>;\n\ninterface TagInputProps\n extends NativeInputProps, Omit<VariantProps<typeof tagInputVariants>, 'error'> {\n /** Controlled tag list. */\n value?: string[];\n /** Uncontrolled initial tag list. */\n defaultValue?: string[];\n /** Fires with the full accepted tag set after every add/remove. */\n onChange?: (tags: string[]) => void;\n /** Visible field label, associated to the text input. */\n label?: ReactNode;\n /** Hint shown below the field. Hidden while an error message is showing. */\n helperText?: ReactNode;\n /** Message shown below the field when invalid. */\n errorMessage?: ReactNode;\n /** Marks the field invalid: sets `aria-invalid` and error styling. */\n error?: boolean;\n /** Caps the number of tags. Adds beyond the cap are no-ops. */\n max?: number;\n /** Allow the same tag more than once. Off → duplicates are rejected. */\n allowDuplicates?: boolean;\n /** Make duplicate detection case-sensitive. Default: case-insensitive. */\n caseSensitive?: boolean;\n /** Consumer gate run on each candidate tag. Return false to reject (draft kept). */\n validate?: (tag: string, tags: string[]) => boolean;\n /** Characters that commit the draft and split a paste. Newline always splits a paste. */\n delimiters?: string[];\n /** Badge variant used for the chips. */\n chipVariant?: BadgeProps['variant'];\n /** Accessible name for each chip's remove button. */\n removeLabel?: (tag: string) => string;\n /** Live-region text announced on add/remove (screen readers). */\n formatAnnouncement?: (tag: string, action: 'add' | 'remove') => string;\n}\n\n// ─── 3. Component ─── //\n\nfunction TagInput({\n id: externalId,\n value,\n defaultValue,\n onChange,\n label,\n helperText,\n errorMessage,\n error,\n size,\n disabled,\n required,\n placeholder,\n max,\n allowDuplicates = false,\n caseSensitive = false,\n validate,\n delimiters = [','],\n chipVariant = 'secondary',\n removeLabel = (tag) => `Remove ${tag}`,\n formatAnnouncement = (tag, action) => `${tag} ${action === 'add' ? 'added' : 'removed'}`,\n className,\n ...props\n}: TagInputProps) {\n const isControlled = value !== undefined;\n const [uncontrolledTags, setUncontrolledTags] = useState<string[]>(defaultValue ?? []);\n const tags = isControlled ? value : uncontrolledTags;\n\n const [draft, setDraft] = useState('');\n const [announcement, setAnnouncement] = useState('');\n const inputRef = useRef<HTMLInputElement>(null);\n\n const { fieldId, errorId, helperId, hasError, hasErrorMessage, hasHelper, controlProps } =\n useFieldA11y({\n name: 'TagInput',\n id: externalId,\n label,\n error,\n errorMessage,\n helperText,\n 'aria-label': props['aria-label'],\n 'aria-labelledby': props['aria-labelledby'],\n });\n\n const commit = (next: string[]) => {\n if (!isControlled) setUncontrolledTags(next);\n onChange?.(next);\n };\n\n const norm = (t: string) => (caseSensitive ? t : t.toLowerCase());\n\n // Run raw fragments through the full accept pipeline (trim → drop-empty →\n // max cap → dedup → validate), appending the survivors. Only ever appends,\n // so the accepted set is `next.slice(current.length)`.\n const accept = (raw: string[], current: string[]): string[] => {\n let next = current;\n for (const fragment of raw) {\n const trimmed = fragment.trim();\n if (!trimmed) continue;\n if (max !== undefined && next.length >= max) break;\n if (!allowDuplicates && next.some((t) => norm(t) === norm(trimmed))) continue;\n if (validate && !validate(trimmed, next)) continue;\n next = [...next, trimmed];\n }\n return next;\n };\n\n const announceAdded = (added: string[]) => {\n if (added.length > 0) {\n setAnnouncement(added.map((t) => formatAnnouncement(t, 'add')).join(', '));\n }\n };\n\n const commitDraft = () => {\n const next = accept([draft], tags);\n if (next.length > tags.length) {\n commit(next);\n announceAdded(next.slice(tags.length));\n setDraft('');\n }\n // Rejected (dup / max / validate / empty): keep the draft so it can be fixed.\n };\n\n // Build a paste splitter from the delimiter chars + newlines. `-` is escaped\n // too (trailing in the class) so a delimiter like `-` can't form an invalid\n // character-class range (e.g. `['|','-']` → `[|-…]` would throw).\n const splitPaste = (text: string): string[] => {\n const escaped = delimiters.map((d) => d.replace(/[.*+?^${}()|[\\]\\\\-]/g, '\\\\$&'));\n const pattern = new RegExp(`[${escaped.join('')}\\\\n\\\\r]`);\n return text.split(pattern);\n };\n\n const removeTag = (index: number) => {\n const removed = tags[index];\n commit(tags.filter((_, i) => i !== index));\n setAnnouncement(formatAnnouncement(removed, 'remove'));\n inputRef.current?.focus();\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (disabled) return;\n if (event.key === 'Enter') {\n // Always swallow Enter so it adds a tag instead of submitting the form.\n event.preventDefault();\n if (draft.trim()) commitDraft();\n } else if (delimiters.includes(event.key)) {\n event.preventDefault();\n if (draft.trim()) commitDraft();\n } else if (event.key === 'Backspace' && draft === '' && tags.length > 0) {\n event.preventDefault();\n removeTag(tags.length - 1);\n }\n };\n\n const handlePaste = (event: React.ClipboardEvent<HTMLInputElement>) => {\n if (disabled) return;\n const text = event.clipboardData.getData('text');\n const fragments = splitPaste(text);\n // No delimiter in the pasted text → let it type normally into the draft.\n if (fragments.length <= 1) return;\n event.preventDefault();\n const next = accept(fragments, tags);\n if (next.length > tags.length) {\n commit(next);\n announceAdded(next.slice(tags.length));\n // Clear any in-progress draft so it isn't left stranded after the paste.\n setDraft('');\n }\n };\n\n // Clicking the box chrome (not a chip button or the input) focuses the input.\n const handleBoxMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {\n const target = event.target as HTMLElement;\n if (target === inputRef.current || target.closest('button')) return;\n event.preventDefault();\n inputRef.current?.focus();\n };\n\n const chipSize: BadgeProps['size'] = size === 'lg' ? 'md' : 'sm';\n\n return (\n <div data-slot=\"tag-input-field\" className=\"ddga-field\">\n {label && (\n <label htmlFor={fieldId} className=\"ddga-tag-input__label\">\n {label}\n {required && (\n <span aria-hidden=\"true\" className=\"ddga-tag-input__required\">\n *\n </span>\n )}\n </label>\n )}\n <div\n data-slot=\"tag-input-control\"\n className={cn(tagInputVariants({ size, error: hasError }), className)}\n data-disabled={disabled || undefined}\n onMouseDown={disabled ? undefined : handleBoxMouseDown}\n >\n {tags.length > 0 && (\n <ul data-slot=\"tag-input-list\" className=\"ddga-tag-input__list\" role=\"list\">\n {tags.map((tag, index) => (\n <li\n // Tags can repeat (allowDuplicates) so the value alone is not a\n // stable key; pair it with the index.\n key={`${tag}-${index}`}\n data-slot=\"tag-input-item\"\n className=\"ddga-tag-input__item\"\n // `display:contents` on the list/item can drop the implicit\n // list semantics in some engines; re-assert them explicitly.\n role=\"listitem\"\n >\n <Badge\n variant={chipVariant}\n size={chipSize}\n // Controlled-open: the chip never self-hides — removal flows\n // through onChange so controlled consumers stay the source of truth.\n open\n dismissible={!disabled}\n onDismiss={() => removeTag(index)}\n closeLabel={removeLabel(tag)}\n >\n {tag}\n </Badge>\n </li>\n ))}\n </ul>\n )}\n <input\n // Spread consumer props first, then our a11y contract + handlers so\n // they cannot be clobbered.\n {...props}\n {...controlProps}\n ref={inputRef}\n data-slot=\"tag-input\"\n className=\"ddga-tag-input__field\"\n type=\"text\"\n value={draft}\n disabled={disabled}\n // `aria-required` (not native `required`): the input holds the draft,\n // not the committed tags, so native `required` would block form\n // submit whenever the draft is empty even though tags exist.\n aria-required={required || undefined}\n placeholder={tags.length === 0 ? placeholder : undefined}\n onChange={(event) => setDraft(event.target.value)}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n />\n </div>\n <div data-slot=\"tag-input-live\" className=\"ddga-sr-only\" role=\"status\" aria-live=\"polite\">\n {announcement}\n </div>\n {hasErrorMessage && (\n <FieldMessage id={errorId} variant=\"error\">\n {errorMessage}\n </FieldMessage>\n )}\n {hasHelper && (\n <FieldMessage id={helperId} variant=\"helper\">\n {helperText}\n </FieldMessage>\n )}\n </div>\n );\n}\n\n// ─── 4. Exports ─── //\n\nexport { TagInput, tagInputVariants };\nexport type { TagInputProps };\n"]}
|
|
@@ -41,6 +41,7 @@ function TagInput({
|
|
|
41
41
|
error,
|
|
42
42
|
size,
|
|
43
43
|
disabled,
|
|
44
|
+
required,
|
|
44
45
|
placeholder,
|
|
45
46
|
max,
|
|
46
47
|
allowDuplicates = false,
|
|
@@ -144,7 +145,10 @@ function TagInput({
|
|
|
144
145
|
};
|
|
145
146
|
const chipSize = size === "lg" ? "md" : "sm";
|
|
146
147
|
return /* @__PURE__ */ jsxs("div", { "data-slot": "tag-input-field", className: "ddga-field", children: [
|
|
147
|
-
label && /* @__PURE__ */
|
|
148
|
+
label && /* @__PURE__ */ jsxs("label", { htmlFor: fieldId, className: "ddga-tag-input__label", children: [
|
|
149
|
+
label,
|
|
150
|
+
required && /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "ddga-tag-input__required", children: "*" })
|
|
151
|
+
] }),
|
|
148
152
|
/* @__PURE__ */ jsxs(
|
|
149
153
|
"div",
|
|
150
154
|
{
|
|
@@ -185,6 +189,7 @@ function TagInput({
|
|
|
185
189
|
type: "text",
|
|
186
190
|
value: draft,
|
|
187
191
|
disabled,
|
|
192
|
+
"aria-required": required || void 0,
|
|
188
193
|
placeholder: tags.length === 0 ? placeholder : void 0,
|
|
189
194
|
onChange: (event) => setDraft(event.target.value),
|
|
190
195
|
onKeyDown: handleKeyDown,
|
|
@@ -204,4 +209,4 @@ export {
|
|
|
204
209
|
tagInputVariants,
|
|
205
210
|
TagInput
|
|
206
211
|
};
|
|
207
|
-
//# sourceMappingURL=chunk-
|
|
212
|
+
//# sourceMappingURL=chunk-BTP7G7WR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/TagInput/TagInput.tsx"],"sourcesContent":["'use client';\n\nimport { useRef, useState, type ReactNode } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\nimport { useFieldA11y, FieldMessage } from '../../field';\nimport { Badge, type BadgeProps } from '../Badge';\n\n// ─── 1. Variants (cva) ─── //\n\n// Applied to the *control* (the bordered box), not the raw <input> — the box\n// owns the border, sizing, focus ring and disabled/error styling so the chips\n// and the text input wrap inside the field. Mirrors Input's box, but the box\n// grows vertically as chips wrap (min-block-size, not a fixed height).\nconst tagInputVariants = cva('ddga-tag-input', {\n variants: {\n size: {\n sm: 'ddga-tag-input--sm',\n md: 'ddga-tag-input--md',\n lg: 'ddga-tag-input--lg',\n },\n error: {\n true: 'ddga-tag-input--error',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\n// ─── 2. Types ─── //\n\n// We own `value` / `defaultValue` (string[] tags, not strings), `onChange`\n// (fires with the tag array), and the design-system `size` variant — so they\n// are stripped from the native input props the rest are spread onto.\ntype NativeInputProps = Omit<\n React.ComponentProps<'input'>,\n 'value' | 'defaultValue' | 'onChange' | 'size'\n>;\n\ninterface TagInputProps\n extends NativeInputProps, Omit<VariantProps<typeof tagInputVariants>, 'error'> {\n /** Controlled tag list. */\n value?: string[];\n /** Uncontrolled initial tag list. */\n defaultValue?: string[];\n /** Fires with the full accepted tag set after every add/remove. */\n onChange?: (tags: string[]) => void;\n /** Visible field label, associated to the text input. */\n label?: ReactNode;\n /** Hint shown below the field. Hidden while an error message is showing. */\n helperText?: ReactNode;\n /** Message shown below the field when invalid. */\n errorMessage?: ReactNode;\n /** Marks the field invalid: sets `aria-invalid` and error styling. */\n error?: boolean;\n /** Caps the number of tags. Adds beyond the cap are no-ops. */\n max?: number;\n /** Allow the same tag more than once. Off → duplicates are rejected. */\n allowDuplicates?: boolean;\n /** Make duplicate detection case-sensitive. Default: case-insensitive. */\n caseSensitive?: boolean;\n /** Consumer gate run on each candidate tag. Return false to reject (draft kept). */\n validate?: (tag: string, tags: string[]) => boolean;\n /** Characters that commit the draft and split a paste. Newline always splits a paste. */\n delimiters?: string[];\n /** Badge variant used for the chips. */\n chipVariant?: BadgeProps['variant'];\n /** Accessible name for each chip's remove button. */\n removeLabel?: (tag: string) => string;\n /** Live-region text announced on add/remove (screen readers). */\n formatAnnouncement?: (tag: string, action: 'add' | 'remove') => string;\n}\n\n// ─── 3. Component ─── //\n\nfunction TagInput({\n id: externalId,\n value,\n defaultValue,\n onChange,\n label,\n helperText,\n errorMessage,\n error,\n size,\n disabled,\n required,\n placeholder,\n max,\n allowDuplicates = false,\n caseSensitive = false,\n validate,\n delimiters = [','],\n chipVariant = 'secondary',\n removeLabel = (tag) => `Remove ${tag}`,\n formatAnnouncement = (tag, action) => `${tag} ${action === 'add' ? 'added' : 'removed'}`,\n className,\n ...props\n}: TagInputProps) {\n const isControlled = value !== undefined;\n const [uncontrolledTags, setUncontrolledTags] = useState<string[]>(defaultValue ?? []);\n const tags = isControlled ? value : uncontrolledTags;\n\n const [draft, setDraft] = useState('');\n const [announcement, setAnnouncement] = useState('');\n const inputRef = useRef<HTMLInputElement>(null);\n\n const { fieldId, errorId, helperId, hasError, hasErrorMessage, hasHelper, controlProps } =\n useFieldA11y({\n name: 'TagInput',\n id: externalId,\n label,\n error,\n errorMessage,\n helperText,\n 'aria-label': props['aria-label'],\n 'aria-labelledby': props['aria-labelledby'],\n });\n\n const commit = (next: string[]) => {\n if (!isControlled) setUncontrolledTags(next);\n onChange?.(next);\n };\n\n const norm = (t: string) => (caseSensitive ? t : t.toLowerCase());\n\n // Run raw fragments through the full accept pipeline (trim → drop-empty →\n // max cap → dedup → validate), appending the survivors. Only ever appends,\n // so the accepted set is `next.slice(current.length)`.\n const accept = (raw: string[], current: string[]): string[] => {\n let next = current;\n for (const fragment of raw) {\n const trimmed = fragment.trim();\n if (!trimmed) continue;\n if (max !== undefined && next.length >= max) break;\n if (!allowDuplicates && next.some((t) => norm(t) === norm(trimmed))) continue;\n if (validate && !validate(trimmed, next)) continue;\n next = [...next, trimmed];\n }\n return next;\n };\n\n const announceAdded = (added: string[]) => {\n if (added.length > 0) {\n setAnnouncement(added.map((t) => formatAnnouncement(t, 'add')).join(', '));\n }\n };\n\n const commitDraft = () => {\n const next = accept([draft], tags);\n if (next.length > tags.length) {\n commit(next);\n announceAdded(next.slice(tags.length));\n setDraft('');\n }\n // Rejected (dup / max / validate / empty): keep the draft so it can be fixed.\n };\n\n // Build a paste splitter from the delimiter chars + newlines. `-` is escaped\n // too (trailing in the class) so a delimiter like `-` can't form an invalid\n // character-class range (e.g. `['|','-']` → `[|-…]` would throw).\n const splitPaste = (text: string): string[] => {\n const escaped = delimiters.map((d) => d.replace(/[.*+?^${}()|[\\]\\\\-]/g, '\\\\$&'));\n const pattern = new RegExp(`[${escaped.join('')}\\\\n\\\\r]`);\n return text.split(pattern);\n };\n\n const removeTag = (index: number) => {\n const removed = tags[index];\n commit(tags.filter((_, i) => i !== index));\n setAnnouncement(formatAnnouncement(removed, 'remove'));\n inputRef.current?.focus();\n };\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {\n if (disabled) return;\n if (event.key === 'Enter') {\n // Always swallow Enter so it adds a tag instead of submitting the form.\n event.preventDefault();\n if (draft.trim()) commitDraft();\n } else if (delimiters.includes(event.key)) {\n event.preventDefault();\n if (draft.trim()) commitDraft();\n } else if (event.key === 'Backspace' && draft === '' && tags.length > 0) {\n event.preventDefault();\n removeTag(tags.length - 1);\n }\n };\n\n const handlePaste = (event: React.ClipboardEvent<HTMLInputElement>) => {\n if (disabled) return;\n const text = event.clipboardData.getData('text');\n const fragments = splitPaste(text);\n // No delimiter in the pasted text → let it type normally into the draft.\n if (fragments.length <= 1) return;\n event.preventDefault();\n const next = accept(fragments, tags);\n if (next.length > tags.length) {\n commit(next);\n announceAdded(next.slice(tags.length));\n // Clear any in-progress draft so it isn't left stranded after the paste.\n setDraft('');\n }\n };\n\n // Clicking the box chrome (not a chip button or the input) focuses the input.\n const handleBoxMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {\n const target = event.target as HTMLElement;\n if (target === inputRef.current || target.closest('button')) return;\n event.preventDefault();\n inputRef.current?.focus();\n };\n\n const chipSize: BadgeProps['size'] = size === 'lg' ? 'md' : 'sm';\n\n return (\n <div data-slot=\"tag-input-field\" className=\"ddga-field\">\n {label && (\n <label htmlFor={fieldId} className=\"ddga-tag-input__label\">\n {label}\n {required && (\n <span aria-hidden=\"true\" className=\"ddga-tag-input__required\">\n *\n </span>\n )}\n </label>\n )}\n <div\n data-slot=\"tag-input-control\"\n className={cn(tagInputVariants({ size, error: hasError }), className)}\n data-disabled={disabled || undefined}\n onMouseDown={disabled ? undefined : handleBoxMouseDown}\n >\n {tags.length > 0 && (\n <ul data-slot=\"tag-input-list\" className=\"ddga-tag-input__list\" role=\"list\">\n {tags.map((tag, index) => (\n <li\n // Tags can repeat (allowDuplicates) so the value alone is not a\n // stable key; pair it with the index.\n key={`${tag}-${index}`}\n data-slot=\"tag-input-item\"\n className=\"ddga-tag-input__item\"\n // `display:contents` on the list/item can drop the implicit\n // list semantics in some engines; re-assert them explicitly.\n role=\"listitem\"\n >\n <Badge\n variant={chipVariant}\n size={chipSize}\n // Controlled-open: the chip never self-hides — removal flows\n // through onChange so controlled consumers stay the source of truth.\n open\n dismissible={!disabled}\n onDismiss={() => removeTag(index)}\n closeLabel={removeLabel(tag)}\n >\n {tag}\n </Badge>\n </li>\n ))}\n </ul>\n )}\n <input\n // Spread consumer props first, then our a11y contract + handlers so\n // they cannot be clobbered.\n {...props}\n {...controlProps}\n ref={inputRef}\n data-slot=\"tag-input\"\n className=\"ddga-tag-input__field\"\n type=\"text\"\n value={draft}\n disabled={disabled}\n // `aria-required` (not native `required`): the input holds the draft,\n // not the committed tags, so native `required` would block form\n // submit whenever the draft is empty even though tags exist.\n aria-required={required || undefined}\n placeholder={tags.length === 0 ? placeholder : undefined}\n onChange={(event) => setDraft(event.target.value)}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n />\n </div>\n <div data-slot=\"tag-input-live\" className=\"ddga-sr-only\" role=\"status\" aria-live=\"polite\">\n {announcement}\n </div>\n {hasErrorMessage && (\n <FieldMessage id={errorId} variant=\"error\">\n {errorMessage}\n </FieldMessage>\n )}\n {hasHelper && (\n <FieldMessage id={helperId} variant=\"helper\">\n {helperText}\n </FieldMessage>\n )}\n </div>\n );\n}\n\n// ─── 4. Exports ─── //\n\nexport { TagInput, tagInputVariants };\nexport type { TagInputProps };\n"],"mappings":"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","names":[]}
|
|
@@ -171,9 +171,20 @@ function SidebarRail({
|
|
|
171
171
|
}
|
|
172
172
|
);
|
|
173
173
|
}
|
|
174
|
-
function SidebarInset({ asChild, className, ...props }) {
|
|
174
|
+
function SidebarInset({ asChild, scrollable, className, ...props }) {
|
|
175
175
|
const Comp = asChild ? _radixui.Slot.Slot : "main";
|
|
176
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
176
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
177
|
+
Comp,
|
|
178
|
+
{
|
|
179
|
+
"data-slot": "sidebar-inset",
|
|
180
|
+
className: _chunkV6MXOJQ4cjs.cn.call(void 0,
|
|
181
|
+
"ddga-sidebar-inset",
|
|
182
|
+
scrollable && "ddga-sidebar-inset--scrollable",
|
|
183
|
+
className
|
|
184
|
+
),
|
|
185
|
+
...props
|
|
186
|
+
}
|
|
187
|
+
);
|
|
177
188
|
}
|
|
178
189
|
function SidebarHeader({ asChild, className, ...props }) {
|
|
179
190
|
const Comp = asChild ? _radixui.Slot.Slot : "div";
|
|
@@ -216,4 +227,4 @@ function SidebarSeparator({ className, ...props }) {
|
|
|
216
227
|
|
|
217
228
|
|
|
218
229
|
exports.SidebarProvider = SidebarProvider; exports.Sidebar = Sidebar; exports.SidebarTrigger = SidebarTrigger; exports.SidebarRail = SidebarRail; exports.SidebarInset = SidebarInset; exports.SidebarHeader = SidebarHeader; exports.SidebarContent = SidebarContent; exports.SidebarFooter = SidebarFooter; exports.SidebarSeparator = SidebarSeparator;
|
|
219
|
-
//# sourceMappingURL=chunk-
|
|
230
|
+
//# sourceMappingURL=chunk-CISRE6BC.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-CISRE6BC.cjs","../src/components/Sidebar/Sidebar.tsx"],"names":["value"],"mappings":"AAAA;AACE;AACA;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACA;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;AChBA,8BAA0D;AAC1D,mCAAsC;AAgFhC,+CAAA;AA3DN,SAAS,eAAA,CAAgB;AAAA,EACvB,YAAA,EAAc,IAAA;AAAA,EACd,IAAA,EAAM,QAAA;AAAA,EACN,YAAA;AAAA,EACA,iBAAA,EAAmB,GAAA;AAAA,EACnB,iBAAA,EAAmB,IAAA;AAAA,EACnB,SAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAyB;AACvB,EAAA,MAAM,SAAA,EAAW,2CAAA,gBAA4B,CAAA;AAC7C,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,EAAA,EAAI,6BAAA,KAAc,CAAA;AAElD,EAAA,MAAM,aAAA,EAAe,SAAA,IAAa,KAAA,CAAA;AAClC,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,EAAA,EAAI,6BAAA,WAAoB,CAAA;AAC5D,EAAA,MAAM,KAAA,EAAO,aAAA,EAAgB,SAAA,EAAuB,YAAA;AAEpD,EAAA,MAAM,QAAA,EAAU,gCAAA;AAAA,IACd,CAACA,MAAAA,EAAAA,GAAmB;AAClB,MAAA,GAAA,CAAI,CAAC,YAAA,EAAc,eAAA,CAAgBA,MAAK,CAAA;AACxC,sBAAA,YAAA,wBAAA,CAAeA,MAAK,GAAA;AAAA,IACtB,CAAA;AAAA,IACA,CAAC,YAAA,EAAc,YAAY;AAAA,EAC7B,CAAA;AAEA,EAAA,MAAM,cAAA,EAAgB,gCAAA,CAAY,EAAA,GAAM;AACtC,IAAA,GAAA,CAAI,QAAA,EAAU;AACZ,MAAA,aAAA,CAAc,CAAC,CAAA,EAAA,GAAM,CAAC,CAAC,CAAA;AACvB,MAAA,MAAA;AAAA,IACF;AACA,IAAA,GAAA,CAAI,YAAA,EAAc;AAChB,sBAAA,YAAA,0BAAA,CAAe,CAAC,IAAI,GAAA;AAAA,IACtB,EAAA,KAAO;AACL,MAAA,eAAA,CAAgB,CAAC,CAAA,EAAA,GAAM,CAAC,CAAC,CAAA;AAAA,IAC3B;AAAA,EACF,CAAA,EAAG,CAAC,QAAA,EAAU,YAAA,EAAc,YAAA,EAAc,IAAI,CAAC,CAAA;AAE/C,EAAA,8BAAA,CAAU,EAAA,GAAM;AACd,IAAA,GAAA,CAAI,CAAC,gBAAA,EAAkB,MAAA;AACvB,IAAA,MAAM,UAAA,EAAY,CAAC,CAAA,EAAA,GAAqB;AACtC,MAAA,GAAA,CAAI,CAAA,CAAE,GAAA,CAAI,WAAA,CAAY,EAAA,IAAM,IAAA,GAAA,CAAQ,CAAA,CAAE,QAAA,GAAW,CAAA,CAAE,OAAA,CAAA,EAAU;AAC3D,QAAA,CAAA,CAAE,cAAA,CAAe,CAAA;AACjB,QAAA,aAAA,CAAc,CAAA;AAAA,MAChB;AAAA,IACF,CAAA;AACA,IAAA,MAAA,CAAO,gBAAA,CAAiB,SAAA,EAAW,SAAS,CAAA;AAC5C,IAAA,OAAO,CAAA,EAAA,GAAM,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,SAAS,CAAA;AAAA,EAC9D,CAAA,EAAG,CAAC,gBAAA,EAAkB,aAAa,CAAC,CAAA;AAEpC,EAAA,MAAM,MAAA,EAAkC,KAAA,EAAO,WAAA,EAAa,WAAA;AAE5D,EAAA,MAAM,MAAA,EAAQ,4BAAA;AAAA,IACZ,CAAA,EAAA,GAAA,CAAO,EAAE,KAAA,EAAO,IAAA,EAAM,OAAA,EAAS,UAAA,EAAY,aAAA,EAAe,QAAA,EAAU,cAAc,CAAA,CAAA;AAAA,IAClF,CAAC,KAAA,EAAO,IAAA,EAAM,OAAA,EAAS,UAAA,EAAY,QAAA,EAAU,aAAa;AAAA,EAC5D,CAAA;AAEA,EAAA,uBACE,6BAAA,gCAAC,CAAe,QAAA,EAAf,EAAwB,KAAA,EACvB,QAAA,kBAAA,6BAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,iBAAA;AAAA,MACV,SAAA,EAAW,kCAAA,sBAAG,EAAwB,SAAS,CAAA;AAAA,MAC/C,KAAA;AAAA,MACC,GAAG,KAAA;AAAA,MAEH;AAAA,IAAA;AAAA,EACH,EAAA,CACF,CAAA;AAEJ;AAWA,SAAS,OAAA,CAAQ;AAAA,EACf,QAAA,EAAU,SAAA;AAAA,EACV,YAAA,EAAc,MAAA;AAAA,EACd,KAAA,EAAO,OAAA;AAAA,EACP,SAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA,EAAc,UAAA,EAAY,SAAA;AAAA,EAC1B,GAAG;AACL,CAAA,EAAiB;AACf,EAAA,MAAM,EAAE,QAAA,EAAU,UAAA,EAAY,aAAA,EAAe,MAAM,EAAA,EAAI,0CAAA,CAAW;AAElE,EAAA,GAAA,CAAI,QAAA,EAAU;AACZ,IAAA,uBACE,6BAAA,wBAAC,EAAA,EAAO,IAAA,EAAM,UAAA,EAAY,YAAA,EAAc,aAAA,EACtC,QAAA,kBAAA,6BAAA;AAAA,MAAC,+BAAA;AAAA,MAAA;AAAA,QACC,IAAA;AAAA,QACA,IAAA,EAAK,IAAA;AAAA,QACL,YAAA,EAAY,SAAA;AAAA,QACZ,WAAA,EAAU,SAAA;AAAA,QACV,aAAA,EAAY,MAAA;AAAA,QACZ,cAAA,EAAc,OAAA;AAAA,QACd,WAAA,EAAW,IAAA;AAAA,QACX,SAAA,EAAW,kCAAA,cAAG,EAAgB,sBAAA,EAAwB,SAAS,CAAA;AAAA,QAC9D,GAAG,KAAA;AAAA,QAEH;AAAA,MAAA;AAAA,IACH,EAAA,CACF,CAAA;AAAA,EAEJ;AAEA,EAAA,uBACE,6BAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,SAAA;AAAA,MACV,YAAA,EAAY,SAAA;AAAA,MACZ,YAAA,EAAY,KAAA;AAAA,MACZ,kBAAA,EAAkB,WAAA;AAAA,MAClB,cAAA,EAAc,OAAA;AAAA,MACd,WAAA,EAAW,IAAA;AAAA,MACX,SAAA,EAAW,kCAAA,cAAG,EAAgB,SAAS,CAAA;AAAA,MACtC,GAAG,KAAA;AAAA,MAEH;AAAA,IAAA;AAAA,EACH,CAAA;AAEJ;AAQA,SAAS,cAAA,CAAe;AAAA,EACtB,OAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA,EAAc,UAAA,EAAY,gBAAA;AAAA,EAC1B,GAAG;AACL,CAAA,EAAwB;AACtB,EAAA,MAAM,EAAE,aAAA,EAAe,IAAA,EAAM,UAAA,EAAY,SAAS,EAAA,EAAI,0CAAA,CAAW;AACjE,EAAA,MAAM,KAAA,EAAO,QAAA,EAAU,aAAA,CAAc,KAAA,EAAO,QAAA;AAC5C,EAAA,uBACE,6BAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAM,QAAA,EAAU,KAAA,EAAA,EAAY,QAAA;AAAA,MAC5B,WAAA,EAAU,iBAAA;AAAA,MAEV,YAAA,EAAY,QAAA,EAAU,KAAA,EAAA,EAAY,SAAA;AAAA,MAClC,eAAA,EAAe,SAAA,EAAW,SAAA,EAAW,KAAA,CAAA;AAAA,MACrC,eAAA,EAAe,SAAA,EAAW,WAAA,EAAa,IAAA;AAAA,MACvC,SAAA,EAAW,kCAAA,uBAAG,EAAyB,SAAS,CAAA;AAAA,MAChD,OAAA,EAAS,CAAC,CAAA,EAAA,GAA2C;AACnD,wBAAA,OAAA,0BAAA,CAAU,CAAC,GAAA;AACX,QAAA,aAAA,CAAc,CAAA;AAAA,MAChB,CAAA;AAAA,MACC,GAAG,KAAA;AAAA,MAEH,QAAA,mBAAA,QAAA,0BAAY,6BAAA,2BAAC,EAAA,EAAU,aAAA,EAAY,OAAA,CAAO;AAAA,IAAA;AAAA,EAC7C,CAAA;AAEJ;AAEA,SAAS,WAAA,CAAY;AAAA,EACnB,SAAA;AAAA,EACA,YAAA,EAAc,UAAA,EAAY,gBAAA;AAAA,EAC1B,GAAG;AACL,CAAA,EAAmC;AACjC,EAAA,MAAM,EAAE,cAAc,EAAA,EAAI,0CAAA,CAAW;AACrC,EAAA,uBACE,6BAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,WAAA,EAAU,cAAA;AAAA,MACV,YAAA,EAAY,SAAA;AAAA,MACZ,KAAA,EAAO,SAAA;AAAA,MACP,QAAA,EAAU,CAAA,CAAA;AAAA,MACV,SAAA,EAAW,kCAAA,oBAAG,EAAsB,SAAS,CAAA;AAAA,MAC7C,OAAA,EAAS,aAAA;AAAA,MACR,GAAG;AAAA,IAAA;AAAA,EACN,CAAA;AAEJ;AAeA,SAAS,YAAA,CAAa,EAAE,OAAA,EAAS,UAAA,EAAY,SAAA,EAAW,GAAG,MAAM,CAAA,EAAsB;AACrF,EAAA,MAAM,KAAA,EAAO,QAAA,EAAU,aAAA,CAAc,KAAA,EAAO,MAAA;AAC5C,EAAA,uBACE,6BAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,eAAA;AAAA,MACV,SAAA,EAAW,kCAAA;AAAA,QACT,oBAAA;AAAA,QACA,WAAA,GAAc,gCAAA;AAAA,QACd;AAAA,MACF,CAAA;AAAA,MACC,GAAG;AAAA,IAAA;AAAA,EACN,CAAA;AAEJ;AAMA,SAAS,aAAA,CAAc,EAAE,OAAA,EAAS,SAAA,EAAW,GAAG,MAAM,CAAA,EAAwB;AAC5E,EAAA,MAAM,KAAA,EAAO,QAAA,EAAU,aAAA,CAAc,KAAA,EAAO,KAAA;AAC5C,EAAA,uBACE,6BAAA,IAAC,EAAA,EAAK,WAAA,EAAU,gBAAA,EAAiB,SAAA,EAAW,kCAAA,sBAAG,EAAwB,SAAS,CAAA,EAAI,GAAG,MAAA,CAAO,CAAA;AAElG;AAEA,SAAS,cAAA,CAAe,EAAE,OAAA,EAAS,SAAA,EAAW,GAAG,MAAM,CAAA,EAAwB;AAC7E,EAAA,MAAM,KAAA,EAAO,QAAA,EAAU,aAAA,CAAc,KAAA,EAAO,KAAA;AAC5C,EAAA,uBACE,6BAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,iBAAA;AAAA,MACV,SAAA,EAAW,kCAAA,uBAAG,EAAyB,SAAS,CAAA;AAAA,MAC/C,GAAG;AAAA,IAAA;AAAA,EACN,CAAA;AAEJ;AAEA,SAAS,aAAA,CAAc,EAAE,OAAA,EAAS,SAAA,EAAW,GAAG,MAAM,CAAA,EAAwB;AAC5E,EAAA,MAAM,KAAA,EAAO,QAAA,EAAU,aAAA,CAAc,KAAA,EAAO,KAAA;AAC5C,EAAA,uBACE,6BAAA,IAAC,EAAA,EAAK,WAAA,EAAU,gBAAA,EAAiB,SAAA,EAAW,kCAAA,sBAAG,EAAwB,SAAS,CAAA,EAAI,GAAG,MAAA,CAAO,CAAA;AAElG;AAEA,SAAS,gBAAA,CAAiB,EAAE,SAAA,EAAW,GAAG,MAAM,CAAA,EAA+B;AAC7E,EAAA,uBACE,6BAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,mBAAA;AAAA,MACV,SAAA,EAAW,kCAAA,yBAAG,EAA2B,SAAS,CAAA;AAAA,MACjD,GAAG;AAAA,IAAA;AAAA,EACN,CAAA;AAEJ;ADvDA;AACA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,0VAAC","file":"/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-CISRE6BC.cjs","sourcesContent":[null,"'use client';\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Slot as SlotPrimitive } from 'radix-ui';\nimport { cn } from '../../utils/cn';\nimport { Drawer, DrawerContent } from '../Drawer';\nimport { PanelLeft } from '../../internal/icons';\nimport { SidebarContext, useSidebar, type SidebarContextValue } from './SidebarContext';\nimport { useIsMobile } from './useIsMobile';\n\n// ─── SidebarProvider ─── //\n\ninterface SidebarProviderProps extends React.ComponentProps<'div'> {\n /** Uncontrolled initial desktop state. Default true (expanded). */\n defaultOpen?: boolean;\n /** Controlled desktop open state. */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Viewport width (px) below which the mobile Drawer engages. Default 768. */\n mobileBreakpoint?: number;\n /** Register Cmd/Ctrl+B to toggle. Default true. */\n keyboardShortcut?: boolean;\n}\n\nfunction SidebarProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange,\n mobileBreakpoint = 768,\n keyboardShortcut = true,\n className,\n style,\n children,\n ...props\n}: SidebarProviderProps) {\n const isMobile = useIsMobile(mobileBreakpoint);\n const [openMobile, setOpenMobile] = useState(false);\n\n const isControlled = openProp !== undefined;\n const [openInternal, setOpenInternal] = useState(defaultOpen);\n const open = isControlled ? (openProp as boolean) : openInternal;\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (!isControlled) setOpenInternal(value);\n onOpenChange?.(value);\n },\n [isControlled, onOpenChange],\n );\n\n const toggleSidebar = useCallback(() => {\n if (isMobile) {\n setOpenMobile((v) => !v);\n return;\n }\n if (isControlled) {\n onOpenChange?.(!open);\n } else {\n setOpenInternal((v) => !v);\n }\n }, [isMobile, isControlled, onOpenChange, open]);\n\n useEffect(() => {\n if (!keyboardShortcut) return;\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key.toLowerCase() === 'b' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n toggleSidebar();\n }\n };\n window.addEventListener('keydown', onKeyDown);\n return () => window.removeEventListener('keydown', onKeyDown);\n }, [keyboardShortcut, toggleSidebar]);\n\n const state: 'expanded' | 'collapsed' = open ? 'expanded' : 'collapsed';\n\n const value = useMemo<SidebarContextValue>(\n () => ({ state, open, setOpen, openMobile, setOpenMobile, isMobile, toggleSidebar }),\n [state, open, setOpen, openMobile, isMobile, toggleSidebar],\n );\n\n return (\n <SidebarContext.Provider value={value}>\n <div\n data-slot=\"sidebar-wrapper\"\n className={cn('ddga-sidebar-wrapper', className)}\n style={style}\n {...props}\n >\n {children}\n </div>\n </SidebarContext.Provider>\n );\n}\n\n// ─── Sidebar (container) ─── //\n\ninterface SidebarProps extends React.ComponentProps<'div'> {\n variant?: 'sidebar' | 'floating' | 'inset';\n collapsible?: 'icon' | 'offcanvas' | 'none';\n /** Logical side; flips with dir. Default 'start'. */\n side?: 'start' | 'end';\n}\n\nfunction Sidebar({\n variant = 'sidebar',\n collapsible = 'icon',\n side = 'start',\n className,\n children,\n 'aria-label': ariaLabel = 'Sidebar',\n ...props\n}: SidebarProps) {\n const { isMobile, openMobile, setOpenMobile, state } = useSidebar();\n\n if (isMobile) {\n return (\n <Drawer open={openMobile} onOpenChange={setOpenMobile}>\n <DrawerContent\n side={side}\n size=\"sm\"\n aria-label={ariaLabel}\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n data-variant={variant}\n data-side={side}\n className={cn('ddga-sidebar', 'ddga-sidebar--mobile', className)}\n {...props}\n >\n {children}\n </DrawerContent>\n </Drawer>\n );\n }\n\n return (\n <aside\n data-slot=\"sidebar\"\n aria-label={ariaLabel}\n data-state={state}\n data-collapsible={collapsible}\n data-variant={variant}\n data-side={side}\n className={cn('ddga-sidebar', className)}\n {...props}\n >\n {children}\n </aside>\n );\n}\n\n// ─── Trigger / Rail / Inset ─── //\n\ninterface SidebarTriggerProps extends React.ComponentProps<'button'> {\n asChild?: boolean;\n}\n\nfunction SidebarTrigger({\n asChild,\n className,\n onClick,\n children,\n 'aria-label': ariaLabel = 'Toggle sidebar',\n ...props\n}: SidebarTriggerProps) {\n const { toggleSidebar, open, openMobile, isMobile } = useSidebar();\n const Comp = asChild ? SlotPrimitive.Slot : 'button';\n return (\n <Comp\n type={asChild ? undefined : 'button'}\n data-slot=\"sidebar-trigger\"\n // Don't override the child element's accessible name when asChild.\n aria-label={asChild ? undefined : ariaLabel}\n aria-haspopup={isMobile ? 'dialog' : undefined}\n aria-expanded={isMobile ? openMobile : open}\n className={cn('ddga-sidebar__trigger', className)}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n toggleSidebar();\n }}\n {...props}\n >\n {children ?? <PanelLeft aria-hidden=\"true\" />}\n </Comp>\n );\n}\n\nfunction SidebarRail({\n className,\n 'aria-label': ariaLabel = 'Toggle sidebar',\n ...props\n}: React.ComponentProps<'button'>) {\n const { toggleSidebar } = useSidebar();\n return (\n <button\n type=\"button\"\n data-slot=\"sidebar-rail\"\n aria-label={ariaLabel}\n title={ariaLabel}\n tabIndex={-1}\n className={cn('ddga-sidebar__rail', className)}\n onClick={toggleSidebar}\n {...props}\n />\n );\n}\n\ninterface SidebarInsetProps extends React.ComponentProps<'main'> {\n asChild?: boolean;\n /**\n * Make the inset its own vertical scroll region: tall content scrolls inside\n * it (the sidebar + footer stay put) with zero consumer layout CSS — no\n * `flex` / `min-block-size:0` / `overflow-y:auto` boilerplate. The whole inset\n * scrolls, header included; for a fixed header with only the body scrolling,\n * leave this off and compose a nested scroll region inside the inset (see the\n * App shell story).\n */\n scrollable?: boolean;\n}\n\nfunction SidebarInset({ asChild, scrollable, className, ...props }: SidebarInsetProps) {\n const Comp = asChild ? SlotPrimitive.Slot : 'main';\n return (\n <Comp\n data-slot=\"sidebar-inset\"\n className={cn(\n 'ddga-sidebar-inset',\n scrollable && 'ddga-sidebar-inset--scrollable',\n className,\n )}\n {...props}\n />\n );\n}\n\n// ─── Structure ─── //\n\ntype SidebarSectionProps = React.ComponentProps<'div'> & { asChild?: boolean };\n\nfunction SidebarHeader({ asChild, className, ...props }: SidebarSectionProps) {\n const Comp = asChild ? SlotPrimitive.Slot : 'div';\n return (\n <Comp data-slot=\"sidebar-header\" className={cn('ddga-sidebar__header', className)} {...props} />\n );\n}\n\nfunction SidebarContent({ asChild, className, ...props }: SidebarSectionProps) {\n const Comp = asChild ? SlotPrimitive.Slot : 'div';\n return (\n <Comp\n data-slot=\"sidebar-content\"\n className={cn('ddga-sidebar__content', className)}\n {...props}\n />\n );\n}\n\nfunction SidebarFooter({ asChild, className, ...props }: SidebarSectionProps) {\n const Comp = asChild ? SlotPrimitive.Slot : 'div';\n return (\n <Comp data-slot=\"sidebar-footer\" className={cn('ddga-sidebar__footer', className)} {...props} />\n );\n}\n\nfunction SidebarSeparator({ className, ...props }: React.ComponentProps<'hr'>) {\n return (\n <hr\n data-slot=\"sidebar-separator\"\n className={cn('ddga-sidebar__separator', className)}\n {...props}\n />\n );\n}\n\n// ─── Exports ─── //\n\nexport { SidebarProvider };\nexport type { SidebarProviderProps };\n\nexport { Sidebar };\nexport type { SidebarProps };\n\nexport { SidebarTrigger, SidebarRail, SidebarInset };\nexport type { SidebarTriggerProps, SidebarInsetProps };\n\nexport { SidebarHeader, SidebarContent, SidebarFooter, SidebarSeparator };\nexport type { SidebarSectionProps };\n\nexport { useSidebar };\nexport type { SidebarContextValue };\n"]}
|
|
@@ -53,6 +53,14 @@ function useComboboxContext(component) {
|
|
|
53
53
|
}
|
|
54
54
|
return ctx;
|
|
55
55
|
}
|
|
56
|
+
function warnRichLabelNeedsAriaLabel(label, ariaLabel, ariaLabelledBy) {
|
|
57
|
+
if (process.env.NODE_ENV === "production") return;
|
|
58
|
+
if (ariaLabel || ariaLabelledBy) return;
|
|
59
|
+
if (label === void 0 || label === null || typeof label === "string") return;
|
|
60
|
+
console.warn(
|
|
61
|
+
'[dga/Combobox] `label` is a non-string node and no `aria-label`/`aria-labelledby` was given, so the options popover falls back to the untranslated name "Options". Pass a localized `aria-label` to name the popover for screen-reader users.'
|
|
62
|
+
);
|
|
63
|
+
}
|
|
56
64
|
function Combobox({
|
|
57
65
|
value: controlledValue,
|
|
58
66
|
defaultValue,
|
|
@@ -77,6 +85,7 @@ function Combobox({
|
|
|
77
85
|
"aria-label": ariaLabel,
|
|
78
86
|
"aria-labelledby": ariaLabelledBy
|
|
79
87
|
}) {
|
|
88
|
+
warnRichLabelNeedsAriaLabel(label, ariaLabel, ariaLabelledBy);
|
|
80
89
|
const [internalValue, setInternalValue] = _react.useState.call(void 0, defaultValue);
|
|
81
90
|
const isControlled = controlledValue !== void 0;
|
|
82
91
|
const value = isControlled ? controlledValue : internalValue;
|
|
@@ -259,4 +268,4 @@ function ComboboxSeparator({ className, ...props }) {
|
|
|
259
268
|
|
|
260
269
|
|
|
261
270
|
exports.comboboxTriggerVariants = comboboxTriggerVariants; exports.comboboxVariants = comboboxVariants; exports.Combobox = Combobox; exports.ComboboxItem = ComboboxItem; exports.ComboboxGroup = ComboboxGroup; exports.ComboboxSeparator = ComboboxSeparator;
|
|
262
|
-
//# sourceMappingURL=chunk-
|
|
271
|
+
//# sourceMappingURL=chunk-CVQFSXRR.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-CVQFSXRR.cjs","../src/components/Combobox/Combobox.tsx"],"names":[],"mappings":"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","file":"/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-CVQFSXRR.cjs","sourcesContent":[null,"'use client';\n\nimport {\n Children,\n createContext,\n isValidElement,\n useCallback,\n useContext,\n useId,\n useMemo,\n useState,\n type ReactNode,\n} from 'react';\nimport { Command } from 'cmdk';\nimport { Popover as PopoverPrimitive } from 'radix-ui';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\nimport { Check, ChevronDown } from '../../internal/icons';\nimport { useFieldA11y, FieldMessage } from '../../field';\nimport { DgaContext } from '../../providers/DgaContext';\n\n// ─── 1. Variants ─── //\n\n// Trigger height matches Input/Select so a Combobox lines up in a form row.\nconst comboboxTriggerVariants = cva('ddga-combobox-trigger', {\n variants: {\n size: {\n sm: 'ddga-combobox-trigger--sm',\n md: 'ddga-combobox-trigger--md',\n },\n error: {\n true: 'ddga-combobox-trigger--error',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\n// Keep a no-op `comboboxVariants` for parity with the project's barrel\n// convention (every component re-exports a *Variants from its barrel).\nconst comboboxVariants = comboboxTriggerVariants;\n\n// ─── 2. Context (bridges Root state to Items + label lookup) ─── //\n//\n// Items register `value → label` on mount so the trigger can render the\n// selected option's human-readable label without consumers having to thread\n// a separate `displayValue` function in the common case. Async-loaded\n// options can still override via `<Combobox getLabel={...}>` below.\n\ninterface ComboboxContextValue {\n value?: string;\n select: (value: string) => void;\n}\n\nconst ComboboxContext = createContext<ComboboxContextValue | null>(null);\n\nfunction useComboboxContext(component: string): ComboboxContextValue {\n const ctx = useContext(ComboboxContext);\n if (!ctx) {\n throw new Error(`<${component}> must be rendered inside <Combobox>.`);\n }\n return ctx;\n}\n\n// ─── 3. Types ─── //\n\ninterface ComboboxProps extends VariantProps<typeof comboboxTriggerVariants> {\n /** Currently selected option value (controlled). */\n value?: string;\n /** Initial value when uncontrolled. */\n defaultValue?: string;\n /** Fires whenever the selection changes (controlled or uncontrolled). */\n onValueChange?: (value: string) => void;\n /** Controlled popover open state. */\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Visible label above the trigger. */\n label?: ReactNode;\n /** Hint shown below the trigger when there's no error. */\n helperText?: ReactNode;\n /** Message shown below the trigger when `error` is true. */\n errorMessage?: ReactNode;\n /** Marks the field invalid — sets `aria-invalid` and the error border. */\n error?: boolean;\n /** Marks the field required — adds the asterisk + `aria-required`. */\n required?: boolean;\n /** Disables the trigger entirely. */\n disabled?: boolean;\n /** Placeholder shown in the trigger when no value is selected. */\n placeholder?: ReactNode;\n /** Placeholder for the search input inside the panel. Defaults to `\"Search…\"`. */\n searchPlaceholder?: string;\n /** Shown when no item matches the search query. Defaults to `\"No results.\"`. */\n emptyMessage?: ReactNode;\n /**\n * Override the trigger label resolver — useful when items are loaded async\n * after the value is set, or when the trigger should show a richer label\n * than the item's rendered children. Receives the current value, returns\n * the node to display. Falls back to the registered item's label.\n */\n getLabel?: (value: string) => ReactNode;\n /** Caller-supplied id for the trigger; falls back to a generated one. */\n id?: string;\n /** Forwarded to the trigger (the focusable button). */\n className?: string;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n /** `<ComboboxItem>` (+ optional Group / Separator) children. */\n children: ReactNode;\n}\n\ninterface ComboboxItemProps extends Omit<\n React.ComponentProps<typeof Command.Item>,\n 'value' | 'onSelect'\n> {\n /** Stable value for filtering + selection. */\n value: string;\n /** Extra search terms cmdk should match against the input. */\n keywords?: string[];\n /** Disable this item from selection. */\n disabled?: boolean;\n /** Optional select handler — fires alongside the root's `onValueChange`. */\n onSelect?: (value: string) => void;\n}\n\ninterface ComboboxGroupProps extends React.ComponentProps<typeof Command.Group> {\n /** Group heading rendered above its items. */\n heading?: ReactNode;\n}\n\ntype ComboboxSeparatorProps = React.ComponentProps<typeof Command.Separator>;\n\n// ─── 4. Root ─── //\n\n// Dev-only nudge: when `label` is a rich (non-string) node and no\n// `aria-label`/`aria-labelledby` is given, the options popover (role=\"dialog\")\n// falls back to the untranslated name \"Options\". Point i18n-conscious consumers\n// at the fix. Mirrors the ScrollArea/Popover a11y warnings.\nfunction warnRichLabelNeedsAriaLabel(\n label: ReactNode,\n ariaLabel?: string,\n ariaLabelledBy?: string,\n) {\n if (process.env.NODE_ENV === 'production') return;\n if (ariaLabel || ariaLabelledBy) return;\n if (label === undefined || label === null || typeof label === 'string') return;\n console.warn(\n '[dga/Combobox] `label` is a non-string node and no `aria-label`/`aria-labelledby` was ' +\n 'given, so the options popover falls back to the untranslated name \"Options\". Pass a ' +\n 'localized `aria-label` to name the popover for screen-reader users.',\n );\n}\n\nfunction Combobox({\n value: controlledValue,\n defaultValue,\n onValueChange,\n open: controlledOpen,\n defaultOpen,\n onOpenChange,\n label,\n helperText,\n errorMessage,\n error,\n required,\n disabled,\n size,\n placeholder,\n searchPlaceholder = 'Search…',\n emptyMessage = 'No results.',\n getLabel,\n id: externalId,\n className,\n children,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n}: ComboboxProps) {\n warnRichLabelNeedsAriaLabel(label, ariaLabel, ariaLabelledBy);\n\n // Uncontrolled fallbacks.\n const [internalValue, setInternalValue] = useState<string | undefined>(defaultValue);\n const isControlled = controlledValue !== undefined;\n const value = isControlled ? controlledValue : internalValue;\n\n const [internalOpen, setInternalOpen] = useState(defaultOpen ?? false);\n const isOpenControlled = controlledOpen !== undefined;\n const open = isOpenControlled ? controlledOpen : internalOpen;\n\n const setOpen = useCallback(\n (next: boolean) => {\n if (!isOpenControlled) setInternalOpen(next);\n onOpenChange?.(next);\n },\n [isOpenControlled, onOpenChange],\n );\n\n const select = useCallback(\n (next: string) => {\n if (!isControlled) setInternalValue(next);\n onValueChange?.(next);\n setOpen(false);\n },\n [isControlled, onValueChange, setOpen],\n );\n\n const ctx = useMemo<ComboboxContextValue>(() => ({ value, select }), [value, select]);\n\n // Walk `children` once to build a value → label map. Synchronous so the\n // trigger shows the right label on first render — registration via\n // useEffect would only fire when items mount, and items don't mount until\n // the popover opens (Radix Portal lazy-mounts). Recurses through\n // `ComboboxGroup` so grouped items still resolve. Bare children only —\n // doesn't dive into arbitrary nested DOM.\n const itemLabels = useMemo<Map<string, ReactNode>>(() => {\n const map = new Map<string, ReactNode>();\n const visit = (nodes: ReactNode): void => {\n Children.forEach(nodes, (child) => {\n if (!isValidElement(child)) return;\n const childProps = child.props as { value?: unknown; children?: ReactNode };\n if (typeof childProps.value === 'string') {\n map.set(childProps.value, childProps.children);\n } else if (childProps.children) {\n visit(childProps.children);\n }\n });\n };\n visit(children);\n return map;\n }, [children]);\n\n // Field a11y wiring — same primitive as Select.\n const { fieldId, errorId, helperId, hasError, hasErrorMessage, hasHelper, controlProps } =\n useFieldA11y({\n name: 'Combobox',\n id: externalId,\n label,\n error,\n errorMessage,\n helperText,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n });\n\n // Portal anchored to DgaProvider root (mirrors Select/Modal/DropdownMenu).\n const providerCtx = useContext(DgaContext);\n // Body-mounted portal target (see DgaProvider) — escapes ancestor\n // clipping while keeping theme inheritance via mirrored data-theme/vars.\n const portalContainer = providerCtx?.portalEl ?? providerCtx?.rootEl ?? undefined;\n\n // Trigger label — explicit override wins; otherwise look up from the\n // children-derived map; otherwise fall back to the placeholder.\n const triggerLabel = useMemo<ReactNode>(() => {\n if (value === undefined) return null;\n if (getLabel) return getLabel(value);\n return itemLabels.get(value) ?? null;\n }, [value, getLabel, itemLabels]);\n\n const searchId = useId();\n\n return (\n <ComboboxContext.Provider value={ctx}>\n <div data-slot=\"combobox-field\" className=\"ddga-field\">\n {label && (\n <label htmlFor={fieldId} className=\"ddga-combobox__label\">\n {label}\n {required && (\n <span aria-hidden=\"true\" className=\"ddga-combobox__required\">\n *\n </span>\n )}\n </label>\n )}\n <PopoverPrimitive.Root open={open} onOpenChange={setOpen}>\n <PopoverPrimitive.Trigger asChild>\n <button\n type=\"button\"\n {...controlProps}\n // Trigger stays a plain button — Radix Popover.Trigger sets\n // aria-haspopup + aria-expanded + aria-controls so AT users\n // hear \"Pick a fruit, button, has popup\". We declared role=\"combobox\"\n // earlier but it requires aria-controls pointing to the listbox,\n // which Radix wires for dialog semantics — axe flagged the mismatch.\n aria-required={required || undefined}\n disabled={disabled}\n data-slot=\"combobox-trigger\"\n className={cn(comboboxTriggerVariants({ size, error: hasError }), className)}\n >\n <span className=\"ddga-combobox__value\">\n {triggerLabel ?? <span className=\"ddga-combobox__placeholder\">{placeholder}</span>}\n </span>\n <ChevronDown aria-hidden=\"true\" className=\"ddga-combobox__icon\" />\n </button>\n </PopoverPrimitive.Trigger>\n <PopoverPrimitive.Portal container={portalContainer}>\n <PopoverPrimitive.Content\n data-slot=\"combobox-content\"\n className=\"ddga-combobox-content\"\n sideOffset={4}\n align=\"start\"\n // Popover.Content is role=\"dialog\" → axe requires an accessible\n // name. Use the field label when it's a string; otherwise fall\n // back to a generic \"Options\" so a11y stays valid even when the\n // consumer composes a rich React node as the label.\n aria-label={ariaLabel ?? (typeof label === 'string' ? label : 'Options')}\n aria-labelledby={ariaLabelledBy}\n // Match trigger width so the panel doesn't visually float over.\n style={{ inlineSize: 'var(--radix-popover-trigger-width)' }}\n onOpenAutoFocus={(event) => {\n // cmdk handles its own focus management (Input gets focused on\n // mount via autoFocus below). Prevent Radix from also moving\n // focus or we lose the search input as the auto-focus target.\n event.preventDefault();\n }}\n >\n <Command\n id={searchId}\n data-slot=\"combobox-command\"\n className=\"ddga-combobox-command\"\n // cmdk's default filter matches if the input is a substring of\n // the item value OR any keyword — fine for our v1 use case.\n >\n <Command.Input\n autoFocus\n placeholder={searchPlaceholder}\n data-slot=\"combobox-input\"\n className=\"ddga-combobox-input\"\n />\n <Command.List data-slot=\"combobox-list\" className=\"ddga-combobox-list\">\n <Command.Empty data-slot=\"combobox-empty\" className=\"ddga-combobox-empty\">\n {emptyMessage}\n </Command.Empty>\n {children}\n </Command.List>\n </Command>\n </PopoverPrimitive.Content>\n </PopoverPrimitive.Portal>\n </PopoverPrimitive.Root>\n {hasErrorMessage && (\n <FieldMessage id={errorId} variant=\"error\">\n {errorMessage}\n </FieldMessage>\n )}\n {hasHelper && (\n <FieldMessage id={helperId} variant=\"helper\">\n {helperText}\n </FieldMessage>\n )}\n </div>\n </ComboboxContext.Provider>\n );\n}\n\n// ─── 5. Item ─── //\n\nfunction ComboboxItem({\n value,\n keywords,\n disabled,\n onSelect,\n className,\n children,\n ...props\n}: ComboboxItemProps) {\n const { value: selectedValue, select } = useComboboxContext('ComboboxItem');\n\n const isSelected = selectedValue === value;\n\n return (\n <Command.Item\n value={value}\n keywords={keywords}\n disabled={disabled}\n onSelect={(v) => {\n onSelect?.(v);\n select(v);\n }}\n data-slot=\"combobox-item\"\n // cmdk owns `data-selected` for keyboard highlight — use a separate\n // attribute for the chosen value so the two don't collide.\n data-active={isSelected ? '' : undefined}\n className={cn('ddga-combobox-item', className)}\n {...props}\n >\n <span className=\"ddga-combobox-item__check\" aria-hidden=\"true\">\n {isSelected ? <Check /> : null}\n </span>\n <span className=\"ddga-combobox-item__label\">{children}</span>\n </Command.Item>\n );\n}\n\n// ─── 6. Group + Separator (cmdk passthroughs) ─── //\n\nfunction ComboboxGroup({ className, heading, ...props }: ComboboxGroupProps) {\n return (\n <Command.Group\n heading={heading}\n data-slot=\"combobox-group\"\n className={cn('ddga-combobox-group', className)}\n {...props}\n />\n );\n}\n\nfunction ComboboxSeparator({ className, ...props }: ComboboxSeparatorProps) {\n return (\n <Command.Separator\n data-slot=\"combobox-separator\"\n className={cn('ddga-combobox-separator', className)}\n {...props}\n />\n );\n}\n\n// ─── 7. Exports ─── //\n\nexport {\n Combobox,\n ComboboxItem,\n ComboboxGroup,\n ComboboxSeparator,\n comboboxTriggerVariants,\n comboboxVariants,\n};\nexport type { ComboboxProps, ComboboxItemProps, ComboboxGroupProps, ComboboxSeparatorProps };\n"]}
|
|
@@ -171,9 +171,20 @@ function SidebarRail({
|
|
|
171
171
|
}
|
|
172
172
|
);
|
|
173
173
|
}
|
|
174
|
-
function SidebarInset({ asChild, className, ...props }) {
|
|
174
|
+
function SidebarInset({ asChild, scrollable, className, ...props }) {
|
|
175
175
|
const Comp = asChild ? SlotPrimitive.Slot : "main";
|
|
176
|
-
return /* @__PURE__ */ jsx(
|
|
176
|
+
return /* @__PURE__ */ jsx(
|
|
177
|
+
Comp,
|
|
178
|
+
{
|
|
179
|
+
"data-slot": "sidebar-inset",
|
|
180
|
+
className: cn(
|
|
181
|
+
"ddga-sidebar-inset",
|
|
182
|
+
scrollable && "ddga-sidebar-inset--scrollable",
|
|
183
|
+
className
|
|
184
|
+
),
|
|
185
|
+
...props
|
|
186
|
+
}
|
|
187
|
+
);
|
|
177
188
|
}
|
|
178
189
|
function SidebarHeader({ asChild, className, ...props }) {
|
|
179
190
|
const Comp = asChild ? SlotPrimitive.Slot : "div";
|
|
@@ -216,4 +227,4 @@ export {
|
|
|
216
227
|
SidebarFooter,
|
|
217
228
|
SidebarSeparator
|
|
218
229
|
};
|
|
219
|
-
//# sourceMappingURL=chunk-
|
|
230
|
+
//# sourceMappingURL=chunk-HBAHWCBK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Sidebar/Sidebar.tsx"],"sourcesContent":["'use client';\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { Slot as SlotPrimitive } from 'radix-ui';\nimport { cn } from '../../utils/cn';\nimport { Drawer, DrawerContent } from '../Drawer';\nimport { PanelLeft } from '../../internal/icons';\nimport { SidebarContext, useSidebar, type SidebarContextValue } from './SidebarContext';\nimport { useIsMobile } from './useIsMobile';\n\n// ─── SidebarProvider ─── //\n\ninterface SidebarProviderProps extends React.ComponentProps<'div'> {\n /** Uncontrolled initial desktop state. Default true (expanded). */\n defaultOpen?: boolean;\n /** Controlled desktop open state. */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** Viewport width (px) below which the mobile Drawer engages. Default 768. */\n mobileBreakpoint?: number;\n /** Register Cmd/Ctrl+B to toggle. Default true. */\n keyboardShortcut?: boolean;\n}\n\nfunction SidebarProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange,\n mobileBreakpoint = 768,\n keyboardShortcut = true,\n className,\n style,\n children,\n ...props\n}: SidebarProviderProps) {\n const isMobile = useIsMobile(mobileBreakpoint);\n const [openMobile, setOpenMobile] = useState(false);\n\n const isControlled = openProp !== undefined;\n const [openInternal, setOpenInternal] = useState(defaultOpen);\n const open = isControlled ? (openProp as boolean) : openInternal;\n\n const setOpen = useCallback(\n (value: boolean) => {\n if (!isControlled) setOpenInternal(value);\n onOpenChange?.(value);\n },\n [isControlled, onOpenChange],\n );\n\n const toggleSidebar = useCallback(() => {\n if (isMobile) {\n setOpenMobile((v) => !v);\n return;\n }\n if (isControlled) {\n onOpenChange?.(!open);\n } else {\n setOpenInternal((v) => !v);\n }\n }, [isMobile, isControlled, onOpenChange, open]);\n\n useEffect(() => {\n if (!keyboardShortcut) return;\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key.toLowerCase() === 'b' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n toggleSidebar();\n }\n };\n window.addEventListener('keydown', onKeyDown);\n return () => window.removeEventListener('keydown', onKeyDown);\n }, [keyboardShortcut, toggleSidebar]);\n\n const state: 'expanded' | 'collapsed' = open ? 'expanded' : 'collapsed';\n\n const value = useMemo<SidebarContextValue>(\n () => ({ state, open, setOpen, openMobile, setOpenMobile, isMobile, toggleSidebar }),\n [state, open, setOpen, openMobile, isMobile, toggleSidebar],\n );\n\n return (\n <SidebarContext.Provider value={value}>\n <div\n data-slot=\"sidebar-wrapper\"\n className={cn('ddga-sidebar-wrapper', className)}\n style={style}\n {...props}\n >\n {children}\n </div>\n </SidebarContext.Provider>\n );\n}\n\n// ─── Sidebar (container) ─── //\n\ninterface SidebarProps extends React.ComponentProps<'div'> {\n variant?: 'sidebar' | 'floating' | 'inset';\n collapsible?: 'icon' | 'offcanvas' | 'none';\n /** Logical side; flips with dir. Default 'start'. */\n side?: 'start' | 'end';\n}\n\nfunction Sidebar({\n variant = 'sidebar',\n collapsible = 'icon',\n side = 'start',\n className,\n children,\n 'aria-label': ariaLabel = 'Sidebar',\n ...props\n}: SidebarProps) {\n const { isMobile, openMobile, setOpenMobile, state } = useSidebar();\n\n if (isMobile) {\n return (\n <Drawer open={openMobile} onOpenChange={setOpenMobile}>\n <DrawerContent\n side={side}\n size=\"sm\"\n aria-label={ariaLabel}\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n data-variant={variant}\n data-side={side}\n className={cn('ddga-sidebar', 'ddga-sidebar--mobile', className)}\n {...props}\n >\n {children}\n </DrawerContent>\n </Drawer>\n );\n }\n\n return (\n <aside\n data-slot=\"sidebar\"\n aria-label={ariaLabel}\n data-state={state}\n data-collapsible={collapsible}\n data-variant={variant}\n data-side={side}\n className={cn('ddga-sidebar', className)}\n {...props}\n >\n {children}\n </aside>\n );\n}\n\n// ─── Trigger / Rail / Inset ─── //\n\ninterface SidebarTriggerProps extends React.ComponentProps<'button'> {\n asChild?: boolean;\n}\n\nfunction SidebarTrigger({\n asChild,\n className,\n onClick,\n children,\n 'aria-label': ariaLabel = 'Toggle sidebar',\n ...props\n}: SidebarTriggerProps) {\n const { toggleSidebar, open, openMobile, isMobile } = useSidebar();\n const Comp = asChild ? SlotPrimitive.Slot : 'button';\n return (\n <Comp\n type={asChild ? undefined : 'button'}\n data-slot=\"sidebar-trigger\"\n // Don't override the child element's accessible name when asChild.\n aria-label={asChild ? undefined : ariaLabel}\n aria-haspopup={isMobile ? 'dialog' : undefined}\n aria-expanded={isMobile ? openMobile : open}\n className={cn('ddga-sidebar__trigger', className)}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n toggleSidebar();\n }}\n {...props}\n >\n {children ?? <PanelLeft aria-hidden=\"true\" />}\n </Comp>\n );\n}\n\nfunction SidebarRail({\n className,\n 'aria-label': ariaLabel = 'Toggle sidebar',\n ...props\n}: React.ComponentProps<'button'>) {\n const { toggleSidebar } = useSidebar();\n return (\n <button\n type=\"button\"\n data-slot=\"sidebar-rail\"\n aria-label={ariaLabel}\n title={ariaLabel}\n tabIndex={-1}\n className={cn('ddga-sidebar__rail', className)}\n onClick={toggleSidebar}\n {...props}\n />\n );\n}\n\ninterface SidebarInsetProps extends React.ComponentProps<'main'> {\n asChild?: boolean;\n /**\n * Make the inset its own vertical scroll region: tall content scrolls inside\n * it (the sidebar + footer stay put) with zero consumer layout CSS — no\n * `flex` / `min-block-size:0` / `overflow-y:auto` boilerplate. The whole inset\n * scrolls, header included; for a fixed header with only the body scrolling,\n * leave this off and compose a nested scroll region inside the inset (see the\n * App shell story).\n */\n scrollable?: boolean;\n}\n\nfunction SidebarInset({ asChild, scrollable, className, ...props }: SidebarInsetProps) {\n const Comp = asChild ? SlotPrimitive.Slot : 'main';\n return (\n <Comp\n data-slot=\"sidebar-inset\"\n className={cn(\n 'ddga-sidebar-inset',\n scrollable && 'ddga-sidebar-inset--scrollable',\n className,\n )}\n {...props}\n />\n );\n}\n\n// ─── Structure ─── //\n\ntype SidebarSectionProps = React.ComponentProps<'div'> & { asChild?: boolean };\n\nfunction SidebarHeader({ asChild, className, ...props }: SidebarSectionProps) {\n const Comp = asChild ? SlotPrimitive.Slot : 'div';\n return (\n <Comp data-slot=\"sidebar-header\" className={cn('ddga-sidebar__header', className)} {...props} />\n );\n}\n\nfunction SidebarContent({ asChild, className, ...props }: SidebarSectionProps) {\n const Comp = asChild ? SlotPrimitive.Slot : 'div';\n return (\n <Comp\n data-slot=\"sidebar-content\"\n className={cn('ddga-sidebar__content', className)}\n {...props}\n />\n );\n}\n\nfunction SidebarFooter({ asChild, className, ...props }: SidebarSectionProps) {\n const Comp = asChild ? SlotPrimitive.Slot : 'div';\n return (\n <Comp data-slot=\"sidebar-footer\" className={cn('ddga-sidebar__footer', className)} {...props} />\n );\n}\n\nfunction SidebarSeparator({ className, ...props }: React.ComponentProps<'hr'>) {\n return (\n <hr\n data-slot=\"sidebar-separator\"\n className={cn('ddga-sidebar__separator', className)}\n {...props}\n />\n );\n}\n\n// ─── Exports ─── //\n\nexport { SidebarProvider };\nexport type { SidebarProviderProps };\n\nexport { Sidebar };\nexport type { SidebarProps };\n\nexport { SidebarTrigger, SidebarRail, SidebarInset };\nexport type { SidebarTriggerProps, SidebarInsetProps };\n\nexport { SidebarHeader, SidebarContent, SidebarFooter, SidebarSeparator };\nexport type { SidebarSectionProps };\n\nexport { useSidebar };\nexport type { SidebarContextValue };\n"],"mappings":"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","names":["value"]}
|
|
@@ -93,6 +93,10 @@ function ModalDescription({ asChild, className, ...props }) {
|
|
|
93
93
|
}
|
|
94
94
|
);
|
|
95
95
|
}
|
|
96
|
+
function ModalBody({ asChild, className, ...props }) {
|
|
97
|
+
const Comp = asChild ? _radixui.Slot.Slot : "div";
|
|
98
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Comp, { "data-slot": "modal-body", className: _chunkV6MXOJQ4cjs.cn.call(void 0, "ddga-modal__body", className), ...props });
|
|
99
|
+
}
|
|
96
100
|
function ModalFooter({ asChild, className, ...props }) {
|
|
97
101
|
const Comp = asChild ? _radixui.Slot.Slot : "div";
|
|
98
102
|
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Comp, { "data-slot": "modal-footer", className: _chunkV6MXOJQ4cjs.cn.call(void 0, "ddga-modal__footer", className), ...props });
|
|
@@ -111,5 +115,6 @@ function ModalClose({ className, ...props }) {
|
|
|
111
115
|
|
|
112
116
|
|
|
113
117
|
|
|
114
|
-
|
|
115
|
-
|
|
118
|
+
|
|
119
|
+
exports.modalContentVariants = modalContentVariants; exports.Modal = Modal; exports.ModalTrigger = ModalTrigger; exports.ModalContent = ModalContent; exports.ModalHeader = ModalHeader; exports.ModalTitle = ModalTitle; exports.ModalDescription = ModalDescription; exports.ModalBody = ModalBody; exports.ModalFooter = ModalFooter; exports.ModalClose = ModalClose;
|
|
120
|
+
//# sourceMappingURL=chunk-I6BOBHO6.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-I6BOBHO6.cjs","../src/components/Modal/Modal.tsx"],"names":[],"mappings":"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","file":"/home/devdhaif/work/react/dga-dev/packages/react/dist/chunk-I6BOBHO6.cjs","sourcesContent":[null,"'use client';\n\nimport { useContext } from 'react';\nimport { Dialog as DialogPrimitive, Slot as SlotPrimitive } from 'radix-ui';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\nimport { DgaContext } from '../../providers/DgaContext';\nimport { Close } from '../../internal/icons';\n\n// ─── 1. Variants (cva) ─── //\n\nconst modalContentVariants = cva('ddga-modal', {\n variants: {\n size: {\n sm: 'ddga-modal--sm',\n md: 'ddga-modal--md',\n lg: 'ddga-modal--lg',\n xl: 'ddga-modal--xl',\n full: 'ddga-modal--full',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\n// ─── 2. Types ─── //\n//\n// Closed compound shape that hides Radix's Portal/Overlay plumbing. The Portal\n// is anchored to `DgaContext.rootEl` so `data-theme` + custom theme classes\n// set on the provider inherit into the modal — without it, the modal would\n// silently mount under <body> and miss dark mode / palette switches.\n\ntype ModalProps = React.ComponentProps<typeof DialogPrimitive.Root>;\ntype ModalTriggerProps = React.ComponentProps<typeof DialogPrimitive.Trigger>;\ntype ModalCloseProps = React.ComponentProps<typeof DialogPrimitive.Close>;\n\ninterface ModalContentProps\n extends\n React.ComponentProps<typeof DialogPrimitive.Content>,\n VariantProps<typeof modalContentVariants> {\n /**\n * Render a corner X close button. Defaults to `true`. Set `false` for\n * action-forcing dialogs (e.g. \"Are you sure?\") where the user must pick\n * one of the explicit footer buttons.\n */\n showCloseButton?: boolean;\n /** Localized label for the close button. Defaults to `\"Close\"`. */\n closeLabel?: string;\n}\n\ntype ModalSectionProps = React.ComponentProps<'div'> & { asChild?: boolean };\n\ninterface ModalTitleProps extends React.ComponentProps<typeof DialogPrimitive.Title> {\n /** Override the heading element (e.g. render an `<h3>` instead of the default `<h2>`). */\n asChild?: boolean;\n}\n\ninterface ModalDescriptionProps extends React.ComponentProps<typeof DialogPrimitive.Description> {\n /** Override the element (e.g. render a `<div>` for richer markup). */\n asChild?: boolean;\n}\n\n// ─── 3. Components ─── //\n\nfunction Modal(props: ModalProps) {\n return <DialogPrimitive.Root {...props} />;\n}\n\nfunction ModalTrigger({ className, ...props }: ModalTriggerProps) {\n // Radix Trigger supports asChild natively — pass through.\n return <DialogPrimitive.Trigger data-slot=\"modal-trigger\" className={className} {...props} />;\n}\n\nfunction ModalContent({\n size,\n showCloseButton = true,\n closeLabel = 'Close',\n className,\n children,\n ...props\n}: ModalContentProps) {\n // Anchor the Portal to the DgaProvider's body-level portal container.\n // Pattern documented in DgaContext.ts; regression test in Modal.test.tsx\n // mirrors Select/Tooltip. The portal container mirrors data-theme + dir +\n // CSS vars from the provider so theming still flows; using it (rather\n // than the in-tree `rootEl`) keeps the modal's `position: fixed` overlay\n // from being trapped by an ancestor `transform` or `overflow: hidden`\n // (Storybook autodocs is the motivating case).\n const ctx = useContext(DgaContext);\n const portalContainer = ctx?.portalEl ?? ctx?.rootEl ?? undefined;\n\n return (\n <DialogPrimitive.Portal container={portalContainer}>\n <DialogPrimitive.Overlay className=\"ddga-modal__overlay\" data-slot=\"modal-overlay\" />\n <DialogPrimitive.Content\n data-slot=\"modal-content\"\n className={cn(modalContentVariants({ size }), className)}\n {...props}\n >\n {children}\n {showCloseButton ? (\n <DialogPrimitive.Close\n className=\"ddga-modal__close\"\n aria-label={closeLabel}\n data-slot=\"modal-close-x\"\n >\n <Close aria-hidden=\"true\" />\n </DialogPrimitive.Close>\n ) : null}\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n );\n}\n\nfunction ModalHeader({ asChild, className, ...props }: ModalSectionProps) {\n const Comp = asChild ? SlotPrimitive.Slot : 'div';\n return (\n <Comp data-slot=\"modal-header\" className={cn('ddga-modal__header', className)} {...props} />\n );\n}\n\nfunction ModalTitle({ asChild, className, ...props }: ModalTitleProps) {\n // Dialog.Title wires aria-labelledby on the parent Content. We pass asChild\n // through so consumers can swap heading level (h2 → h1/h3) without losing\n // the labelling link.\n return (\n <DialogPrimitive.Title\n asChild={asChild}\n data-slot=\"modal-title\"\n className={cn('ddga-modal__title', className)}\n {...props}\n />\n );\n}\n\nfunction ModalDescription({ asChild, className, ...props }: ModalDescriptionProps) {\n // Dialog.Description wires aria-describedby on the parent Content. asChild\n // lets consumers swap the element if they need richer markup.\n return (\n <DialogPrimitive.Description\n asChild={asChild}\n data-slot=\"modal-description\"\n className={cn('ddga-modal__description', className)}\n {...props}\n />\n );\n}\n\nfunction ModalBody({ asChild, className, ...props }: ModalSectionProps) {\n // Scrollable middle region (mirrors DrawerBody) — grows to fill the space\n // between a pinned header and footer and scrolls internally when content\n // overflows, so a tall modal never clips and the footer stays visible with\n // zero consumer config. Optional: short, non-scrolling bodies can still drop\n // raw content directly under ModalContent (it gets the same inline padding).\n const Comp = asChild ? SlotPrimitive.Slot : 'div';\n return <Comp data-slot=\"modal-body\" className={cn('ddga-modal__body', className)} {...props} />;\n}\n\nfunction ModalFooter({ asChild, className, ...props }: ModalSectionProps) {\n const Comp = asChild ? SlotPrimitive.Slot : 'div';\n return (\n <Comp data-slot=\"modal-footer\" className={cn('ddga-modal__footer', className)} {...props} />\n );\n}\n\nfunction ModalClose({ className, ...props }: ModalCloseProps) {\n // Consumer-level close trigger for footer buttons etc. Radix Close supports\n // asChild natively — pass through so consumers can wrap a <Button>.\n return <DialogPrimitive.Close data-slot=\"modal-close\" className={className} {...props} />;\n}\n\n// ─── 4. Exports ─── //\n\nexport {\n Modal,\n ModalTrigger,\n ModalContent,\n ModalHeader,\n ModalTitle,\n ModalDescription,\n ModalBody,\n ModalFooter,\n ModalClose,\n modalContentVariants,\n};\nexport type {\n ModalProps,\n ModalTriggerProps,\n ModalContentProps,\n ModalSectionProps,\n ModalTitleProps,\n ModalDescriptionProps,\n ModalCloseProps,\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["'use client';\n\nimport { useContext } from 'react';\nimport { Tooltip as TooltipPrimitive } from 'radix-ui';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\nimport { DgaContext } from '../../providers/DgaContext';\n\n// ─── 1. Variants (cva) ─── //\n\nconst tooltipContentVariants = cva('ddga-tooltip', {\n variants: {\n size: {\n sm: 'ddga-tooltip--sm',\n md: 'ddga-tooltip--md',\n },\n },\n defaultVariants: {\n size: 'md',\n },\n});\n\n// ─── 2. Types ─── //\n//\n// We expose a closed compound shape that hides Radix's Provider/Portal/Arrow\n// details. `TooltipProvider` is already nested in `DgaProvider`, so consumers\n// don't need to add their own. The Portal container is wired from\n// `DgaContext.rootEl` (see DgaContext.ts) so the tooltip inherits `data-theme`\n// + custom theme classes set on the provider — without it, the tooltip would\n// silently mount under <body> and miss dark mode.\n\ntype TooltipProps = React.ComponentProps<typeof TooltipPrimitive.Root>;\n\ntype TooltipTriggerProps = React.ComponentProps<typeof TooltipPrimitive.Trigger>;\n\ninterface TooltipContentProps\n extends\n Omit<React.ComponentProps<typeof TooltipPrimitive.Content>, 'asChild'>,\n VariantProps<typeof tooltipContentVariants> {\n /** Show a small arrow pointing at the trigger. Defaults to true. */\n arrow?: boolean;\n}\n\n// ─── 3. Components ─── //\n\n/**\n * Tooltip root. **Must be rendered inside `<DgaProvider>`** — the provider\n * supplies the Radix `TooltipProvider` this depends on (and the themed portal\n * container). There is no need to add your own `TooltipProvider`; used outside\n * a `DgaProvider` the tooltip will not work.\n */\nfunction Tooltip(props: TooltipProps) {\n return <TooltipPrimitive.Root {...props} />;\n}\n\nfunction TooltipTrigger({ className, ...props }: TooltipTriggerProps) {\n // Radix Trigger already supports asChild natively — pass through.\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" className={className} {...props} />;\n}\n\nfunction TooltipContent({\n size,\n arrow = true,\n sideOffset = 6,\n className,\n children,\n ...props\n}: TooltipContentProps) {\n // Anchor the Portal to the DgaProvider's body-level portal container.\n // Theme + dark mode inherit through mirrored data-theme/dir/CSS vars on\n // the portal element; using it (rather than the in-tree `rootEl`) keeps\n // the tooltip from being clipped by ancestor overflow or trapped by an\n // ancestor `transform`. Falls back to <body> if used outside a provider.\n const ctx = useContext(DgaContext);\n const portalContainer = ctx?.portalEl ?? ctx?.rootEl ?? undefined;\n\n return (\n <TooltipPrimitive.Portal container={portalContainer}>\n <TooltipPrimitive.Content\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(tooltipContentVariants({ size }), className)}\n {...props}\n >\n {children}\n {arrow ? <TooltipPrimitive.Arrow className=\"ddga-tooltip__arrow\" /> : null}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n}\n\n// ─── 4. Exports ─── //\n\nexport { Tooltip, TooltipTrigger, TooltipContent, tooltipContentVariants };\nexport type { TooltipProps, TooltipTriggerProps, TooltipContentProps };\n"],"mappings":";;;;;;;;AAEA,SAAS,kBAAkB;AAC3B,SAAS,WAAW,wBAAwB;AAC5C,SAAS,WAA8B;AAgD9B,cA0BH,YA1BG;AA1CT,IAAM,yBAAyB,IAAI,gBAAgB;AAAA,EACjD,UAAU;AAAA,IACR,MAAM;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,IACN;AAAA,EACF;AAAA,EACA,iBAAiB;AAAA,IACf,MAAM;AAAA,EACR;AACF,CAAC;AA+BD,SAAS,QAAQ,OAAqB;AACpC,SAAO,oBAAC,iBAAiB,MAAjB,EAAuB,GAAG,OAAO;AAC3C;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,MAAM,GAAwB;AAEpE,SAAO,oBAAC,iBAAiB,SAAjB,EAAyB,aAAU,mBAAkB,WAAuB,GAAG,OAAO;AAChG;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA,QAAQ;AAAA,EACR,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAwB;AAMtB,QAAM,MAAM,WAAW,UAAU;AACjC,QAAM,kBAAkB,KAAK,YAAY,KAAK,UAAU;AAExD,SACE,oBAAC,iBAAiB,QAAjB,EAAwB,WAAW,iBAClC;AAAA,IAAC,iBAAiB;AAAA,IAAjB;AAAA,MACC,aAAU;AAAA,MACV;AAAA,MACA,WAAW,GAAG,uBAAuB,EAAE,KAAK,CAAC,GAAG,SAAS;AAAA,MACxD,GAAG;AAAA,MAEH;AAAA;AAAA,QACA,QAAQ,oBAAC,iBAAiB,OAAjB,EAAuB,WAAU,uBAAsB,IAAK;AAAA;AAAA;AAAA,EACxE,GACF;AAEJ;","names":[]}
|
|
@@ -93,6 +93,10 @@ function ModalDescription({ asChild, className, ...props }) {
|
|
|
93
93
|
}
|
|
94
94
|
);
|
|
95
95
|
}
|
|
96
|
+
function ModalBody({ asChild, className, ...props }) {
|
|
97
|
+
const Comp = asChild ? SlotPrimitive.Slot : "div";
|
|
98
|
+
return /* @__PURE__ */ jsx(Comp, { "data-slot": "modal-body", className: cn("ddga-modal__body", className), ...props });
|
|
99
|
+
}
|
|
96
100
|
function ModalFooter({ asChild, className, ...props }) {
|
|
97
101
|
const Comp = asChild ? SlotPrimitive.Slot : "div";
|
|
98
102
|
return /* @__PURE__ */ jsx(Comp, { "data-slot": "modal-footer", className: cn("ddga-modal__footer", className), ...props });
|
|
@@ -109,7 +113,8 @@ export {
|
|
|
109
113
|
ModalHeader,
|
|
110
114
|
ModalTitle,
|
|
111
115
|
ModalDescription,
|
|
116
|
+
ModalBody,
|
|
112
117
|
ModalFooter,
|
|
113
118
|
ModalClose
|
|
114
119
|
};
|
|
115
|
-
//# sourceMappingURL=chunk-
|
|
120
|
+
//# sourceMappingURL=chunk-JOJ23OD4.js.map
|