@exsto/ds 0.0.1-rc.5 → 0.0.1-rc.7

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 (27) 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 +174 -576
  6. package/dist/index.js.map +1 -1
  7. package/dist/rich-text-editor.js +846 -0
  8. package/dist/rich-text-editor.js.map +1 -0
  9. package/dist/styles.css +221 -51
  10. package/dist/ui/src/components/edyn/date-range-picker/date-range-picker.d.ts +7 -1
  11. package/dist/ui/src/components/edyn/multi-select/multi-select.d.ts +10 -2
  12. package/dist/ui/src/components/edyn/rich-text-content/allow-list.d.ts +11 -0
  13. package/dist/ui/src/components/edyn/rich-text-content/index.d.ts +2 -0
  14. package/dist/ui/src/components/edyn/rich-text-content/rich-text-content.d.ts +22 -0
  15. package/dist/ui/src/components/edyn/rich-text-content/rich-text-content.test.d.ts +8 -0
  16. package/dist/ui/src/components/edyn/rich-text-editor/extensions.d.ts +18 -0
  17. package/dist/ui/src/components/edyn/rich-text-editor/index.d.ts +3 -0
  18. package/dist/ui/src/components/edyn/rich-text-editor/mention-list.d.ts +17 -0
  19. package/dist/ui/src/components/edyn/rich-text-editor/rich-text-editor.d.ts +53 -0
  20. package/dist/ui/src/components/edyn/rich-text-editor/rich-text-editor.test.d.ts +6 -0
  21. package/dist/ui/src/components/edyn/rich-text-editor/serialize.d.ts +13 -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/components/ui/progress/progress.d.ts +38 -4
  26. package/dist/ui/src/index.d.ts +1 -0
  27. package/package.json +21 -1
@@ -30,6 +30,12 @@ export interface IMultiSelectProps {
30
30
  options: readonly TMultiSelectOption[];
31
31
  value: readonly string[];
32
32
  onValueChange: (value: string[]) => void;
33
+ /**
34
+ * What the trigger says once something is chosen. `selection` (default) names the one chosen or counts several;
35
+ * `label` keeps the label and only counts, so a value the page shows elsewhere (as a removable chip, say) is
36
+ * not repeated here: nothing chosen reads `placeholder`, anything chosen reads `labels.selectedCount(n)`.
37
+ */
38
+ summary?: 'selection' | 'label';
33
39
  /** For a Label's htmlFor. */
34
40
  id?: string;
35
41
  'aria-label'?: string;
@@ -73,7 +79,9 @@ export interface IMultiSelectProps {
73
79
  */
74
80
  export declare const resolveChosen: (value: readonly string[], options: readonly TMultiSelectOption[], selectedOptions?: readonly TMultiSelectOption[]) => TMultiSelectOption[];
75
81
  /** What the trigger says: the placeholder, the one picked, or a count. */
76
- export declare const summarize: (chosen: readonly TMultiSelectOption[], placeholder: string, labels: IMultiSelectLabels) => string;
82
+ export declare const summarize: (chosen: readonly TMultiSelectOption[], placeholder: string, labels: IMultiSelectLabels, summary?: "selection" | "label") => string;
83
+ /** Every chosen name, for a tooltip on a trigger whose text is cut. With `label` the names are not shown, so it is the text itself. */
84
+ export declare const fullSelection: (chosen: readonly TMultiSelectOption[], placeholder: string, labels: IMultiSelectLabels, summary?: "selection" | "label") => string;
77
85
  /**
78
86
  * A choice of several from a list: a trigger shaped like a Select that says what is picked
79
87
  * (the placeholder, the one picked, or a count), and a popup with a search field and checkbox
@@ -85,4 +93,4 @@ export declare const summarize: (chosen: readonly TMultiSelectOption[], placehol
85
93
  * server: the caller fetches the options for the typed text, and says when they are loading,
86
94
  * failed, or have another page.
87
95
  */
88
- export declare const MultiSelect: ({ placeholder, searchPlaceholder, options, value, onValueChange, id, disabled, className, onSearchChange, searchDelay, selectedOptions, loading, error, onRetry, hasMore, onLoadMore, loadingMore, labels: labelOverrides, ...rest }: IMultiSelectProps) => import('react').JSX.Element;
96
+ export declare const MultiSelect: ({ placeholder, searchPlaceholder, options, value, onValueChange, id, disabled, className, onSearchChange, searchDelay, selectedOptions, loading, error, onRetry, hasMore, onLoadMore, loadingMore, labels: labelOverrides, summary, ...rest }: IMultiSelectProps) => import('react').JSX.Element;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The HTML the rich-text editor emits, and the only HTML RichTextContent renders. An app that
3
+ * sanitises on a server takes its allow-list from here: nothing outside these elements and this
4
+ * attribute ever comes out of the editor, whatever was pasted into it.
5
+ */
6
+ export declare const RICH_TEXT_ELEMENTS: readonly ["p", "br", "hr", "strong", "em", "u", "ul", "ol", "li", "a"];
7
+ /** The attributes each element may carry. Every other element carries none (no class, no style). */
8
+ export declare const RICH_TEXT_ATTRIBUTES: Readonly<Record<string, readonly string[]>>;
9
+ /** A link must be absolute and use one of these. `javascript:`, `data:` and relative links are refused. */
10
+ export declare const RICH_TEXT_LINK_PROTOCOLS: readonly ["http", "https", "mailto"];
11
+ export declare const isAllowedRichTextHref: (href: string) => boolean;
@@ -0,0 +1,2 @@
1
+ export * from './allow-list';
2
+ export * from './rich-text-content';
@@ -0,0 +1,22 @@
1
+ import { HTMLAttributes, ReactNode } from 'react';
2
+ /**
3
+ * How rich text looks, shared by the editor and by RichTextContent so a comment reads the same while it is typed and
4
+ * after it is saved. Descendant selectors rather than classes on the elements, because the HTML that is stored carries
5
+ * no classes.
6
+ */
7
+ export declare const RICH_TEXT_BODY_CLASS = "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";
8
+ export declare const RICH_TEXT_MENTION_CLASS = "rounded-sm bg-primary/10 px-1 py-0.5 font-medium text-primary";
9
+ /** The HTML as React elements, keeping only what the editor can produce. Browser only (it needs a DOM parser). */
10
+ export declare const richTextToNodes: (html: string) => ReactNode[];
11
+ export interface IRichTextContentProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'dangerouslySetInnerHTML'> {
12
+ /** The HTML to show. Only the editor's elements are rendered, whatever else it holds. */
13
+ html: string;
14
+ }
15
+ /**
16
+ * Shows rich text the editor produced (or any HTML), as the same elements the editor emits and nothing else:
17
+ * `p`, `br`, `hr`, `strong`, `em`, `u`, `ul`, `ol`, `li` and `a` with an `href` (http, https or mailto; it opens in a new tab
18
+ * with `rel="noopener noreferrer"`). Everything else is dropped and its text kept. Built as React elements, not injected
19
+ * as markup, so it is safe on HTML that has not been cleaned. A run like `@name@example.test` or `@assignees` is shown
20
+ * as a chip.
21
+ */
22
+ export declare const RichTextContent: ({ html, className, ...props }: IRichTextContentProps) => import('react').JSX.Element;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * RichTextContent shows saved HTML as the editor's own elements and nothing else. It is built as React elements,
3
+ * so these assertions read the markup it renders: a script or a javascript: link that survived would show here.
4
+ *
5
+ * PATH TAKEN: happy-dom parses the input (DOMParser) and renderToStaticMarkup prints the result, which is enough
6
+ * for what this component decides (what stays, what goes, what is added). How it looks is the browser spec's.
7
+ */
8
+ export {};
@@ -0,0 +1,18 @@
1
+ import { Extension } from '@tiptap/core';
2
+ import { SuggestionKeyDownProps, SuggestionProps } from '@tiptap/suggestion';
3
+ import { TMentionToText } from './serialize';
4
+ import { IRichTextMentionItem } from './types';
5
+ /** What the editor needs from the component while it runs. Held in a ref, so the extensions are built once. */
6
+ export interface IEditorHost {
7
+ mentionEnabled: () => boolean;
8
+ maxLength: () => number | undefined;
9
+ toText: () => TMentionToText;
10
+ onSuggestion: (props: SuggestionProps<IRichTextMentionItem, IRichTextMentionItem> | null) => void;
11
+ onSuggestionKey: (props: SuggestionKeyDownProps) => boolean;
12
+ }
13
+ /**
14
+ * The editor's whole schema: paragraph, line break, bold, italic, underline, bullet and numbered lists, link, and the
15
+ * mention chip. Whatever else arrives (a paste, `value`) is not in the schema, so ProseMirror drops the markup and keeps
16
+ * the text.
17
+ */
18
+ export declare const buildExtensions: (host: IEditorHost) => (Extension<any, any> | import('@tiptap/core').Node<any, any> | import('@tiptap/core').Node<import('@tiptap/extension-paragraph').ParagraphOptions, any> | import('@tiptap/core').Node<import('@tiptap/extension-hard-break').HardBreakOptions, any> | import('@tiptap/core').Mark<import('@tiptap/extension-bold').BoldOptions, any> | import('@tiptap/core').Node<import('@tiptap/extension-list').BulletListOptions, any> | import('@tiptap/core').Node<import('@tiptap/extension-list').ListItemOptions, any> | import('@tiptap/core').Node<import('@tiptap/extension-horizontal-rule').HorizontalRuleOptions, any> | import('@tiptap/core').Mark<import('@tiptap/extension-link').LinkOptions, any> | Extension<import('@tiptap/extensions').UndoRedoOptions, any> | import('@tiptap/core').Node<import('@tiptap/extension-mention').MentionOptions<any, import('@tiptap/extension-mention').MentionNodeAttrs>, any>)[];
@@ -0,0 +1,3 @@
1
+ export { RICH_TEXT_ATTRIBUTES, RICH_TEXT_ELEMENTS, RICH_TEXT_LINK_PROTOCOLS } from '../rich-text-content/allow-list';
2
+ export * from './rich-text-editor';
3
+ export * from './types';
@@ -0,0 +1,17 @@
1
+ import { RefObject } from 'react';
2
+ import { IRichTextLabels, IRichTextMention, IRichTextMentionItem } from './types';
3
+ export interface IMentionListProps {
4
+ query: string;
5
+ /** Where the @ was typed. */
6
+ rect: (() => DOMRect | null) | null;
7
+ config: IRichTextMention;
8
+ labels: IRichTextLabels;
9
+ listId: string;
10
+ onPick: (item: IRichTextMentionItem) => void;
11
+ /** The editor keeps focus, so the list is driven by its keys: the editor calls this one. */
12
+ keyHandler: RefObject<((event: KeyboardEvent) => boolean) | null>;
13
+ /** The id of the option the editor should name as `aria-activedescendant`. */
14
+ onActiveChange: (optionId: string | undefined) => void;
15
+ }
16
+ /** The list that opens under the caret when the writer types @. */
17
+ export declare const MentionList: ({ query, rect, config, labels, listId, onPick, keyHandler, onActiveChange }: IMentionListProps) => import('react').JSX.Element;
@@ -0,0 +1,53 @@
1
+ import { ComponentPropsWithoutRef, Ref } from 'react';
2
+ import { IRichTextEditorHandle, IRichTextField, IRichTextLabels, IRichTextMention } from './types';
3
+ export interface IRichTextEditorProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'defaultValue' | 'onChange' | 'id'> {
4
+ /** The HTML, when the parent owns it. Pass back what `onChange` gave. An empty editor is `""`. */
5
+ value?: string;
6
+ /** The HTML to start from when the editor owns its own value. */
7
+ defaultValue?: string;
8
+ /** Called with the HTML after every edit. Only the elements in `RICH_TEXT_ELEMENTS` can appear, and `""` when there is no text. */
9
+ onChange?: (html: string) => void;
10
+ placeholder?: string;
11
+ disabled?: boolean;
12
+ /** Shows the content and keeps it selectable and copyable, with no toolbar. */
13
+ readOnly?: boolean;
14
+ /** Draws the error border and sets `aria-invalid`. The message is the form's to draw: point `aria-describedby` at it. */
15
+ invalid?: boolean;
16
+ /**
17
+ * Lines the box is tall when empty.
18
+ * @default 6
19
+ */
20
+ minRows?: number;
21
+ /**
22
+ * Lines it grows to before it scrolls inside.
23
+ * @default 20
24
+ */
25
+ maxRows?: number;
26
+ /** The most characters of text (a mention counts as the text it is written as). An edit past it is refused. Off by default. */
27
+ maxLength?: number;
28
+ /** Turns @ into a search the app answers. Without it, @ is an ordinary character. */
29
+ mention?: IRichTextMention;
30
+ /** Adds an "Insert a field" menu that writes `{{id}}` at the caret. */
31
+ fields?: IRichTextField[];
32
+ /**
33
+ * Whether the formatting toolbar shows.
34
+ * @default true
35
+ */
36
+ toolbar?: boolean;
37
+ /** Replaces any of the strings the editor shows (the defaults are English). */
38
+ labels?: Partial<IRichTextLabels>;
39
+ /** On the editable element, so a form can name it. */
40
+ id?: string;
41
+ autoFocus?: boolean;
42
+ /** Called with the files when the writer pastes only files (a screenshot). Without it, such a paste does nothing. */
43
+ onPasteFiles?: (files: File[]) => void;
44
+ /** Gives `insertText` and `focus`, for buttons outside the editor. */
45
+ ref?: Ref<IRichTextEditorHandle>;
46
+ }
47
+ /**
48
+ * A small rich-text field: paragraphs, bold, italic, underline, bulleted and numbered lists and links, with optional
49
+ * @mentions the app answers asynchronously. The value is HTML in and out, and only the elements in `RICH_TEXT_ELEMENTS`
50
+ * can come out (no class, no style), whatever is pasted. A mention is a chip while editing and plain text in the HTML.
51
+ * The server should still sanitise: this is a convenience for the writer, not a security boundary.
52
+ */
53
+ export declare const RichTextEditor: ({ value, defaultValue, onChange, placeholder, disabled, readOnly, invalid, minRows, maxRows, maxLength, mention, fields, toolbar, labels, id, autoFocus, onPasteFiles, ref, className, "aria-invalid": ariaInvalid, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, ...props }: IRichTextEditorProps) => import('react').JSX.Element;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * The editor's schema decides what HTML can come out, whatever goes in. These tests drive the real extension set
3
+ * through a headless ProseMirror editor and read what it serialises, so the allow-list the docs promise is the one
4
+ * that is checked. Typing, focus and the mention list need a real browser: e2e/rich-text-editor.spec.ts.
5
+ */
6
+ export {};
@@ -0,0 +1,13 @@
1
+ import { Node as TProseNode } from '@tiptap/pm/model';
2
+ import { IRichTextMention } from './types';
3
+ export type TMentionToText = NonNullable<IRichTextMention['toText']>;
4
+ export declare const defaultMentionToText: TMentionToText;
5
+ /**
6
+ * The document as HTML. Not `editor.getHTML()`: that would write a mention as its chip element, and
7
+ * the HTML must carry the plain text the app chose (`@person@example.test`) and nothing else.
8
+ */
9
+ export declare const serializeDocument: (doc: TProseNode, toText: TMentionToText) => string;
10
+ /** No text and no mention. A document of blank paragraphs, spaces and line breaks is empty too. */
11
+ export declare const isDocumentEmpty: (doc: TProseNode) => boolean;
12
+ /** Characters the HTML text will have: a mention counts as the text it is written as. */
13
+ export declare const countCharacters: (doc: TProseNode, toText: TMentionToText) => number;
@@ -0,0 +1,20 @@
1
+ import { Editor } from '@tiptap/core';
2
+ import { RefObject } from 'react';
3
+ import { IRichTextField, IRichTextLabels } from './types';
4
+ /** A typed address becomes a link: "name@example.test" a mailto, "example.test" an https address. */
5
+ export declare const normalizeHref: (raw: string) => string;
6
+ /** Where the writer's selection was when the link box opened: moving focus into the box must not lose it. */
7
+ export interface ILinkRange {
8
+ from: number;
9
+ to: number;
10
+ }
11
+ export interface IRichTextToolbarProps {
12
+ linkRange: RefObject<ILinkRange | null>;
13
+ editor: Editor;
14
+ labels: IRichTextLabels;
15
+ fields: IRichTextField[] | undefined;
16
+ disabled: boolean;
17
+ linkOpen: boolean;
18
+ onLinkOpenChange: (open: boolean) => void;
19
+ }
20
+ export declare const RichTextToolbar: ({ linkRange, editor, labels, fields, disabled, linkOpen, onLinkOpenChange }: IRichTextToolbarProps) => import('react').JSX.Element;
@@ -0,0 +1,68 @@
1
+ /** One person (or anything else) the app offers when the writer types @. */
2
+ export interface IRichTextMentionItem {
3
+ /** What the HTML carries. By default the value is written as `@${id}`, so an email address works as an id. */
4
+ id: string;
5
+ /** What the chip shows while the text is being edited. */
6
+ label: string;
7
+ /** A second, muted line in the list (a role, an email address). */
8
+ secondary?: string;
9
+ }
10
+ /** A page of results. Return a plain array instead when there is only ever one page. */
11
+ export interface IRichTextMentionPage {
12
+ items: IRichTextMentionItem[];
13
+ /** True when asking for `page + 1` would return more. The list loads it when it is scrolled to the end. */
14
+ hasMore?: boolean;
15
+ }
16
+ export interface IRichTextMentionSearchOptions {
17
+ /** 1-based. */
18
+ page: number;
19
+ /** Aborted when the writer types on or closes the list: pass it to `fetch` so a stale search stops. */
20
+ signal: AbortSignal;
21
+ }
22
+ export type TRichTextMentionSearch = (query: string, options: IRichTextMentionSearchOptions) => Promise<IRichTextMentionItem[] | IRichTextMentionPage>;
23
+ export interface IRichTextMention {
24
+ /** Asked for the first page when the writer types @ and again for every change of the text after it, debounced. */
25
+ search: TRichTextMentionSearch;
26
+ /**
27
+ * How a mention is written into the HTML. The chip exists only while editing; the HTML carries this text
28
+ * and no element. Default: `@${item.id}`.
29
+ */
30
+ toText?: (item: Pick<IRichTextMentionItem, 'id' | 'label'>) => string;
31
+ /** Milliseconds to wait after the last keystroke before searching. Default 250. */
32
+ debounce?: number;
33
+ }
34
+ /** A field of a template (a mail merge token). Inserted as the plain text `{{id}}`. */
35
+ export interface IRichTextField {
36
+ id: string;
37
+ label: string;
38
+ }
39
+ /** What a ref to the editor can do, for a button outside it (a merge tag, say). */
40
+ export interface IRichTextEditorHandle {
41
+ /** Writes plain text at the caret (over the selection), and puts focus back in the editor. */
42
+ insertText: (text: string) => void;
43
+ focus: () => void;
44
+ }
45
+ /** Every string the editor shows, so an app can translate them. */
46
+ export interface IRichTextLabels {
47
+ toolbar: string;
48
+ bold: string;
49
+ italic: string;
50
+ underline: string;
51
+ bulletList: string;
52
+ numberedList: string;
53
+ link: string;
54
+ horizontalRule: string;
55
+ insertField: string;
56
+ linkAddress: string;
57
+ linkApply: string;
58
+ linkRemove: string;
59
+ linkInvalid: string;
60
+ mentionList: string;
61
+ mentionSearching: string;
62
+ mentionEmpty: string;
63
+ mentionError: string;
64
+ mentionLoadingMore: string;
65
+ /** Announced as the list changes. `{count}` is replaced. */
66
+ mentionResults: string;
67
+ }
68
+ export declare const DEFAULT_RICH_TEXT_LABELS: IRichTextLabels;
@@ -2,7 +2,7 @@ import { Popover as PopoverPrimitive } from '@base-ui/react/popover';
2
2
  import type * as React from 'react';
3
3
  export declare const Popover: ({ ...props }: PopoverPrimitive.Root.Props) => React.JSX.Element;
4
4
  export declare const PopoverTrigger: ({ ...props }: PopoverPrimitive.Trigger.Props) => React.JSX.Element;
5
- export declare const PopoverContent: ({ className, align, alignOffset, side, sideOffset, ...props }: PopoverPrimitive.Popup.Props & Pick<PopoverPrimitive.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset">) => React.JSX.Element;
5
+ export declare const PopoverContent: ({ className, align, alignOffset, side, sideOffset, anchor, ...props }: PopoverPrimitive.Popup.Props & Pick<PopoverPrimitive.Positioner.Props, "align" | "alignOffset" | "anchor" | "side" | "sideOffset">) => React.JSX.Element;
6
6
  export declare const PopoverHeader: ({ className, ...props }: React.ComponentProps<"div">) => React.JSX.Element;
7
7
  export declare const PopoverTitle: ({ className, ...props }: PopoverPrimitive.Title.Props) => React.JSX.Element;
8
8
  export declare const PopoverDescription: ({ className, ...props }: PopoverPrimitive.Description.Props) => React.JSX.Element;
@@ -1,13 +1,47 @@
1
1
  import { Progress as ProgressPrimitive } from '@base-ui/react/progress';
2
2
  import { VariantProps } from 'class-variance-authority';
3
- declare const progressIndicatorVariants: (props?: ({
4
- tone?: "default" | "destructive" | "success" | "warning" | "info" | null | undefined;
3
+ /**
4
+ * The tones: a closed set of semantic colours rather than a class string, so a bar cannot carry a
5
+ * colour the theme does not define and dark mode and a re-theme keep working. Each is the theme token
6
+ * the fill uses; the track is a 20% tint of the same token.
7
+ */
8
+ declare const TONE_TOKEN: {
9
+ readonly default: "var(--primary)";
10
+ readonly info: "var(--info)";
11
+ readonly success: "var(--success)";
12
+ readonly warning: "var(--warning)";
13
+ readonly destructive: "var(--destructive)";
14
+ };
15
+ export type TProgressTone = keyof typeof TONE_TOKEN;
16
+ /**
17
+ * Colours an app can set without a class string. --progress-color replaces the fill (any colour, such as an
18
+ * app's own status tokens); --progress-track replaces the track, which does not follow the fill: an app
19
+ * that wants a neutral track sets it to var(--muted). Both are read where the bar is, so they follow the
20
+ * theme and can be set on :root or on any ancestor.
21
+ */
22
+ export declare const progressFill: (tone: TProgressTone) => string;
23
+ export declare const progressTrack: (tone: TProgressTone) => string;
24
+ /**
25
+ * How the fill eases its width. The defaults are the 300ms ease-in-out it always had; an app retunes them
26
+ * with --progress-duration and --progress-ease, or turns the easing off with `animated={false}` when the
27
+ * number it shows is itself animated and the bar is driven from the same clock.
28
+ */
29
+ export declare const PROGRESS_DURATION = "var(--progress-duration, 300ms)";
30
+ export declare const PROGRESS_EASE = "var(--progress-ease, cubic-bezier(0.4, 0, 0.2, 1))";
31
+ declare const progressTrackVariants: (props?: ({
32
+ size?: "default" | "sm" | null | undefined;
5
33
  } & import('class-variance-authority/types').ClassProp) | undefined) => string;
6
- export type TProgressTone = NonNullable<VariantProps<typeof progressIndicatorVariants>['tone']>;
7
34
  export interface IProgressProps extends Omit<ProgressPrimitive.Root.Props, 'value'> {
8
35
  value?: number | null;
9
36
  /** The bar's colour: a share of a total reads as `warning` when nearly used up, `success` when done. */
10
37
  tone?: TProgressTone;
38
+ /** 4px (`sm`) or 8px (default) tall. */
39
+ size?: VariantProps<typeof progressTrackVariants>['size'];
40
+ /**
41
+ * Whether the fill eases when `value` changes. Turn it off when the value already moves smoothly
42
+ * (driven from an animated number's clock), or the bar eases a second time behind it.
43
+ */
44
+ animated?: boolean;
11
45
  }
12
- export declare const Progress: ({ value, tone, className, ...props }: IProgressProps) => import('react').JSX.Element;
46
+ export declare const Progress: ({ value, tone, size, animated, className, ...props }: IProgressProps) => import('react').JSX.Element;
13
47
  export {};
@@ -4,6 +4,7 @@ export * from './components/edyn/date-range-picker';
4
4
  export * from './components/edyn/initials-avatar';
5
5
  export * from './components/edyn/multi-select';
6
6
  export * from './components/edyn/progress-line';
7
+ export * from './components/edyn/rich-text-content';
7
8
  export * from './components/edyn/video-player';
8
9
  export * from './components/ui/accordion';
9
10
  export * from './components/ui/alert';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exsto/ds",
3
- "version": "0.0.1-rc.5",
3
+ "version": "0.0.1-rc.7",
4
4
  "description": "The eDynamix design system: React components and design tokens.",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -27,6 +27,10 @@
27
27
  "types": "./dist/ds/src/index.d.ts",
28
28
  "default": "./dist/index.js"
29
29
  },
30
+ "./rich-text-editor": {
31
+ "types": "./dist/ds/src/rich-text-editor.d.ts",
32
+ "default": "./dist/rich-text-editor.js"
33
+ },
30
34
  "./styles.css": {
31
35
  "types": "./dist/styles.css.d.ts",
32
36
  "default": "./dist/styles.css"
@@ -46,6 +50,22 @@
46
50
  "@shadcn/react": "^0.3.1",
47
51
  "@tabler/icons-react": "^3.44.0",
48
52
  "@tanstack/react-virtual": "^3.13.0",
53
+ "@tiptap/core": "3.32.2",
54
+ "@tiptap/extension-bold": "3.32.2",
55
+ "@tiptap/extension-document": "3.32.2",
56
+ "@tiptap/extension-hard-break": "3.32.2",
57
+ "@tiptap/extension-horizontal-rule": "3.32.2",
58
+ "@tiptap/extension-italic": "3.32.2",
59
+ "@tiptap/extension-link": "3.32.2",
60
+ "@tiptap/extension-list": "3.32.2",
61
+ "@tiptap/extension-mention": "3.32.2",
62
+ "@tiptap/extension-paragraph": "3.32.2",
63
+ "@tiptap/extension-text": "3.32.2",
64
+ "@tiptap/extension-underline": "3.32.2",
65
+ "@tiptap/extensions": "3.32.2",
66
+ "@tiptap/pm": "3.32.2",
67
+ "@tiptap/react": "3.32.2",
68
+ "@tiptap/suggestion": "3.32.2",
49
69
  "class-variance-authority": "^0.7.1",
50
70
  "clsx": "^2.1.1",
51
71
  "cmdk": "^1.1.1",