@exsto/ds 0.0.1-rc.6 → 0.0.1-rc.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/README.md +33 -0
  2. package/dist/chunks/toggle-C2c5oDaE.js +629 -0
  3. package/dist/chunks/toggle-C2c5oDaE.js.map +1 -0
  4. package/dist/ds/src/rich-text-editor.d.ts +8 -0
  5. package/dist/index.js +3 -470
  6. package/dist/index.js.map +1 -1
  7. package/dist/rich-text-editor.js +904 -0
  8. package/dist/rich-text-editor.js.map +1 -0
  9. package/dist/styles.css +159 -0
  10. package/dist/ui/src/components/edyn/rich-text-content/allow-list.d.ts +11 -0
  11. package/dist/ui/src/components/edyn/rich-text-content/index.d.ts +2 -0
  12. package/dist/ui/src/components/edyn/rich-text-content/rich-text-content.d.ts +22 -0
  13. package/dist/ui/src/components/edyn/rich-text-content/rich-text-content.test.d.ts +8 -0
  14. package/dist/ui/src/components/edyn/rich-text-editor/extensions.d.ts +18 -0
  15. package/dist/ui/src/components/edyn/rich-text-editor/index.d.ts +3 -0
  16. package/dist/ui/src/components/edyn/rich-text-editor/mention-list.d.ts +17 -0
  17. package/dist/ui/src/components/edyn/rich-text-editor/rich-text-editor.d.ts +53 -0
  18. package/dist/ui/src/components/edyn/rich-text-editor/rich-text-editor.test.d.ts +6 -0
  19. package/dist/ui/src/components/edyn/rich-text-editor/serialize.d.ts +13 -0
  20. package/dist/ui/src/components/edyn/rich-text-editor/sync.d.ts +19 -0
  21. package/dist/ui/src/components/edyn/rich-text-editor/sync.test.d.ts +11 -0
  22. package/dist/ui/src/components/edyn/rich-text-editor/toolbar.d.ts +20 -0
  23. package/dist/ui/src/components/edyn/rich-text-editor/types.d.ts +68 -0
  24. package/dist/ui/src/components/ui/popover/popover.d.ts +1 -1
  25. package/dist/ui/src/index.d.ts +1 -0
  26. package/package.json +21 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toggle-C2c5oDaE.js","names":[],"sources":["../../../ui/src/lib/utils.ts","../../../ui/src/components/ui/button/button.tsx","../../../ui/src/components/ui/popover/popover.tsx","../../../ui/src/hooks/use-merged-refs.ts","../../../ui/src/components/ui/scroll-area/scroll-area.tsx","../../../ui/src/lib/popup-list.ts","../../../ui/src/components/edyn/rich-text-content/allow-list.ts","../../../ui/src/components/edyn/rich-text-content/rich-text-content.tsx","../../../ui/src/components/ui/input/input.tsx","../../../ui/src/components/ui/dropdown-menu/dropdown-menu.tsx","../../../ui/src/components/ui/toggle/toggle.tsx"],"sourcesContent":["import type { ClassValue } from 'clsx';\nimport { clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport const cn = (...inputs: ClassValue[]): string => twMerge(clsx(inputs));\n\n/** A CSS length as a component prop: a number is px, a string is used verbatim. */\nexport type TCssLength = number | string;\n\n/**\n * Normalise a size prop to a CSS length.\n *\n * Bare numbers become px, which is also what a bare numeric *string* means: an\n * element attribute arrives as a string, so `width=\"480\"` and `width={480}` have\n * to land on the same value. Anything with a unit, a percentage or a keyword\n * passes through untouched.\n */\nexport const cssLength = (value: TCssLength | null | undefined): string | undefined => {\n if (value == null || value === '') {\n return undefined;\n }\n\n if (typeof value === 'number') {\n return Number.isFinite(value) ? `${value}px` : undefined;\n }\n\n return /^-?\\d*\\.?\\d+$/.test(value.trim()) ? `${value.trim()}px` : value;\n};\n","import { Button as ButtonPrimitive } from '@base-ui/react/button';\nimport { cn } from '@edyn/ui/lib/utils';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { isValidElement } from 'react';\n\nexport const buttonVariants = cva(\n \"group/button inline-flex shrink-0 cursor-pointer items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all motion-reduce:transition-none motion-reduce:transform-none outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/80',\n outline:\n 'border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50',\n secondary:\n 'bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground',\n ghost: 'hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50',\n destructive:\n 'bg-destructive/10 text-destructive hover:bg-destructive/15 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/15 dark:hover:bg-destructive/20 dark:focus-visible:ring-destructive/40',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2',\n xs: \"h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3\",\n sm: \"h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5\",\n lg: 'h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2',\n icon: 'size-8',\n 'icon-xs': \"size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3\",\n 'icon-sm': 'size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg',\n 'icon-lg': 'size-9',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\n/**\n * Whether this Button is rendering a link rather than a button, so it can keep\n * link semantics. Covers `render={<a href=\"...\" />}` and a routing component\n * that takes an `href` (Next's Link). A component with a different prop for its\n * destination (react-router's `to`) cannot be recognised from here: give those\n * `nativeButton={false} role={undefined}` directly.\n */\nconst rendersALink = (render: ButtonPrimitive.Props['render']): boolean =>\n isValidElement(render) && (render.type === 'a' || typeof (render.props as { href?: unknown }).href === 'string');\n\n/**\n * A link that looks like a button is still a link, and has to be announced as\n * one: it opens in a new tab, it has an address, Enter follows it and Space\n * scrolls the page.\n *\n * Base UI needs telling, in two steps. Rendering an anchor while `nativeButton`\n * is true (its default) warns in development and puts `type=\"button\"` on the\n * anchor; following the warning and passing `nativeButton={false}` then adds\n * `role=\"button\"`, which is what takes the link semantics away. So this does\n * both: non-native, with the role and the tabindex Base UI would add cleared\n * again. An explicit prop from the caller still wins over either.\n */\nconst LINK_PROPS = { nativeButton: false, role: undefined, tabIndex: undefined } as const;\n\nexport const Button = ({\n className,\n variant = 'default',\n size = 'default',\n ...props\n}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) => {\n return (\n <ButtonPrimitive\n data-slot=\"button\"\n {...(rendersALink(props.render) ? LINK_PROPS : {})}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n};\n","import { Popover as PopoverPrimitive } from '@base-ui/react/popover';\nimport { cn } from '@edyn/ui/lib/utils';\nimport type * as React from 'react';\n\nexport const Popover = ({ ...props }: PopoverPrimitive.Root.Props) => {\n return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />;\n};\n\nexport const PopoverTrigger = ({ ...props }: PopoverPrimitive.Trigger.Props) => {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />;\n};\n\nexport const PopoverContent = ({\n className,\n align = 'center',\n alignOffset = 0,\n side = 'bottom',\n sideOffset = 4,\n anchor,\n ...props\n}: PopoverPrimitive.Popup.Props & Pick<PopoverPrimitive.Positioner.Props, 'align' | 'alignOffset' | 'anchor' | 'side' | 'sideOffset'>) => {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Positioner\n align={align}\n alignOffset={alignOffset}\n anchor={anchor}\n side={side}\n sideOffset={sideOffset}\n className=\"isolate z-50\"\n >\n <PopoverPrimitive.Popup\n data-slot=\"popover-content\"\n className={cn(\n 'z-50 flex w-72 origin-(--transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 motion-reduce:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',\n className,\n )}\n {...props}\n />\n </PopoverPrimitive.Positioner>\n </PopoverPrimitive.Portal>\n );\n};\n\nexport const PopoverHeader = ({ className, ...props }: React.ComponentProps<'div'>) => {\n return <div data-slot=\"popover-header\" className={cn('flex flex-col gap-0.5 text-sm', className)} {...props} />;\n};\n\nexport const PopoverTitle = ({ className, ...props }: PopoverPrimitive.Title.Props) => {\n return <PopoverPrimitive.Title data-slot=\"popover-title\" className={cn('font-medium', className)} {...props} />;\n};\n\nexport const PopoverDescription = ({ className, ...props }: PopoverPrimitive.Description.Props) => {\n return <PopoverPrimitive.Description data-slot=\"popover-description\" className={cn('text-muted-foreground', className)} {...props} />;\n};\n","import { type Ref, type RefCallback, useCallback } from 'react';\n\ntype TPossibleRef<T> = Ref<T> | undefined;\n\nconst assignRef = <T>(ref: TPossibleRef<T>, value: T) => {\n if (typeof ref === 'function') {\n ref(value);\n } else if (ref !== null) {\n // Using type assertion to RefObject since we know it's not null\n (ref as { current: T }).current = value;\n }\n};\n\nconst mergeRefs = <T>(...refs: TPossibleRef<T>[]) => {\n return (node: T) => {\n for (const ref of refs) {\n if (ref) {\n assignRef(ref, node);\n }\n }\n };\n};\n\nexport const useMergedRefs = <T>(...refs: TPossibleRef<T>[]) => {\n return useCallback(mergeRefs(...refs), [...refs]) as RefCallback<T>;\n};\n","import { ScrollArea as BaseScrollArea } from '@base-ui/react/scroll-area';\nimport { useMergedRefs } from '@edyn/ui/hooks/use-merged-refs';\nimport { cn } from '@edyn/ui/lib/utils';\nimport { type ComponentProps, type RefObject, useEffect, useRef } from 'react';\n\n/**\n * When the bar shows: 'hover' on area hover or while scrolling (default),\n * 'scroll' only while scrolling, 'always' permanent. In every mode the bar is\n * mounted only while that axis actually overflows, so 'always' means \"always\n * when there is something to scroll\", never a bar on a list that fits.\n */\nexport type TScrollbarVisibility = 'hover' | 'scroll' | 'always';\n\n/**\n * Surface the edge fades blended into, back when they were painted.\n *\n * @deprecated The fades are cut into the content by a mask, so they match any\n * surface without being told which one. Still accepted, and ignored.\n */\nexport type TScrollAreaFadeFrom = 'card' | 'background' | 'sidebar' | 'popover';\n\nexport interface IScrollBarProps extends ComponentProps<typeof BaseScrollArea.Scrollbar> {\n visibility?: TScrollbarVisibility;\n}\n\nexport const ScrollBar = ({ className, orientation = 'vertical', visibility = 'hover', ...props }: IScrollBarProps) => {\n return (\n <BaseScrollArea.Scrollbar\n data-slot=\"scroll-area-scrollbar\"\n orientation={orientation}\n className={cn(\n 'peer/scrollbar z-100 flex touch-none select-none motion-safe:transition-opacity motion-safe:duration-150',\n // Size, gap and start read --scroll-bar-size, --scroll-bar-gap and --scroll-bar-start (see scroll-bar.css), whose\n // defaults are the 8px bar flush with the box that it has always been.\n orientation === 'vertical' &&\n 'h-(--scroll-bar-length) w-(--scroll-bar-size) me-(--scroll-bar-gap) mt-(--scroll-bar-offset-top) border-l border-l-transparent p-px',\n orientation === 'horizontal' &&\n 'h-(--scroll-bar-size) ms-(--scroll-bar-gap) me-(--scroll-bar-gap) mb-(--scroll-bar-gap) flex-col border-t border-t-transparent p-px',\n visibility !== 'always' && 'opacity-0 data-scrolling:opacity-100',\n visibility === 'hover' && 'data-hovering:opacity-100 group-hover/scroll-area:opacity-100',\n className,\n )}\n {...props}\n >\n <BaseScrollArea.Thumb className=\"relative flex-1 rounded-full bg-muted-foreground/50 transition-colors hover:bg-muted-foreground/70 data-scrolling:bg-muted-foreground/70\" />\n </BaseScrollArea.Scrollbar>\n );\n};\n\nexport interface IScrollAreaProps extends ComponentProps<typeof BaseScrollArea.Root> {\n /** Which axes get a styled scrollbar; content decides what actually overflows. */\n orientation?: 'horizontal' | 'vertical' | 'both';\n /** Scrollbar reveal behavior (mirrors the Radix ScrollArea `type` prop). */\n type?: TScrollbarVisibility;\n /** Edge fades hinting at clipped content; each one shows only while its own edge hides something. */\n fade?: boolean;\n /**\n * @deprecated No longer read. The fades mask the content, so they sit correctly\n * on any surface; passing this does nothing and is safe to delete.\n */\n fadeFrom?: TScrollAreaFadeFrom;\n /** Places both bars, for a host that gives them a gutter of their own (a sidebar menu). */\n scrollbarClassName?: string;\n viewportId?: string;\n /** Access to the scrollable viewport (e.g. to reset scroll position on route changes). */\n viewportRef?: RefObject<HTMLDivElement | null>;\n viewportClassName?: string;\n /** Published on the viewport as data-scroll-restoration-id, for a router that restores scroll position. */\n scrollRestorationId?: string;\n /**\n * Whether the viewport is a tab stop of its own (default). Turn it off inside a\n * widget that already owns focus, a menu above all: its items are the tab\n * stops, and a focusable wrapper between the role and its items is both\n * redundant and an aria-required-children violation.\n */\n focusable?: boolean;\n /** @deprecated Use `viewportId`. */\n viewPortId?: string;\n /** @deprecated Use `viewportRef`. */\n viewPortRef?: RefObject<HTMLDivElement | null>;\n /** @deprecated Use `viewportClassName`. */\n viewPortClassName?: string;\n /** Places the vertical bar only; `scrollbarClassName` covers both. */\n scrollVerticalClassName?: string;\n /** Places the horizontal bar only; `scrollbarClassName` covers both. */\n scrollHorizontalClassName?: string;\n}\n\n/**\n * Which axes fade, published for scroll-fade.css to key its mask off. The\n * stylesheet reaches this element's own viewport through a child combinator, so a\n * ScrollArea nested in another one cannot pick up its ancestor's edges.\n */\n/**\n * Base UI gives the root, the viewport and the content `role=\"presentation\"`. On\n * a div that changes nothing for a screen reader, but it is an EXPLICIT role, and\n * axe treats explicit presentation children as foreign to a parent that owns\n * required children. A ScrollArea inside `role=\"menu\"` or `role=\"listbox\"` then\n * fails as a critical aria-required-children violation, while the same div with\n * no role passes straight through. Clearing it is what makes a ScrollArea legal\n * in a popup list. A spread because the literal `role={undefined}` is flagged by\n * the a11y lint rule, which cannot tell it from an invalid role.\n */\nconst NO_ROLE = { role: undefined } as const;\n\n/** Base UI makes the viewport a tab stop (0, or -1 with nothing to scroll); undefined takes that away. */\nconst NO_TAB_STOP = { tabIndex: undefined } as const;\n\nconst FADE_AXIS = {\n vertical: 'block',\n horizontal: 'inline',\n both: 'both',\n} as const;\n\n/**\n * Themed scroll container (Base UI): overflowing content scrolls INSIDE the component\n * with a slim overlay scrollbar instead of exposing a native browser scrollbar. House\n * rule: wide/tall content (tables, lists, code) always goes through this, never a bare\n * overflow-* utility.\n *\n * Cap the height with a plain class on the component itself, e.g.\n * `<ScrollArea className=\"max-h-88\">`. The viewport picks the cap up through\n * `max-h-inherit`, which matters because the viewport is the element that actually\n * scrolls: a cap that lands only on the root leaves tall content spilling out\n * underneath with no scrollbar, and that reads as a working height right up until the\n * content outgrows it.\n *\n * `fade` fades out each edge that is currently hiding content, rather than always\n * fading one: a permanent fade is a lie half the time, dimming the last row that fits\n * and promising more below when the reader is already at the end. It is cut into the\n * content by a mask (@edyn/theme/scroll-fade.css), so it needs no surface colour and\n * reads correctly over a tint, a gradient or a glow. A host that keeps something\n * unscrolled at the top, such as a sticky table header, exempts that band by setting\n * --scroll-fade-offset on the ScrollArea. The static faded-* utilities in\n * @edyn/theme/utilities.css are the other tool, for DECORATIVE edges that do not\n * track scroll position.\n *\n * The viewport publishes its size as --scroll-area-width/--scroll-area-height CSS vars\n * so children can size against the visible area.\n */\nexport const ScrollArea = ({\n className,\n children,\n orientation = 'vertical',\n type = 'hover',\n fade = false,\n fadeFrom = 'card',\n scrollbarClassName,\n viewportId,\n viewportRef,\n viewportClassName,\n scrollRestorationId,\n focusable = true,\n viewPortId,\n viewPortRef,\n viewPortClassName,\n scrollVerticalClassName,\n scrollHorizontalClassName,\n ...props\n}: IScrollAreaProps) => {\n const refInner = useRef<HTMLDivElement | null>(null);\n // The viewPort* spellings are the pre-rc.4 names, kept so existing callers\n // keep working; the viewport* ones match the rest of the ecosystem.\n const refsViewport = useMergedRefs(refInner, viewportRef ?? viewPortRef);\n\n useEffect(() => {\n const el = refInner.current;\n if (!el) {\n return;\n }\n const observer = new ResizeObserver(() => {\n el.style.setProperty('--scroll-area-width', `${el.clientWidth}px`);\n el.style.setProperty('--scroll-area-height', `${el.clientHeight}px`);\n });\n observer.observe(el);\n return () => {\n observer.disconnect();\n };\n }, []);\n\n return (\n <BaseScrollArea.Root\n data-slot=\"scroll-area\"\n // Everything inside clips at this box, so a focus ring drawn outside an\n // element at the edge would be cut off; see @edyn/theme/focus.css.\n data-focus=\"inset\"\n // The single-row grid is load-bearing rather than tidying. `h-full` on the viewport\n // cannot be trusted to size it: a percentage height only resolves against a definite\n // containing block, and a host that sizes this by flex inside a max-height column\n // (`min-h-0 flex-1`) is not definite, so the viewport fell back to auto and grew to\n // its content instead of scrolling. A grid item stretches to its track, and the track\n // is sized from the root's used height, which flex has already settled. `grid-rows-1`\n // is `repeat(1, minmax(0, 1fr))`: one track that may shrink below its content.\n className={cn('group/scroll-area relative grid min-w-0 grid-rows-1 overflow-hidden', className)}\n data-fade={fade ? FADE_AXIS[orientation] : undefined}\n {...NO_ROLE}\n {...props}\n >\n {(orientation === 'vertical' || orientation === 'both') && (\n <ScrollBar orientation=\"vertical\" visibility={type} className={cn(scrollbarClassName, scrollVerticalClassName)} />\n )}\n {(orientation === 'horizontal' || orientation === 'both') && (\n <ScrollBar orientation=\"horizontal\" visibility={type} className={cn(scrollbarClassName, scrollHorizontalClassName)} />\n )}\n <BaseScrollArea.Corner />\n <BaseScrollArea.Viewport\n data-slot=\"scroll-area-viewport\"\n id={viewportId ?? viewPortId}\n ref={refsViewport}\n data-scroll-restoration-id={scrollRestorationId}\n {...NO_ROLE}\n {...(focusable ? null : NO_TAB_STOP)}\n // One axis means one axis. Base UI leaves both axes scrollable, so a\n // vertical list could still be dragged sideways, and anything that put a\n // row in view (focus moving, scrollIntoView with inline: nearest) slid\n // the whole list across. The clamp is marked important because Base UI\n // sets the viewport's overflow itself.\n className={cn(\n 'max-h-inherit w-full rounded-[inherit]',\n orientation === 'vertical' && 'overflow-x-hidden!',\n orientation === 'horizontal' && 'overflow-y-hidden!',\n viewportClassName ?? viewPortClassName,\n )}\n >\n {/* Content is NOT optional: it carries the ResizeObserver that recomputes the\n thumb when the CONTENT resizes without the viewport resizing (e.g. a route\n swap to a shorter page). Without it the thumb keeps the previous page's\n geometry and a fully-visible page still shows a scrollbar.\n\n A vertical scroller also pins its content to the viewport's width, so a\n long label truncates instead of widening the list and inventing a\n horizontal scroll. Base UI sets min-width: fit-content inline, which is\n what makes that happen and why this is an inline style too. */}\n <BaseScrollArea.Content {...NO_ROLE} style={orientation === 'vertical' ? { minWidth: 0 } : undefined}>\n {children}\n </BaseScrollArea.Content>\n </BaseScrollArea.Viewport>\n </BaseScrollArea.Root>\n );\n};\n","import { cn } from '@edyn/ui/lib/utils';\n\n/**\n * The one look for a list in a popup or a menu: the command palette, Select,\n * Combobox, MultiSelect and the dropdown menus.\n *\n * These lists used to disagree with each other in every detail that shows:\n * three different radii, two different paddings, a grey fill for the highlight\n * in one and the accent in another, and the chosen item marked by a check on\n * the left in Select and on the right in the menus. Picking something from one\n * list then felt like a different product from picking something in the next.\n *\n * It lives here as classes rather than as a stylesheet so a caller's own\n * className still wins: an unlayered rule would beat every utility, including\n * the one someone passes for a single list.\n *\n * ONE ITEM: transparent at rest, 32px tall, 6px radius (--radius-sm), 6px by\n * 8px of padding, text-sm, its own icons 16px and muted. Under the pointer or\n * the keyboard it takes one translucent fill of the text colour, and its icons\n * the text colour. Chosen is medium weight with a check at the END, never a\n * fill, so \"where I am\" and \"what I picked\" can be told apart at a glance.\n */\n\n/**\n * Which primitive renders the item, because the two disagree about the same\n * attribute names in a way that silently breaks the styling:\n *\n * - cmdk writes `data-selected=\"false\"` and `data-disabled=\"false\"` on items\n * that are neither, so a bare `data-selected:` variant matches EVERY item and\n * highlights the whole list. Its states have to be matched by value.\n * - Base UI omits the attribute instead, so presence is the test there. That\n * needs the BRACKET form for `selected`: shadcn redefines the bare\n * `data-selected:` variant to match only data-selected=\"true\" (for the\n * calendar), and Base UI writes it as an empty string, so the bare form\n * compiles and silently never applies. `highlighted` and `disabled` have no\n * such override, so those stay bare.\n * - And the same name means different things: cmdk's `data-selected` is the\n * keyboard cursor, Base UI's is the chosen value. In cmdk the chosen state is\n * `data-checked`, which the DS's own CommandItem sets.\n */\nexport type TPopupItemFlavor = 'base-ui' | 'cmdk';\n\nconst ITEM_BASE =\n \"relative flex min-h-8 cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm text-foreground outline-none select-none [&>svg]:pointer-events-none [&>svg]:shrink-0 [&>svg]:text-muted-foreground [&>svg:not([class*='size-'])]:size-4\";\n\nconst ITEM_STATES: Record<TPopupItemFlavor, string> = {\n 'base-ui':\n 'data-highlighted:bg-foreground/6 data-highlighted:[&>svg]:text-foreground data-[selected]:font-medium data-disabled:pointer-events-none data-disabled:opacity-50',\n cmdk: 'data-[selected=true]:bg-foreground/6 data-[selected=true]:[&>svg]:text-foreground data-[checked=true]:font-medium data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50',\n};\n\n/** The shared item look. `checkable` leaves room at the end for the check. */\nexport const popupItemClass = (flavor: TPopupItemFlavor = 'base-ui', checkable = false): string =>\n cn(ITEM_BASE, ITEM_STATES[flavor], checkable && 'pr-8');\n\n/**\n * The check's slot, at the end of the item and the same size whether or not the\n * check is in it, so a list does not shift as the choice moves.\n */\nexport const POPUP_ITEM_INDICATOR_CLASS = 'pointer-events-none absolute right-2 flex size-4 items-center justify-center text-foreground';\n\n/** A group's heading in any of these lists. */\nexport const POPUP_GROUP_LABEL_CLASS = 'px-2 py-1.5 text-xs font-medium text-muted-foreground';\n","/**\n * The HTML the rich-text editor emits, and the only HTML RichTextContent renders. An app that\n * sanitises on a server takes its allow-list from here: nothing outside these elements and this\n * attribute ever comes out of the editor, whatever was pasted into it.\n */\nexport const RICH_TEXT_ELEMENTS = ['p', 'br', 'hr', 'strong', 'em', 'u', 'ul', 'ol', 'li', 'a'] as const;\n\n/** The attributes each element may carry. Every other element carries none (no class, no style). */\nexport const RICH_TEXT_ATTRIBUTES: Readonly<Record<string, readonly string[]>> = { a: ['href'] };\n\n/** A link must be absolute and use one of these. `javascript:`, `data:` and relative links are refused. */\nexport const RICH_TEXT_LINK_PROTOCOLS = ['http', 'https', 'mailto'] as const;\n\nexport const isAllowedRichTextHref = (href: string): boolean => {\n const cleaned = Array.from(href)\n .filter((char) => char.charCodeAt(0) > 32)\n .join('');\n const colon = cleaned.indexOf(':');\n if (colon < 1) {\n return false;\n }\n const protocol = cleaned.slice(0, colon).toLowerCase();\n return (RICH_TEXT_LINK_PROTOCOLS as readonly string[]).includes(protocol);\n};\n","import { cn } from '@edyn/ui/lib/utils';\nimport { createElement, type HTMLAttributes, type ReactNode, useMemo } from 'react';\nimport { isAllowedRichTextHref } from './allow-list';\n\n/**\n * How rich text looks, shared by the editor and by RichTextContent so a comment reads the same while it is typed and\n * after it is saved. Descendant selectors rather than classes on the elements, because the HTML that is stored carries\n * no classes.\n */\nexport const RICH_TEXT_BODY_CLASS =\n 'text-sm leading-6 wrap-break-word [&_a]:text-primary [&_a]:underline [&_a]:underline-offset-2 [&_hr]:my-3 [&_hr]:border-0 [&_hr]:border-t [&_hr]:border-border [&_ol]:list-decimal [&_ol]:ps-5 [&_p+p]:mt-2 [&_ul]:list-disc [&_ul]:ps-5 [&_ul+p]:mt-2 [&_ol+p]:mt-2 [&_p+ul]:mt-2 [&_p+ol]:mt-2';\n\nconst MENTION_PATTERN = /(?<![\\w.+-])@(?:assignees\\b|[A-Za-z0-9._%+-]+@[A-Za-z0-9-]+(?:\\.[A-Za-z0-9-]+)+)/g;\n\nexport const RICH_TEXT_MENTION_CLASS = 'rounded-sm bg-primary/10 px-1 py-0.5 font-medium text-primary';\n\nconst TAG_FOR: Readonly<Record<string, string>> = { b: 'strong', i: 'em' };\nconst KEPT = new Set(['p', 'strong', 'em', 'u', 'ul', 'ol', 'li', 'a', 'br', 'hr']);\nconst DROPPED_WITH_CONTENT = new Set(['script', 'style', 'template', 'iframe', 'object', 'embed', 'noscript', 'svg', 'math', 'head', 'title']);\n\nconst withMentions = (text: string, key: string): ReactNode[] => {\n const parts: ReactNode[] = [];\n let last = 0;\n for (const match of text.matchAll(MENTION_PATTERN)) {\n const start = match.index ?? 0;\n if (start > last) {\n parts.push(text.slice(last, start));\n }\n parts.push(\n <span key={`${key}-${start}`} data-slot=\"rich-text-mention\" className={RICH_TEXT_MENTION_CLASS}>\n {match[0]}\n </span>,\n );\n last = start + match[0].length;\n }\n if (last < text.length) {\n parts.push(text.slice(last));\n }\n return parts;\n};\n\nconst toNodes = (parent: Node, key: string, insideLink: boolean): ReactNode[] => {\n const out: ReactNode[] = [];\n parent.childNodes.forEach((child, index) => {\n const childKey = `${key}.${index}`;\n if (child.nodeType === 3) {\n const text = child.textContent ?? '';\n out.push(...(insideLink ? [text] : withMentions(text, childKey)));\n return;\n }\n if (child.nodeType !== 1) {\n return;\n }\n const element = child as Element;\n const name = element.tagName.toLowerCase();\n if (DROPPED_WITH_CONTENT.has(name)) {\n return;\n }\n const tag = TAG_FOR[name] ?? name;\n if (!KEPT.has(tag)) {\n out.push(...toNodes(element, childKey, insideLink));\n return;\n }\n if (tag === 'br') {\n out.push(<br key={childKey} />);\n return;\n }\n if (tag === 'hr') {\n out.push(<hr key={childKey} />);\n return;\n }\n if (tag === 'a') {\n const href = element.getAttribute('href') ?? '';\n const inner = toNodes(element, childKey, true);\n out.push(\n ...(isAllowedRichTextHref(href)\n ? [\n <a key={childKey} href={href.trim()} rel=\"noopener noreferrer\" target=\"_blank\">\n {inner}\n </a>,\n ]\n : inner),\n );\n return;\n }\n out.push(createElement(tag, { key: childKey }, ...toNodes(element, childKey, insideLink)));\n });\n return out;\n};\n\n/** The HTML as React elements, keeping only what the editor can produce. Browser only (it needs a DOM parser). */\nexport const richTextToNodes = (html: string): ReactNode[] => {\n if (typeof DOMParser === 'undefined' || html === '') {\n return [];\n }\n const parsed = new DOMParser().parseFromString(`<body>${html}`, 'text/html');\n return toNodes(parsed.body, 'r', false);\n};\n\nexport interface IRichTextContentProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'dangerouslySetInnerHTML'> {\n /** The HTML to show. Only the editor's elements are rendered, whatever else it holds. */\n html: string;\n}\n\n/**\n * Shows rich text the editor produced (or any HTML), as the same elements the editor emits and nothing else:\n * `p`, `br`, `hr`, `strong`, `em`, `u`, `ul`, `ol`, `li` and `a` with an `href` (http, https or mailto; it opens in a new tab\n * with `rel=\"noopener noreferrer\"`). Everything else is dropped and its text kept. Built as React elements, not injected\n * as markup, so it is safe on HTML that has not been cleaned. A run like `@name@example.test` or `@assignees` is shown\n * as a chip.\n */\nexport const RichTextContent = ({ html, className, ...props }: IRichTextContentProps) => {\n const nodes = useMemo(() => richTextToNodes(html), [html]);\n return (\n <div data-slot=\"rich-text-content\" className={cn(RICH_TEXT_BODY_CLASS, className)} {...props}>\n {nodes}\n </div>\n );\n};\n","import { Input as InputPrimitive } from '@base-ui/react/input';\nimport { cn } from '@edyn/ui/lib/utils';\nimport type * as React from 'react';\n\nexport const Input = ({ className, type, ...props }: React.ComponentProps<'input'>) => {\n return (\n <InputPrimitive\n type={type}\n data-slot=\"input\"\n className={cn(\n 'h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40',\n className,\n )}\n {...props}\n />\n );\n};\n","import { Menu as MenuPrimitive } from '@base-ui/react/menu';\nimport { POPUP_GROUP_LABEL_CLASS, POPUP_ITEM_INDICATOR_CLASS, popupItemClass } from '@edyn/ui/lib/popup-list';\nimport { cn } from '@edyn/ui/lib/utils';\nimport { IconCheck, IconChevronRight } from '@tabler/icons-react';\nimport type * as React from 'react';\nimport { ScrollArea } from '../scroll-area';\n\nexport const DropdownMenu = ({ ...props }: MenuPrimitive.Root.Props) => {\n return <MenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\n};\n\nexport const DropdownMenuPortal = ({ ...props }: MenuPrimitive.Portal.Props) => {\n return <MenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />;\n};\n\nexport const DropdownMenuTrigger = ({ ...props }: MenuPrimitive.Trigger.Props) => {\n return <MenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />;\n};\n\n/**\n * Scrolls inside a DS ScrollArea like the other popup lists, with the bar shown\n * for as long as the menu overflows and a fade on whichever end is cut off.\n *\n * Base UI puts `role=\"menu\"` on this popup itself and offers no inner list part\n * to move it onto, so the ScrollArea sits INSIDE the role. That is only legal\n * because ScrollArea drops the `role=\"presentation\"` Base UI gives its root,\n * viewport and content: a menu may not own presentation wrappers (axe reports\n * a critical aria-required-children violation), but it may own plain divs.\n * e2e/a11y.spec.ts scans the open menu in both themes to keep it that way.\n */\nexport const DropdownMenuContent = ({\n align = 'start',\n alignOffset = 0,\n side = 'bottom',\n sideOffset = 4,\n className,\n children,\n ...props\n}: MenuPrimitive.Popup.Props & Pick<MenuPrimitive.Positioner.Props, 'align' | 'alignOffset' | 'side' | 'sideOffset'>) => {\n return (\n <MenuPrimitive.Portal>\n <MenuPrimitive.Positioner className=\"isolate z-50 outline-none\" align={align} alignOffset={alignOffset} side={side} sideOffset={sideOffset}>\n <MenuPrimitive.Popup\n data-slot=\"dropdown-menu-content\"\n className={cn(\n 'z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-hidden rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95',\n 'motion-reduce:animate-none',\n className,\n )}\n {...props}\n >\n {/* max-h-inherit hands the positioner's measured height to the element that\n scrolls; the padding sits on the content so the cap is the popup's exactly. */}\n <ScrollArea type=\"always\" fade focusable={false} className=\"max-h-inherit\">\n <div className=\"p-1\">{children}</div>\n </ScrollArea>\n </MenuPrimitive.Popup>\n </MenuPrimitive.Positioner>\n </MenuPrimitive.Portal>\n );\n};\n\nexport const DropdownMenuGroup = ({ ...props }: MenuPrimitive.Group.Props) => {\n return <MenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />;\n};\n\nexport const DropdownMenuLabel = ({\n className,\n inset,\n ...props\n}: MenuPrimitive.GroupLabel.Props & {\n inset?: boolean;\n}) => {\n return (\n <MenuPrimitive.GroupLabel\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(POPUP_GROUP_LABEL_CLASS, 'data-[inset=true]:pl-7', className)}\n {...props}\n />\n );\n};\n\nexport const DropdownMenuItem = ({\n className,\n inset,\n variant = 'default',\n ...props\n}: MenuPrimitive.Item.Props & {\n inset?: boolean;\n variant?: 'default' | 'destructive';\n}) => {\n return (\n <MenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n 'group/dropdown-menu-item',\n popupItemClass(),\n 'data-[inset=true]:pl-7',\n // A destructive item keeps its own colour, and its own highlight with it:\n // the shared translucent one would make it read like any other item.\n 'data-[variant=destructive]:text-destructive data-[variant=destructive]:[&>svg]:text-destructive',\n 'data-[variant=destructive]:data-highlighted:bg-destructive/10 data-[variant=destructive]:data-highlighted:text-destructive',\n className,\n )}\n {...props}\n />\n );\n};\n\nexport const DropdownMenuSub = ({ ...props }: MenuPrimitive.SubmenuRoot.Props) => {\n return <MenuPrimitive.SubmenuRoot data-slot=\"dropdown-menu-sub\" {...props} />;\n};\n\nexport const DropdownMenuSubTrigger = ({\n className,\n inset,\n children,\n ...props\n}: MenuPrimitive.SubmenuTrigger.Props & {\n inset?: boolean;\n}) => {\n return (\n <MenuPrimitive.SubmenuTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n popupItemClass(),\n // An open submenu holds its trigger in the highlight while the pointer is\n // down in its panel.\n 'data-[inset=true]:pl-7 data-popup-open:bg-foreground/6 data-popup-open:[&>svg]:text-foreground',\n className,\n )}\n {...props}\n >\n {children}\n <IconChevronRight className=\"ml-auto\" />\n </MenuPrimitive.SubmenuTrigger>\n );\n};\n\nexport const DropdownMenuSubContent = ({\n align = 'start',\n alignOffset = -3,\n side = 'right',\n sideOffset = 0,\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuContent>) => {\n return (\n <DropdownMenuContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n 'w-auto min-w-[96px] rounded-lg bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',\n 'motion-reduce:animate-none',\n className,\n )}\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n {...props}\n />\n );\n};\n\nexport const DropdownMenuCheckboxItem = ({\n className,\n children,\n checked,\n inset,\n ...props\n}: MenuPrimitive.CheckboxItem.Props & {\n inset?: boolean;\n}) => {\n return (\n <MenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n data-inset={inset}\n className={cn(popupItemClass('base-ui', true), 'data-checked:font-medium data-[inset=true]:pl-7', className)}\n checked={checked}\n {...props}\n >\n <span className={POPUP_ITEM_INDICATOR_CLASS} data-slot=\"dropdown-menu-checkbox-item-indicator\">\n <MenuPrimitive.CheckboxItemIndicator>\n <IconCheck />\n </MenuPrimitive.CheckboxItemIndicator>\n </span>\n {children}\n </MenuPrimitive.CheckboxItem>\n );\n};\n\nexport const DropdownMenuRadioGroup = ({ ...props }: MenuPrimitive.RadioGroup.Props) => {\n return <MenuPrimitive.RadioGroup data-slot=\"dropdown-menu-radio-group\" {...props} />;\n};\n\nexport const DropdownMenuRadioItem = ({\n className,\n children,\n inset,\n ...props\n}: MenuPrimitive.RadioItem.Props & {\n inset?: boolean;\n}) => {\n return (\n <MenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n data-inset={inset}\n className={cn(popupItemClass('base-ui', true), 'data-checked:font-medium data-[inset=true]:pl-7', className)}\n {...props}\n >\n <span className={POPUP_ITEM_INDICATOR_CLASS} data-slot=\"dropdown-menu-radio-item-indicator\">\n <MenuPrimitive.RadioItemIndicator>\n <IconCheck />\n </MenuPrimitive.RadioItemIndicator>\n </span>\n {children}\n </MenuPrimitive.RadioItem>\n );\n};\n\nexport const DropdownMenuSeparator = ({ className, ...props }: MenuPrimitive.Separator.Props) => {\n return <MenuPrimitive.Separator data-slot=\"dropdown-menu-separator\" className={cn('-mx-1 my-1 h-px bg-border', className)} {...props} />;\n};\n\nexport const DropdownMenuShortcut = ({ className, ...props }: React.ComponentProps<'span'>) => {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn('ml-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground', className)}\n {...props}\n />\n );\n};\n","import { Toggle as TogglePrimitive } from '@base-ui/react/toggle';\nimport { cn } from '@edyn/ui/lib/utils';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nexport const toggleVariants = cva(\n 'inline-flex shrink-0 cursor-pointer items-center justify-center gap-1.5 rounded-lg border border-transparent text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 data-pressed:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\"size-\"])]:size-4',\n {\n variants: {\n variant: {\n default: 'bg-transparent hover:bg-muted hover:text-foreground data-pressed:bg-muted',\n outline:\n 'border-border bg-background hover:bg-muted hover:text-foreground data-pressed:bg-muted dark:border-input dark:bg-input/30 dark:hover:bg-input/50',\n },\n size: {\n sm: 'h-7 px-2.5 text-[0.8rem]',\n default: 'h-8 px-2.5',\n lg: 'h-9 px-3',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nexport type TToggleVariants = VariantProps<typeof toggleVariants>;\n\nexport const Toggle = <Value extends string>({\n className,\n variant = 'default',\n size = 'default',\n ...props\n}: TogglePrimitive.Props<Value> & TToggleVariants) => {\n return <TogglePrimitive data-slot=\"toggle\" className={cn(toggleVariants({ variant, size, className }))} {...props} />;\n};\n"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * `@exsto/ds/rich-text-editor` - the rich-text editor, on its own entry on purpose.
3
+ *
4
+ * The editor carries its own engine (TipTap on ProseMirror, roughly 140 KB gzipped). Re-exported from
5
+ * `@exsto/ds` it would be one more import in the entry every consumer loads, and a bundler cannot
6
+ * always tell it unused. Here an app pays for it only on the pages that import this path.
7
+ */
8
+ export * from '../../ui/src/components/edyn/rich-text-editor';