@mittwald/flow-react-components 1.5.0-next.46 → 1.5.0-next.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/component-index.json +1 -1
- package/dist/assets/doc-properties.json +1 -1
- package/dist/css/all-layered.css +1 -1
- package/dist/css/all.css +1 -1
- package/dist/js/packages/components/src/components/Calendar/Calendar.mjs +7 -4
- package/dist/js/packages/components/src/components/Calendar/Calendar.mjs.map +1 -1
- package/dist/js/packages/components/src/components/Calendar/Calendar.module.mjs +6 -2
- package/dist/js/packages/components/src/components/Calendar/Calendar.module.mjs.map +1 -1
- package/dist/js/packages/components/src/components/Calendar/components/RangeCalendar/RangeCalendar.mjs +5 -2
- package/dist/js/packages/components/src/components/Calendar/components/RangeCalendar/RangeCalendar.mjs.map +1 -1
- package/dist/js/packages/components/src/components/CartesianChart/CartesianChart.mjs +11 -0
- package/dist/js/packages/components/src/components/CartesianChart/CartesianChart.mjs.map +1 -1
- package/dist/js/packages/components/src/components/CartesianChart/CartesianChart.module.mjs +6 -2
- package/dist/js/packages/components/src/components/CartesianChart/CartesianChart.module.mjs.map +1 -1
- package/dist/js/packages/components/src/components/CodeBlock/CodeBlock.mjs +8 -4
- package/dist/js/packages/components/src/components/CodeBlock/CodeBlock.mjs.map +1 -1
- package/dist/js/packages/components/src/components/CodeBlock/CodeBlock.module.mjs +6 -2
- package/dist/js/packages/components/src/components/CodeBlock/CodeBlock.module.mjs.map +1 -1
- package/dist/js/packages/components/src/components/CodeEditor/CodeEditor.mjs +42 -30
- package/dist/js/packages/components/src/components/CodeEditor/CodeEditor.mjs.map +1 -1
- package/dist/js/packages/components/src/components/CodeEditor/CodeEditor.module.mjs +8 -2
- package/dist/js/packages/components/src/components/CodeEditor/CodeEditor.module.mjs.map +1 -1
- package/dist/js/packages/components/src/components/DonutChart/DonutChart.mjs +30 -16
- package/dist/js/packages/components/src/components/DonutChart/DonutChart.mjs.map +1 -1
- package/dist/js/packages/components/src/components/DonutChart/DonutChart.module.mjs +6 -2
- package/dist/js/packages/components/src/components/DonutChart/DonutChart.module.mjs.map +1 -1
- package/dist/js/packages/components/src/components/DonutChart/components/Donut.mjs +5 -2
- package/dist/js/packages/components/src/components/DonutChart/components/Donut.mjs.map +1 -1
- package/dist/js/packages/components/src/components/FileDropZone/FileDropZone.mjs +6 -3
- package/dist/js/packages/components/src/components/FileDropZone/FileDropZone.mjs.map +1 -1
- package/dist/js/packages/components/src/components/FileDropZone/FileDropZone.module.mjs +6 -2
- package/dist/js/packages/components/src/components/FileDropZone/FileDropZone.module.mjs.map +1 -1
- package/dist/js/packages/components/src/components/ImageCropper/ImageCropper.mjs +27 -22
- package/dist/js/packages/components/src/components/ImageCropper/ImageCropper.mjs.map +1 -1
- package/dist/js/packages/components/src/components/ImageCropper/ImageCropper.module.mjs +6 -2
- package/dist/js/packages/components/src/components/ImageCropper/ImageCropper.module.mjs.map +1 -1
- package/dist/js/packages/components/src/components/Kbd/Kbd.mjs +4 -1
- package/dist/js/packages/components/src/components/Kbd/Kbd.mjs.map +1 -1
- package/dist/js/packages/components/src/components/Kbd/Kbd.module.mjs +6 -2
- package/dist/js/packages/components/src/components/Kbd/Kbd.module.mjs.map +1 -1
- package/dist/js/packages/components/src/components/Markdown/Markdown.mjs +19 -3
- package/dist/js/packages/components/src/components/Markdown/Markdown.mjs.map +1 -1
- package/dist/js/packages/components/src/components/Markdown/Markdown.module.mjs +6 -2
- package/dist/js/packages/components/src/components/Markdown/Markdown.module.mjs.map +1 -1
- package/dist/js/packages/components/src/components/Markdown/components/SkeletonBlocks.mjs +82 -0
- package/dist/js/packages/components/src/components/Markdown/components/SkeletonBlocks.mjs.map +1 -0
- package/dist/js/packages/components/src/components/MarkdownEditor/MarkdownEditor.mjs +9 -6
- package/dist/js/packages/components/src/components/MarkdownEditor/MarkdownEditor.mjs.map +1 -1
- package/dist/js/packages/components/src/components/MarkdownEditor/MarkdownEditor.module.mjs +8 -2
- package/dist/js/packages/components/src/components/MarkdownEditor/MarkdownEditor.module.mjs.map +1 -1
- package/dist/js/packages/components/src/components/Modal/Modal.module.mjs +2 -0
- package/dist/js/packages/components/src/components/Modal/Modal.module.mjs.map +1 -1
- package/dist/js/packages/components/src/components/SkeletonMode/components/SkeletonTextContent/SkeletonTextContent.module.mjs.map +1 -1
- package/dist/js/packages/components/src/components/Table/components/TableCell/TableCell.mjs +2 -1
- package/dist/js/packages/components/src/components/Table/components/TableCell/TableCell.mjs.map +1 -1
- package/dist/js/packages/components/src/components/Table/components/TableColumn/TableColumn.mjs +2 -1
- package/dist/js/packages/components/src/components/Table/components/TableColumn/TableColumn.mjs.map +1 -1
- package/dist/js/packages/components/src/integrations/react-hook-form/components/Field/Field.mjs +1 -2
- package/dist/js/packages/components/src/integrations/react-hook-form/components/Field/Field.mjs.map +1 -1
- package/dist/types/components/DonutChart/components/Donut.d.ts +2 -0
- package/dist/types/components/Markdown/components/SkeletonBlocks.d.ts +15 -0
- package/package.json +9 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Markdown.mjs","names":["styles"],"sources":["../../../../../../../src/components/Markdown/Markdown.tsx"],"sourcesContent":["import { CodeBlock } from \"@/components/CodeBlock\";\nimport { Heading } from \"@/components/Heading\";\nimport { InlineCode } from \"@/components/InlineCode\";\nimport { Link } from \"@/components/Link\";\nimport { Separator } from \"@/components/Separator\";\nimport { Text } from \"@/components/Text\";\nimport type { CSSProperties, FC, ReactNode, Ref } from \"react\";\nimport { Children, isValidElement } from \"react\";\nimport type { Components, Options } from \"react-markdown\";\nimport ReactMarkdown from \"react-markdown\";\nimport styles from \"./Markdown.module.scss\";\nimport { extractTextFromFirstChild } from \"@/lib/react/remote\";\nimport type { AlphaColor, PropsWithClassName } from \"@/lib/types/props\";\nimport clsx from \"clsx\";\nimport remarkGfm from \"remark-gfm\";\nimport { getHeadingLevelWithOffset } from \"@/components/Markdown/lib/getHeadingLevelWithOffset\";\nimport type { CodeEditorLanguage } from \"@/components/CodeEditor/languages\";\n\nexport interface MarkdownProps\n extends PropsWithClassName, Omit<Options, \"components\"> {\n /** The color schema of the markdown component. @default \"default\" */\n color?: \"default\" | AlphaColor;\n /** Shifts all heading levels by the given offset. @default 0 */\n headingOffset?: number;\n /** Allows overriding markdown element renderers from outside. */\n components?: Components;\n /** @internal */\n style?: CSSProperties;\n /** A ref to the elements root. */\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * @flr-generate all\n * @flr-ignore-props components\n */\nexport const Markdown: FC<MarkdownProps> = (props) => {\n const {\n children,\n color = \"default\",\n className,\n headingOffset = 0,\n components: customComponents,\n ref,\n allowElement,\n allowedElements,\n disallowedElements,\n rehypePlugins,\n remarkPlugins,\n remarkRehypeOptions,\n skipHtml,\n unwrapDisallowed,\n urlTransform,\n ...rest\n } = props;\n\n const defaultComponents: Components = {\n a: (props) => (\n <Link target=\"_blank\" color={color} href={props.href}>\n {props.children}\n </Link>\n ),\n p: (props) => (\n <Text elementType=\"p\" color={color}>\n {props.children}\n </Text>\n ),\n code: (props) => <InlineCode color={color}>{props.children}</InlineCode>,\n h1: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(1, headingOffset)}\n color={color}\n >\n {props.children}\n </Heading>\n ),\n h2: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(2, headingOffset)}\n color={color}\n >\n {props.children}\n </Heading>\n ),\n h3: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(3, headingOffset)}\n color={color}\n >\n {props.children}\n </Heading>\n ),\n h4: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(4, headingOffset)}\n color={color}\n >\n {props.children}\n </Heading>\n ),\n h5: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(5, headingOffset)}\n color={color}\n >\n {props.children}\n </Heading>\n ),\n h6: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(6, headingOffset)}\n color={color}\n >\n {props.children}\n </Heading>\n ),\n hr: () => <Separator />,\n pre: (props) => {\n const preElementContent = Children.toArray(props.children)[0];\n\n return (\n <CodeBlock\n copyable={false}\n language={\n isValidElement<{ className?: string }>(preElementContent) &&\n preElementContent.props.className\n ? (preElementContent.props.className.replace(\n \"language-\",\n \"\",\n ) as CodeEditorLanguage)\n : undefined\n }\n code={String(\n isValidElement<{ children: string }>(preElementContent)\n ? preElementContent.props.children\n : preElementContent,\n ).trim()}\n />\n );\n },\n ul: (props) => (\n <
|
|
1
|
+
{"version":3,"file":"Markdown.mjs","names":["styles"],"sources":["../../../../../../../src/components/Markdown/Markdown.tsx"],"sourcesContent":["import { CodeBlock } from \"@/components/CodeBlock\";\nimport { Heading } from \"@/components/Heading\";\nimport { InlineCode } from \"@/components/InlineCode\";\nimport { Link } from \"@/components/Link\";\nimport { Separator } from \"@/components/Separator\";\nimport { Text } from \"@/components/Text\";\nimport type { CSSProperties, FC, ReactNode, Ref } from \"react\";\nimport { Children, isValidElement } from \"react\";\nimport type { Components, Options } from \"react-markdown\";\nimport ReactMarkdown from \"react-markdown\";\nimport styles from \"./Markdown.module.scss\";\nimport { extractTextFromFirstChild } from \"@/lib/react/remote\";\nimport type { AlphaColor, PropsWithClassName } from \"@/lib/types/props\";\nimport clsx from \"clsx\";\nimport remarkGfm from \"remark-gfm\";\nimport { getHeadingLevelWithOffset } from \"@/components/Markdown/lib/getHeadingLevelWithOffset\";\nimport type { CodeEditorLanguage } from \"@/components/CodeEditor/languages\";\nimport {\n SkeletonBlockText,\n SkeletonInlineContent,\n} from \"@/components/Markdown/components/SkeletonBlocks\";\nimport { useSkeletonMode } from \"@/components/SkeletonMode/skeletonModeContext\";\n\nexport interface MarkdownProps\n extends PropsWithClassName, Omit<Options, \"components\"> {\n /** The color schema of the markdown component. @default \"default\" */\n color?: \"default\" | AlphaColor;\n /** Shifts all heading levels by the given offset. @default 0 */\n headingOffset?: number;\n /** Allows overriding markdown element renderers from outside. */\n components?: Components;\n /** @internal */\n style?: CSSProperties;\n /** A ref to the elements root. */\n ref?: Ref<HTMLDivElement>;\n}\n\n/**\n * @flr-generate all\n * @flr-ignore-props components\n */\nexport const Markdown: FC<MarkdownProps> = (props) => {\n const {\n children,\n color = \"default\",\n className,\n headingOffset = 0,\n components: customComponents,\n ref,\n allowElement,\n allowedElements,\n disallowedElements,\n rehypePlugins,\n remarkPlugins,\n remarkRehypeOptions,\n skipHtml,\n unwrapDisallowed,\n urlTransform,\n ...rest\n } = props;\n\n const isSkeleton = useSkeletonMode();\n\n const defaultComponents: Components = {\n a: (props) => (\n <Link target=\"_blank\" color={color} href={props.href}>\n {props.children}\n </Link>\n ),\n p: (props) => (\n <Text elementType=\"p\" color={color}>\n {props.children}\n </Text>\n ),\n code: (props) => <InlineCode color={color}>{props.children}</InlineCode>,\n h1: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(1, headingOffset)}\n color={color}\n >\n {props.children}\n </Heading>\n ),\n h2: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(2, headingOffset)}\n color={color}\n >\n {props.children}\n </Heading>\n ),\n h3: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(3, headingOffset)}\n color={color}\n >\n {props.children}\n </Heading>\n ),\n h4: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(4, headingOffset)}\n color={color}\n >\n {props.children}\n </Heading>\n ),\n h5: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(5, headingOffset)}\n color={color}\n >\n {props.children}\n </Heading>\n ),\n h6: (props) => (\n <Heading\n level={getHeadingLevelWithOffset(6, headingOffset)}\n color={color}\n >\n {props.children}\n </Heading>\n ),\n hr: () => <Separator />,\n pre: (props) => {\n const preElementContent = Children.toArray(props.children)[0];\n\n return (\n <CodeBlock\n copyable={false}\n language={\n isValidElement<{ className?: string }>(preElementContent) &&\n preElementContent.props.className\n ? (preElementContent.props.className.replace(\n \"language-\",\n \"\",\n ) as CodeEditorLanguage)\n : undefined\n }\n code={String(\n isValidElement<{ children: string }>(preElementContent)\n ? preElementContent.props.children\n : preElementContent,\n ).trim()}\n />\n );\n },\n ul: (props) => (\n <SkeletonBlockText color={color}>\n <ul>{props.children as ReactNode}</ul>\n </SkeletonBlockText>\n ),\n ol: (props) => (\n <SkeletonBlockText color={color}>\n <ol>{props.children as ReactNode}</ol>\n </SkeletonBlockText>\n ),\n li: ({ node: ignoredNode, children, ...props }) => (\n <li {...props}>\n <SkeletonInlineContent>{children}</SkeletonInlineContent>\n </li>\n ),\n th: ({ node: ignoredNode, children, ...props }) => (\n <th {...props}>\n <SkeletonInlineContent>{children}</SkeletonInlineContent>\n </th>\n ),\n td: ({ node: ignoredNode, children, ...props }) => (\n <td {...props}>\n <SkeletonInlineContent>{children}</SkeletonInlineContent>\n </td>\n ),\n /* A text bar resets the mode for its content, so the image reads it\n from here. A skeleton issues no request. */\n img: ({ node: ignoredNode, ...props }) =>\n isSkeleton ? null : <img {...props} />,\n blockquote: (props) => (\n <SkeletonBlockText color={color}>\n <blockquote>{props.children}</blockquote>\n </SkeletonBlockText>\n ),\n };\n\n const textContent = extractTextFromFirstChild(children);\n const mergedComponents: Components = {\n ...defaultComponents,\n ...customComponents,\n };\n\n return (\n <div className={clsx(styles.markdown, className)} {...rest} ref={ref}>\n <ReactMarkdown\n allowElement={allowElement}\n allowedElements={allowedElements}\n disallowedElements={disallowedElements}\n rehypePlugins={rehypePlugins}\n remarkPlugins={remarkPlugins ?? [remarkGfm]}\n remarkRehypeOptions={remarkRehypeOptions}\n skipHtml={skipHtml}\n unwrapDisallowed={unwrapDisallowed}\n urlTransform={urlTransform}\n components={mergedComponents}\n >\n {textContent}\n </ReactMarkdown>\n </div>\n );\n};\n\nexport default Markdown;\n"],"mappings":"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"}
|
|
@@ -2,8 +2,12 @@
|
|
|
2
2
|
/* */
|
|
3
3
|
//#region src/components/Markdown/Markdown.module.scss
|
|
4
4
|
var markdown = "flow--markdown";
|
|
5
|
-
var
|
|
5
|
+
var skeletonBlock = "flow--markdown--skeleton-block";
|
|
6
|
+
var Markdown_module_default = {
|
|
7
|
+
markdown,
|
|
8
|
+
skeletonBlock
|
|
9
|
+
};
|
|
6
10
|
//#endregion
|
|
7
|
-
export { Markdown_module_default as default, markdown };
|
|
11
|
+
export { Markdown_module_default as default, markdown, skeletonBlock };
|
|
8
12
|
|
|
9
13
|
//# sourceMappingURL=Markdown.module.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Markdown.module.mjs","names":[],"sources":["../../../../../../../src/components/Markdown/Markdown.module.scss"],"sourcesContent":[".markdown {\n display: flex;\n flex-direction: column;\n row-gap: var(--markdown--spacing);\n min-width: 0;\n\n /* Everything below styles react-markdown's output. Consumers can replace any\n renderer through the `components` prop, so these rules have to match the\n element, not a Flow class that a replacement would not carry. */\n // stylelint-disable-next-line selector-max-type -- react-markdown output\n p {\n white-space: break-spaces;\n }\n\n // remark-gfm renders the table markup itself — Markdown overrides no table\n // renderer, so none of these elements carries a class.\n // stylelint-disable selector-max-type -- react-markdown table output\n table {\n border-radius: var(--table--corner-radius);\n overflow: hidden;\n border-width: var(--table--border-width);\n border-style: var(--table--border-style);\n border-color: var(--table--border-color);\n border-spacing: 0;\n background-color: var(--table--background-color);\n\n thead {\n font-weight: var(--table--header-font-weight);\n }\n\n th,\n td {\n padding-inline: var(--table--padding-x);\n padding-block: var(--table--padding-y);\n text-align: start;\n border-style: var(--table--border-style);\n border-color: var(--table--border-color);\n border-width: 0;\n }\n\n th {\n border-block-end-width: var(--table--header-border-width);\n }\n\n tbody tr {\n &:nth-of-type(odd) td {\n background-color: var(--table--background-color-accent);\n }\n\n &:not(:last-child) td {\n border-block-end-width: var(--table--border-width);\n }\n }\n }\n // stylelint-enable selector-max-type\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"Markdown.module.mjs","names":[],"sources":["../../../../../../../src/components/Markdown/Markdown.module.scss"],"sourcesContent":["@use \"@/styles/mixins/skeleton\";\n\n.markdown {\n display: flex;\n flex-direction: column;\n row-gap: var(--markdown--spacing);\n min-width: 0;\n\n /* Everything below styles react-markdown's output. Consumers can replace any\n renderer through the `components` prop, so these rules have to match the\n element, not a Flow class that a replacement would not carry. */\n // stylelint-disable-next-line selector-max-type -- react-markdown output\n p {\n white-space: break-spaces;\n }\n\n // remark-gfm renders the table markup itself — Markdown overrides no table\n // renderer, so none of these elements carries a class.\n // stylelint-disable selector-max-type -- react-markdown table output\n table {\n border-radius: var(--table--corner-radius);\n overflow: hidden;\n border-width: var(--table--border-width);\n border-style: var(--table--border-style);\n border-color: var(--table--border-color);\n border-spacing: 0;\n background-color: var(--table--background-color);\n\n thead {\n font-weight: var(--table--header-font-weight);\n }\n\n th,\n td {\n padding-inline: var(--table--padding-x);\n padding-block: var(--table--padding-y);\n text-align: start;\n border-style: var(--table--border-style);\n border-color: var(--table--border-color);\n border-width: 0;\n }\n\n th {\n border-block-end-width: var(--table--header-border-width);\n }\n\n tbody tr {\n &:nth-of-type(odd) td {\n background-color: var(--table--background-color-accent);\n }\n\n &:not(:last-child) td {\n border-block-end-width: var(--table--border-width);\n }\n }\n }\n // stylelint-enable selector-max-type\n}\n\n/* SkeletonMode: a list or quote whose items became bars. The bullets take the\n bar color, so no real glyph shows. */\n.skeletonBlock ::marker {\n color: skeleton.$background-color;\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
/* */
|
|
3
|
+
import { SkeletonModeReset, skeletonModeContext, useSkeletonMode } from "../../SkeletonMode/skeletonModeContext.mjs";
|
|
4
|
+
import { SkeletonTextContent } from "../../SkeletonMode/components/SkeletonTextContent/SkeletonTextContent.mjs";
|
|
5
|
+
import { Text } from "../../Text/Text.mjs";
|
|
6
|
+
import Markdown_module_default from "../Markdown.module.mjs";
|
|
7
|
+
import clsx from "clsx";
|
|
8
|
+
import { Children, isValidElement, useContext } from "react";
|
|
9
|
+
import { jsx } from "react/jsx-runtime";
|
|
10
|
+
//#region src/components/Markdown/components/SkeletonBlocks.tsx
|
|
11
|
+
/**
|
|
12
|
+
* A text bar is an inline element and cannot wrap blocks. Markdown puts lists
|
|
13
|
+
* and quotes into a `Text`, so in `SkeletonMode` this `Text` renders as real
|
|
14
|
+
* text, and the blocks inside follow the skeleton rules on their own.
|
|
15
|
+
*/
|
|
16
|
+
var SkeletonBlockText = (props) => {
|
|
17
|
+
const { children, className, ...rest } = props;
|
|
18
|
+
const outerState = useContext(skeletonModeContext);
|
|
19
|
+
return /* @__PURE__ */ jsx(SkeletonModeReset, { children: /* @__PURE__ */ jsx(Text, {
|
|
20
|
+
...rest,
|
|
21
|
+
className: clsx(className, outerState.isEnabled && Markdown_module_default.skeletonBlock),
|
|
22
|
+
children: /* @__PURE__ */ jsx(skeletonModeContext.Provider, {
|
|
23
|
+
value: outerState,
|
|
24
|
+
children
|
|
25
|
+
})
|
|
26
|
+
}) });
|
|
27
|
+
};
|
|
28
|
+
var blockTagNames = /* @__PURE__ */ new Set([
|
|
29
|
+
"blockquote",
|
|
30
|
+
"div",
|
|
31
|
+
"h1",
|
|
32
|
+
"h2",
|
|
33
|
+
"h3",
|
|
34
|
+
"h4",
|
|
35
|
+
"h5",
|
|
36
|
+
"h6",
|
|
37
|
+
"hr",
|
|
38
|
+
"ol",
|
|
39
|
+
"p",
|
|
40
|
+
"pre",
|
|
41
|
+
"table",
|
|
42
|
+
"ul"
|
|
43
|
+
]);
|
|
44
|
+
/** Whether a rendered markdown element is a block — a nested list, a paragraph. */
|
|
45
|
+
var isBlock = (child) => {
|
|
46
|
+
if (!isValidElement(child)) return false;
|
|
47
|
+
const tagName = typeof child.type === "string" ? child.type : child.props.node?.tagName;
|
|
48
|
+
return tagName !== void 0 && blockTagNames.has(tagName);
|
|
49
|
+
};
|
|
50
|
+
var isBlank = (child) => typeof child === "string" && child.trim() === "";
|
|
51
|
+
/**
|
|
52
|
+
* The content of a list item or a table cell: each run of inline content
|
|
53
|
+
* becomes one text bar, blocks inside — a nested list, the paragraphs of a
|
|
54
|
+
* loose list — keep their own skeleton rules. Outside an enabled `SkeletonMode`
|
|
55
|
+
* it renders its children unchanged.
|
|
56
|
+
*/
|
|
57
|
+
var SkeletonInlineContent = (props) => {
|
|
58
|
+
const { children } = props;
|
|
59
|
+
if (!useSkeletonMode()) return children;
|
|
60
|
+
const content = [];
|
|
61
|
+
let run = [];
|
|
62
|
+
const endRun = () => {
|
|
63
|
+
const start = run.findIndex((child) => !isBlank(child));
|
|
64
|
+
const end = run.findLastIndex((child) => !isBlank(child)) + 1;
|
|
65
|
+
if (start === -1) content.push(...run);
|
|
66
|
+
else content.push(...run.slice(0, start), /* @__PURE__ */ jsx(SkeletonTextContent, {
|
|
67
|
+
defaultWidth: "8em",
|
|
68
|
+
children: run.slice(start, end)
|
|
69
|
+
}, content.length), ...run.slice(end));
|
|
70
|
+
run = [];
|
|
71
|
+
};
|
|
72
|
+
for (const child of Children.toArray(children)) if (isBlock(child)) {
|
|
73
|
+
endRun();
|
|
74
|
+
content.push(child);
|
|
75
|
+
} else run.push(child);
|
|
76
|
+
endRun();
|
|
77
|
+
return content;
|
|
78
|
+
};
|
|
79
|
+
//#endregion
|
|
80
|
+
export { SkeletonBlockText, SkeletonInlineContent };
|
|
81
|
+
|
|
82
|
+
//# sourceMappingURL=SkeletonBlocks.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SkeletonBlocks.mjs","names":["styles"],"sources":["../../../../../../../../src/components/Markdown/components/SkeletonBlocks.tsx"],"sourcesContent":["import {\n Children,\n type FC,\n isValidElement,\n type PropsWithChildren,\n type ReactNode,\n useContext,\n} from \"react\";\nimport clsx from \"clsx\";\nimport { Text, type TextProps } from \"@/components/Text\";\nimport { SkeletonTextContent } from \"@/components/SkeletonMode/components/SkeletonTextContent\";\nimport {\n SkeletonModeReset,\n skeletonModeContext,\n useSkeletonMode,\n} from \"@/components/SkeletonMode/skeletonModeContext\";\nimport styles from \"../Markdown.module.scss\";\n\n/**\n * A text bar is an inline element and cannot wrap blocks. Markdown puts lists\n * and quotes into a `Text`, so in `SkeletonMode` this `Text` renders as real\n * text, and the blocks inside follow the skeleton rules on their own.\n */\nexport const SkeletonBlockText: FC<TextProps> = (props) => {\n const { children, className, ...rest } = props;\n\n const outerState = useContext(skeletonModeContext);\n\n return (\n <SkeletonModeReset>\n <Text\n {...rest}\n className={clsx(\n className,\n outerState.isEnabled && styles.skeletonBlock,\n )}\n >\n <skeletonModeContext.Provider value={outerState}>\n {children}\n </skeletonModeContext.Provider>\n </Text>\n </SkeletonModeReset>\n );\n};\n\nconst blockTagNames = new Set([\n \"blockquote\",\n \"div\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"hr\",\n \"ol\",\n \"p\",\n \"pre\",\n \"table\",\n \"ul\",\n]);\n\n/** Whether a rendered markdown element is a block — a nested list, a paragraph. */\nconst isBlock = (child: ReactNode): boolean => {\n if (!isValidElement<{ node?: { tagName?: string } }>(child)) {\n return false;\n }\n\n const tagName =\n typeof child.type === \"string\" ? child.type : child.props.node?.tagName;\n\n return tagName !== undefined && blockTagNames.has(tagName);\n};\n\nconst isBlank = (child: ReactNode) =>\n typeof child === \"string\" && child.trim() === \"\";\n\n/**\n * The content of a list item or a table cell: each run of inline content\n * becomes one text bar, blocks inside — a nested list, the paragraphs of a\n * loose list — keep their own skeleton rules. Outside an enabled `SkeletonMode`\n * it renders its children unchanged.\n */\nexport const SkeletonInlineContent: FC<PropsWithChildren> = (props) => {\n const { children } = props;\n\n const isSkeleton = useSkeletonMode();\n\n if (!isSkeleton) {\n return children;\n }\n\n const content: ReactNode[] = [];\n let run: ReactNode[] = [];\n\n /* The line breaks around a nested list stay outside the bar. */\n const endRun = () => {\n const start = run.findIndex((child) => !isBlank(child));\n const end = run.findLastIndex((child) => !isBlank(child)) + 1;\n\n if (start === -1) {\n content.push(...run);\n } else {\n content.push(\n ...run.slice(0, start),\n <SkeletonTextContent key={content.length} defaultWidth=\"8em\">\n {run.slice(start, end)}\n </SkeletonTextContent>,\n ...run.slice(end),\n );\n }\n\n run = [];\n };\n\n for (const child of Children.toArray(children)) {\n if (isBlock(child)) {\n endRun();\n content.push(child);\n } else {\n run.push(child);\n }\n }\n\n endRun();\n\n return content;\n};\n"],"mappings":";;;;;;;;;;;;;;;AAuBA,IAAa,qBAAoC,UAAU;CACzD,MAAM,EAAE,UAAU,WAAW,GAAG,SAAS;CAEzC,MAAM,aAAa,WAAW,mBAAmB;CAEjD,OACE,oBAAC,mBAAD,EAAA,UACE,oBAAC,MAAD;EACE,GAAI;EACJ,WAAW,KACT,WACA,WAAW,aAAaA,wBAAO,aACjC;EAEA,UAAA,oBAAC,oBAAoB,UAArB;GAA8B,OAAO;GAClC;EAC2B,CAAA;CAC1B,CAAA,EACW,CAAA;AAEvB;AAEA,IAAM,gCAAgB,IAAI,IAAI;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;AAGD,IAAM,WAAW,UAA8B;CAC7C,IAAI,CAAC,eAAgD,KAAK,GACxD,OAAO;CAGT,MAAM,UACJ,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO,MAAM,MAAM,MAAM;CAElE,OAAO,YAAY,KAAA,KAAa,cAAc,IAAI,OAAO;AAC3D;AAEA,IAAM,WAAW,UACf,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM;;;;;;;AAQhD,IAAa,yBAAgD,UAAU;CACrE,MAAM,EAAE,aAAa;CAIrB,IAAI,CAFe,gBAEd,GACH,OAAO;CAGT,MAAM,UAAuB,CAAC;CAC9B,IAAI,MAAmB,CAAC;CAGxB,MAAM,eAAe;EACnB,MAAM,QAAQ,IAAI,WAAW,UAAU,CAAC,QAAQ,KAAK,CAAC;EACtD,MAAM,MAAM,IAAI,eAAe,UAAU,CAAC,QAAQ,KAAK,CAAC,IAAI;EAE5D,IAAI,UAAU,IACZ,QAAQ,KAAK,GAAG,GAAG;OAEnB,QAAQ,KACN,GAAG,IAAI,MAAM,GAAG,KAAK,GACrB,oBAAC,qBAAD;GAA0C,cAAa;GACpD,UAAA,IAAI,MAAM,OAAO,GAAG;EACF,GAFK,QAAQ,MAEb,GACrB,GAAG,IAAI,MAAM,GAAG,CAClB;EAGF,MAAM,CAAC;CACT;CAEA,KAAK,MAAM,SAAS,SAAS,QAAQ,QAAQ,GAC3C,IAAI,QAAQ,KAAK,GAAG;EAClB,OAAO;EACP,QAAQ,KAAK,KAAK;CACpB,OACE,IAAI,KAAK,KAAK;CAIlB,OAAO;CAEP,OAAO;AACT"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { PropsContextProvider } from "../../lib/propsContext/components/PropsContextProvider.mjs";
|
|
4
4
|
import { flowComponent } from "../../lib/componentFactory/flowComponent.mjs";
|
|
5
5
|
import overlayTriggersTunneledTo from "../../lib/propsContext/overlayTriggerTunnel.mjs";
|
|
6
|
+
import { SkeletonModeReset, useSkeletonMode } from "../SkeletonMode/skeletonModeContext.mjs";
|
|
6
7
|
import { useControlledHostValueProps } from "../../lib/remote/useControlledHostValueProps.mjs";
|
|
7
8
|
import { Markdown } from "../Markdown/Markdown.mjs";
|
|
8
9
|
import MarkdownEditor_module_default from "./MarkdownEditor.module.mjs";
|
|
@@ -34,7 +35,8 @@ var MarkdownEditor = flowComponent("MarkdownEditor", (props) => {
|
|
|
34
35
|
onChange,
|
|
35
36
|
textAreaRef: inputRef
|
|
36
37
|
});
|
|
37
|
-
const
|
|
38
|
+
const isSkeleton = useSkeletonMode();
|
|
39
|
+
const rootClassName = clsx(MarkdownEditor_module_default.markdownEditor, MarkdownEditor_module_default[`mode-${mode}`], isDropTarget && MarkdownEditor_module_default.dropTarget, isSkeleton && MarkdownEditor_module_default.skeleton, className);
|
|
38
40
|
const toolbarActionsPropsContext = {
|
|
39
41
|
...overlayTriggersTunneledTo(toolbarActionsTunnel),
|
|
40
42
|
Button: {
|
|
@@ -71,10 +73,11 @@ var MarkdownEditor = flowComponent("MarkdownEditor", (props) => {
|
|
|
71
73
|
});
|
|
72
74
|
onChange(newValue);
|
|
73
75
|
};
|
|
74
|
-
return /* @__PURE__ */
|
|
76
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
75
77
|
...dropProps,
|
|
76
78
|
className: rootClassName,
|
|
77
|
-
|
|
79
|
+
inert: isSkeleton || void 0,
|
|
80
|
+
children: [/* @__PURE__ */ jsx(TextArea, {
|
|
78
81
|
...rest,
|
|
79
82
|
"aria-hidden": mode === "preview",
|
|
80
83
|
isReadOnly: isReadOnly || mode === "preview",
|
|
@@ -95,7 +98,7 @@ var MarkdownEditor = flowComponent("MarkdownEditor", (props) => {
|
|
|
95
98
|
className: MarkdownEditor_module_default.markdown,
|
|
96
99
|
children: value
|
|
97
100
|
}),
|
|
98
|
-
/* @__PURE__ */ jsx(Toolbar, {
|
|
101
|
+
/* @__PURE__ */ jsx(SkeletonModeReset, { children: /* @__PURE__ */ jsx(Toolbar, {
|
|
99
102
|
currentMode: mode,
|
|
100
103
|
isDisabled,
|
|
101
104
|
onModeChange: setMode,
|
|
@@ -103,10 +106,10 @@ var MarkdownEditor = flowComponent("MarkdownEditor", (props) => {
|
|
|
103
106
|
accept,
|
|
104
107
|
isReadOnly,
|
|
105
108
|
onFilesSelected: uploadFiles
|
|
106
|
-
})
|
|
109
|
+
}) })
|
|
107
110
|
]
|
|
108
111
|
})
|
|
109
|
-
})
|
|
112
|
+
}), isSkeleton && /* @__PURE__ */ jsx("div", { className: MarkdownEditor_module_default.skeletonSurface })]
|
|
110
113
|
});
|
|
111
114
|
});
|
|
112
115
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownEditor.mjs","names":["DefaultMarkdown","styles"],"sources":["../../../../../../../src/components/MarkdownEditor/MarkdownEditor.tsx"],"sourcesContent":["import { type ComponentType, type KeyboardEventHandler, useState } from \"react\";\nimport styles from \"./MarkdownEditor.module.scss\";\nimport {\n Markdown as DefaultMarkdown,\n type MarkdownProps,\n} from \"@/components/Markdown\";\nimport { TextArea, type TextAreaProps } from \"@/components/TextArea\";\nimport { Toolbar } from \"@/components/MarkdownEditor/components/Toolbar\";\nimport clsx from \"clsx\";\nimport { flowComponent } from \"@/lib/componentFactory/flowComponent\";\nimport { useObjectRef } from \"@react-aria/utils\";\nimport {\n modifyValueByMarkdownSyntax,\n scrollToCursor,\n} from \"@/components/MarkdownEditor/lib/modifyValueByMarkdownSyntax\";\nimport {\n type InsertType,\n modifyValueByType,\n} from \"@/components/MarkdownEditor/lib/modifyValueByType\";\nimport type { MarkdownEditorUpload } from \"@/components/MarkdownEditor/lib/fileUpload\";\nimport { useFileUpload } from \"@/components/MarkdownEditor/lib/useFileUpload\";\nimport { useControlledHostValueProps } from \"@/lib/remote/useControlledHostValueProps\";\nimport {\n overlayTriggersTunneledTo,\n type PropsContext,\n PropsContextProvider,\n} from \"@/lib/propsContext\";\n\nexport type MarkdownEditorMode = \"editor\" | \"preview\";\n\nexport type { MarkdownEditorUpload };\n\nconst toolbarActionsTunnel = {\n id: \"toolbarActions\",\n component: \"MarkdownEditor\",\n} as const;\n\nexport interface MarkdownEditorProps\n extends TextAreaProps, Pick<MarkdownProps, \"headingOffset\"> {\n /**\n * Allows replacing the markdown preview renderer implementation. Defaults to\n * the internal `Markdown` component.\n */\n markdownComponent?: ComponentType<MarkdownProps>;\n /**\n * Uploads a file the user dropped onto the editor, pasted into it or picked\n * with its attachment button. A placeholder comment sits at the cursor while\n * the returned promise is pending: resolving replaces it with markdown\n * linking to the file — an image embed for an image — and rejecting takes it\n * back out. Without this prop the editor takes no files at all.\n *\n * Named without an `on` prefix on purpose: the remote generator turns an\n * `on*` prop into a fire-and-forget event, and this one has to hand a result\n * back.\n */\n uploadFile?: (file: File) => Promise<MarkdownEditorUpload>;\n /**\n * Which file types the editor takes, as the `accept` attribute of a file\n * input: a comma separated list of MIME types (`image/png`), MIME wildcards\n * (`image/*`) and file extensions (`.png`). Defaults to every type.\n */\n accept?: string;\n}\n\n/** @flr-generate all */\nexport const MarkdownEditor = flowComponent(\"MarkdownEditor\", (props) => {\n const {\n isDisabled,\n isReadOnly,\n children,\n className,\n rows = 5,\n autoResizeMaxRows,\n headingOffset,\n markdownComponent: MarkdownComponent = DefaultMarkdown,\n value,\n onChange,\n uploadFile,\n accept,\n ref,\n ...rest\n } = useControlledHostValueProps(props, \"\");\n\n const inputRef = useObjectRef(ref);\n const [mode, setMode] = useState<MarkdownEditorMode>(\"editor\");\n const toolbarActionsDisabled = isDisabled || mode === \"preview\";\n\n const { dropProps, isDropTarget, uploadFiles } = useFileUpload({\n accept,\n uploadFile,\n isDisabled: isDisabled || isReadOnly || mode === \"preview\",\n value,\n onChange,\n textAreaRef: inputRef,\n });\n\n const rootClassName = clsx(\n styles.markdownEditor,\n styles[`mode-${mode}`],\n isDropTarget && styles.dropTarget,\n className,\n );\n\n const toolbarActionsPropsContext: PropsContext = {\n ...overlayTriggersTunneledTo(toolbarActionsTunnel),\n Button: {\n tunnel: toolbarActionsTunnel,\n size: \"s\",\n variant: \"plain\",\n color: \"dark\",\n isDisabled: toolbarActionsDisabled,\n },\n };\n\n const handleKeyDown: KeyboardEventHandler = (event) => {\n if (event.key !== \"Enter\") {\n return;\n }\n\n const modifyParams = modifyValueByMarkdownSyntax(value, inputRef);\n if (!modifyParams) {\n return;\n }\n\n const { newValue, newSelectionStart, newSelectionEnd } = modifyParams;\n\n requestAnimationFrame(() => {\n if (inputRef.current) {\n inputRef.current.value = newValue;\n inputRef.current?.setSelectionRange(newSelectionStart, newSelectionEnd);\n scrollToCursor(newValue, inputRef.current);\n }\n });\n\n event.preventDefault();\n onChange(newValue);\n };\n\n const handleToolButtonPressed = (type: InsertType) => {\n const { newValue, newSelectionStart, newSelectionEnd } = modifyValueByType(\n value,\n type,\n inputRef,\n );\n\n requestAnimationFrame(() => {\n if (inputRef.current) {\n inputRef.current.value = newValue;\n inputRef.current.setSelectionRange(newSelectionStart, newSelectionEnd);\n inputRef.current.focus();\n }\n });\n\n onChange(newValue);\n };\n\n return (\n <div
|
|
1
|
+
{"version":3,"file":"MarkdownEditor.mjs","names":["DefaultMarkdown","styles"],"sources":["../../../../../../../src/components/MarkdownEditor/MarkdownEditor.tsx"],"sourcesContent":["import { type ComponentType, type KeyboardEventHandler, useState } from \"react\";\nimport styles from \"./MarkdownEditor.module.scss\";\nimport {\n Markdown as DefaultMarkdown,\n type MarkdownProps,\n} from \"@/components/Markdown\";\nimport { TextArea, type TextAreaProps } from \"@/components/TextArea\";\nimport { Toolbar } from \"@/components/MarkdownEditor/components/Toolbar\";\nimport clsx from \"clsx\";\nimport { flowComponent } from \"@/lib/componentFactory/flowComponent\";\nimport { useObjectRef } from \"@react-aria/utils\";\nimport {\n modifyValueByMarkdownSyntax,\n scrollToCursor,\n} from \"@/components/MarkdownEditor/lib/modifyValueByMarkdownSyntax\";\nimport {\n type InsertType,\n modifyValueByType,\n} from \"@/components/MarkdownEditor/lib/modifyValueByType\";\nimport type { MarkdownEditorUpload } from \"@/components/MarkdownEditor/lib/fileUpload\";\nimport { useFileUpload } from \"@/components/MarkdownEditor/lib/useFileUpload\";\nimport { useControlledHostValueProps } from \"@/lib/remote/useControlledHostValueProps\";\nimport {\n overlayTriggersTunneledTo,\n type PropsContext,\n PropsContextProvider,\n} from \"@/lib/propsContext\";\nimport {\n SkeletonModeReset,\n useSkeletonMode,\n} from \"@/components/SkeletonMode/skeletonModeContext\";\n\nexport type MarkdownEditorMode = \"editor\" | \"preview\";\n\nexport type { MarkdownEditorUpload };\n\nconst toolbarActionsTunnel = {\n id: \"toolbarActions\",\n component: \"MarkdownEditor\",\n} as const;\n\nexport interface MarkdownEditorProps\n extends TextAreaProps, Pick<MarkdownProps, \"headingOffset\"> {\n /**\n * Allows replacing the markdown preview renderer implementation. Defaults to\n * the internal `Markdown` component.\n */\n markdownComponent?: ComponentType<MarkdownProps>;\n /**\n * Uploads a file the user dropped onto the editor, pasted into it or picked\n * with its attachment button. A placeholder comment sits at the cursor while\n * the returned promise is pending: resolving replaces it with markdown\n * linking to the file — an image embed for an image — and rejecting takes it\n * back out. Without this prop the editor takes no files at all.\n *\n * Named without an `on` prefix on purpose: the remote generator turns an\n * `on*` prop into a fire-and-forget event, and this one has to hand a result\n * back.\n */\n uploadFile?: (file: File) => Promise<MarkdownEditorUpload>;\n /**\n * Which file types the editor takes, as the `accept` attribute of a file\n * input: a comma separated list of MIME types (`image/png`), MIME wildcards\n * (`image/*`) and file extensions (`.png`). Defaults to every type.\n */\n accept?: string;\n}\n\n/** @flr-generate all */\nexport const MarkdownEditor = flowComponent(\"MarkdownEditor\", (props) => {\n const {\n isDisabled,\n isReadOnly,\n children,\n className,\n rows = 5,\n autoResizeMaxRows,\n headingOffset,\n markdownComponent: MarkdownComponent = DefaultMarkdown,\n value,\n onChange,\n uploadFile,\n accept,\n ref,\n ...rest\n } = useControlledHostValueProps(props, \"\");\n\n const inputRef = useObjectRef(ref);\n const [mode, setMode] = useState<MarkdownEditorMode>(\"editor\");\n const toolbarActionsDisabled = isDisabled || mode === \"preview\";\n\n const { dropProps, isDropTarget, uploadFiles } = useFileUpload({\n accept,\n uploadFile,\n isDisabled: isDisabled || isReadOnly || mode === \"preview\",\n value,\n onChange,\n textAreaRef: inputRef,\n });\n\n const isSkeleton = useSkeletonMode();\n\n const rootClassName = clsx(\n styles.markdownEditor,\n styles[`mode-${mode}`],\n isDropTarget && styles.dropTarget,\n isSkeleton && styles.skeleton,\n className,\n );\n\n const toolbarActionsPropsContext: PropsContext = {\n ...overlayTriggersTunneledTo(toolbarActionsTunnel),\n Button: {\n tunnel: toolbarActionsTunnel,\n size: \"s\",\n variant: \"plain\",\n color: \"dark\",\n isDisabled: toolbarActionsDisabled,\n },\n };\n\n const handleKeyDown: KeyboardEventHandler = (event) => {\n if (event.key !== \"Enter\") {\n return;\n }\n\n const modifyParams = modifyValueByMarkdownSyntax(value, inputRef);\n if (!modifyParams) {\n return;\n }\n\n const { newValue, newSelectionStart, newSelectionEnd } = modifyParams;\n\n requestAnimationFrame(() => {\n if (inputRef.current) {\n inputRef.current.value = newValue;\n inputRef.current?.setSelectionRange(newSelectionStart, newSelectionEnd);\n scrollToCursor(newValue, inputRef.current);\n }\n });\n\n event.preventDefault();\n onChange(newValue);\n };\n\n const handleToolButtonPressed = (type: InsertType) => {\n const { newValue, newSelectionStart, newSelectionEnd } = modifyValueByType(\n value,\n type,\n inputRef,\n );\n\n requestAnimationFrame(() => {\n if (inputRef.current) {\n inputRef.current.value = newValue;\n inputRef.current.setSelectionRange(newSelectionStart, newSelectionEnd);\n inputRef.current.focus();\n }\n });\n\n onChange(newValue);\n };\n\n return (\n <div\n {...dropProps}\n className={rootClassName}\n inert={isSkeleton || undefined}\n >\n <TextArea\n {...rest}\n aria-hidden={mode === \"preview\"}\n isReadOnly={isReadOnly || mode === \"preview\"}\n isDisabled={isDisabled}\n ref={inputRef}\n value={value}\n rows={rows}\n autoResizeMaxRows={autoResizeMaxRows}\n onChange={onChange}\n onKeyDown={handleKeyDown}\n >\n <PropsContextProvider\n props={toolbarActionsPropsContext}\n dependencies={[toolbarActionsDisabled]}\n >\n {children}\n {mode === \"preview\" && (\n <MarkdownComponent\n headingOffset={headingOffset}\n className={styles.markdown}\n >\n {value}\n </MarkdownComponent>\n )}\n {/* Covered by the skeleton surface, so its buttons draw none. */}\n <SkeletonModeReset>\n <Toolbar\n currentMode={mode}\n isDisabled={isDisabled}\n onModeChange={setMode}\n onToolPressed={handleToolButtonPressed}\n accept={accept}\n isReadOnly={isReadOnly}\n onFilesSelected={uploadFiles}\n />\n </SkeletonModeReset>\n </PropsContextProvider>\n </TextArea>\n {/* One surface over toolbar and text area. The label and the field\n description keep their own skeleton rule. */}\n {isSkeleton && <div className={styles.skeletonSurface} />}\n </div>\n );\n});\n\nexport default MarkdownEditor;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAoCA,IAAM,uBAAuB;CAC3B,IAAI;CACJ,WAAW;AACb;;AA8BA,IAAa,iBAAiB,cAAc,mBAAmB,UAAU;CACvE,MAAM,EACJ,YACA,YACA,UACA,WACA,OAAO,GACP,mBACA,eACA,mBAAmB,oBAAoBA,UACvC,OACA,UACA,YACA,QACA,KACA,GAAG,SACD,4BAA4B,OAAO,EAAE;CAEzC,MAAM,WAAW,aAAa,GAAG;CACjC,MAAM,CAAC,MAAM,WAAW,SAA6B,QAAQ;CAC7D,MAAM,yBAAyB,cAAc,SAAS;CAEtD,MAAM,EAAE,WAAW,cAAc,gBAAgB,cAAc;EAC7D;EACA;EACA,YAAY,cAAc,cAAc,SAAS;EACjD;EACA;EACA,aAAa;CACf,CAAC;CAED,MAAM,aAAa,gBAAgB;CAEnC,MAAM,gBAAgB,KACpBC,8BAAO,gBACPA,8BAAO,QAAQ,SACf,gBAAgBA,8BAAO,YACvB,cAAcA,8BAAO,UACrB,SACF;CAEA,MAAM,6BAA2C;EAC/C,GAAG,0BAA0B,oBAAoB;EACjD,QAAQ;GACN,QAAQ;GACR,MAAM;GACN,SAAS;GACT,OAAO;GACP,YAAY;EACd;CACF;CAEA,MAAM,iBAAuC,UAAU;EACrD,IAAI,MAAM,QAAQ,SAChB;EAGF,MAAM,eAAe,4BAA4B,OAAO,QAAQ;EAChE,IAAI,CAAC,cACH;EAGF,MAAM,EAAE,UAAU,mBAAmB,oBAAoB;EAEzD,4BAA4B;GAC1B,IAAI,SAAS,SAAS;IACpB,SAAS,QAAQ,QAAQ;IACzB,SAAS,SAAS,kBAAkB,mBAAmB,eAAe;IACtE,eAAe,UAAU,SAAS,OAAO;GAC3C;EACF,CAAC;EAED,MAAM,eAAe;EACrB,SAAS,QAAQ;CACnB;CAEA,MAAM,2BAA2B,SAAqB;EACpD,MAAM,EAAE,UAAU,mBAAmB,oBAAoB,kBACvD,OACA,MACA,QACF;EAEA,4BAA4B;GAC1B,IAAI,SAAS,SAAS;IACpB,SAAS,QAAQ,QAAQ;IACzB,SAAS,QAAQ,kBAAkB,mBAAmB,eAAe;IACrE,SAAS,QAAQ,MAAM;GACzB;EACF,CAAC;EAED,SAAS,QAAQ;CACnB;CAEA,OACE,qBAAC,OAAD;EACE,GAAI;EACJ,WAAW;EACX,OAAO,cAAc,KAAA;EAHvB,UAAA,CAKE,oBAAC,UAAD;GACE,GAAI;GACJ,eAAa,SAAS;GACtB,YAAY,cAAc,SAAS;GACvB;GACZ,KAAK;GACE;GACD;GACa;GACT;GACV,WAAW;GAEX,UAAA,qBAAC,sBAAD;IACE,OAAO;IACP,cAAc,CAAC,sBAAsB;IAFvC,UAAA;KAIG;KACA,SAAS,aACR,oBAAC,mBAAD;MACiB;MACf,WAAWA,8BAAO;MAEjB,UAAA;KACgB,CAAA;KAGrB,oBAAC,mBAAD,EAAA,UACE,oBAAC,SAAD;MACE,aAAa;MACD;MACZ,cAAc;MACd,eAAe;MACP;MACI;MACZ,iBAAiB;KAClB,CAAA,EACgB,CAAA;IACC;;EACd,CAAA,GAGT,cAAc,oBAAC,OAAD,EAAK,WAAWA,8BAAO,gBAAkB,CAAA,CACrD;;AAET,CAAC"}
|
|
@@ -7,6 +7,8 @@ var toolbarButtons = "flow--markdown-editor--toolbar-buttons";
|
|
|
7
7
|
var modeButton = "flow--markdown-editor--mode-button";
|
|
8
8
|
var markdown = "flow--markdown-editor--markdown";
|
|
9
9
|
var dropTarget = "flow--markdown-editor--drop-target";
|
|
10
|
+
var skeleton = "flow--markdown-editor--skeleton";
|
|
11
|
+
var skeletonSurface = "flow--markdown-editor--skeleton-surface";
|
|
10
12
|
var MarkdownEditor_module_default = {
|
|
11
13
|
markdownEditor,
|
|
12
14
|
toolbar,
|
|
@@ -15,9 +17,13 @@ var MarkdownEditor_module_default = {
|
|
|
15
17
|
markdown,
|
|
16
18
|
"mode-editor": "flow--markdown-editor--mode-editor",
|
|
17
19
|
"mode-preview": "flow--markdown-editor--mode-preview",
|
|
18
|
-
dropTarget
|
|
20
|
+
dropTarget,
|
|
21
|
+
skeleton,
|
|
22
|
+
skeletonSurface,
|
|
23
|
+
"skeleton-surface-shimmer": "flow--markdown-editor--skeleton-surface-shimmer",
|
|
24
|
+
"skeleton-text-shimmer": "flow--markdown-editor--skeleton-text-shimmer"
|
|
19
25
|
};
|
|
20
26
|
//#endregion
|
|
21
|
-
export { MarkdownEditor_module_default as default, dropTarget, markdown, markdownEditor, modeButton, toolbar, toolbarButtons };
|
|
27
|
+
export { MarkdownEditor_module_default as default, dropTarget, markdown, markdownEditor, modeButton, skeleton, skeletonSurface, toolbar, toolbarButtons };
|
|
22
28
|
|
|
23
29
|
//# sourceMappingURL=MarkdownEditor.module.mjs.map
|
package/dist/js/packages/components/src/components/MarkdownEditor/MarkdownEditor.module.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MarkdownEditor.module.mjs","names":[],"sources":["../../../../../../../src/components/MarkdownEditor/MarkdownEditor.module.scss"],"sourcesContent":["@use \"@/styles/mixins/formControl\";\n@use \"@/styles/mixins/scrollbar\";\n\n.markdownEditor {\n display: grid;\n grid-template-areas:\n \"label\"\n \"toolbar\"\n \"content\"\n \"fieldDescription\";\n\n .toolbar {\n grid-area: toolbar;\n display: flex;\n justify-content: space-between;\n padding: var(--form-control--padding-y);\n column-gap: var(--form-control--padding-y);\n flex-wrap: wrap;\n\n @include formControl.formBorder;\n @include formControl.formColor;\n @include formControl.formAnimation;\n\n & {\n border-bottom: none;\n border-end-start-radius: 0;\n border-end-end-radius: 0;\n }\n }\n\n .toolbarButtons {\n display: flex;\n flex-wrap: wrap;\n column-gap: var(--form-control--padding-y);\n }\n\n .modeButton {\n margin-inline-start: auto;\n }\n\n .markdown {\n overflow-y: auto;\n\n @include formControl.formBorder;\n @include formControl.formColor;\n }\n\n :global(.flow--form-field) {\n display: contents;\n }\n\n /* The inner text-area element is react-aria's, but Flow's TextArea puts a\n class on it — select through that class instead of the element type. */\n :global(.flow--text-area--input),\n .markdown {\n @include scrollbar.scrollbar;\n\n grid-area: content;\n padding-block: calc(\n var(--form-control--padding-y) - var(--form-control--border-width)\n );\n padding-inline: var(--form-control--padding-x);\n border-start-start-radius: 0;\n border-start-end-radius: 0;\n }\n\n &.mode-editor {\n .markdown {\n display: none;\n }\n }\n\n /* The hidden text area keeps its place in the grid cell, so the row keeps\n its height – a resized one included. `contain: size` stops the preview from\n growing the row, and stretching fills it exactly. */\n &.mode-preview {\n :global(.flow--text-area--input) {\n opacity: 0;\n pointer-events: none;\n }\n\n .markdown {\n contain: size;\n }\n }\n\n /* States */\n\n &:has(:global(.flow--text-area--input:hover)) .toolbar {\n background-color: var(--form-control--background-color--hover);\n }\n\n &:has(:global(.flow--text-area--input[data-invalid])) .toolbar,\n &:has(:global(.flow--text-area--input[data-invalid])) .markdown {\n background-color: var(--form-control--background-color--invalid);\n border-color: var(--form-control--border-color--invalid);\n }\n\n &:has(:global(.flow--text-area--input[data-focused=\"true\"])) .toolbar,\n &:has(:global(.flow--text-area--input[data-focused=\"true\"])) .markdown {\n background-color: var(--form-control--background-color--focused);\n border-color: var(--form-control--border-color--focused);\n }\n\n &:has(:global(.flow--text-area--input[data-disabled])).mode-editor .toolbar {\n background-color: var(--form-control--background-color--disabled);\n border-color: var(--form-control--border-color--disabled);\n }\n\n /* A drag over the editor reads as its focused state -- dropping focuses it. */\n &.dropTarget {\n .toolbar,\n .markdown,\n :global(.flow--text-area--input) {\n background-color: var(--form-control--background-color--focused);\n border-color: var(--form-control--border-color--focused);\n }\n }\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"MarkdownEditor.module.mjs","names":[],"sources":["../../../../../../../src/components/MarkdownEditor/MarkdownEditor.module.scss"],"sourcesContent":["@use \"@/styles/mixins/formControl\";\n@use \"@/styles/mixins/scrollbar\";\n@use \"@/styles/mixins/skeleton\";\n\n.markdownEditor {\n display: grid;\n grid-template-areas:\n \"label\"\n \"toolbar\"\n \"content\"\n \"fieldDescription\";\n\n .toolbar {\n grid-area: toolbar;\n display: flex;\n justify-content: space-between;\n padding: var(--form-control--padding-y);\n column-gap: var(--form-control--padding-y);\n flex-wrap: wrap;\n\n @include formControl.formBorder;\n @include formControl.formColor;\n @include formControl.formAnimation;\n\n & {\n border-bottom: none;\n border-end-start-radius: 0;\n border-end-end-radius: 0;\n }\n }\n\n .toolbarButtons {\n display: flex;\n flex-wrap: wrap;\n column-gap: var(--form-control--padding-y);\n }\n\n .modeButton {\n margin-inline-start: auto;\n }\n\n .markdown {\n overflow-y: auto;\n\n @include formControl.formBorder;\n @include formControl.formColor;\n }\n\n :global(.flow--form-field) {\n display: contents;\n }\n\n /* The inner text-area element is react-aria's, but Flow's TextArea puts a\n class on it — select through that class instead of the element type. */\n :global(.flow--text-area--input),\n .markdown {\n @include scrollbar.scrollbar;\n\n grid-area: content;\n padding-block: calc(\n var(--form-control--padding-y) - var(--form-control--border-width)\n );\n padding-inline: var(--form-control--padding-x);\n border-start-start-radius: 0;\n border-start-end-radius: 0;\n }\n\n &.mode-editor {\n .markdown {\n display: none;\n }\n }\n\n /* The hidden text area keeps its place in the grid cell, so the row keeps\n its height – a resized one included. `contain: size` stops the preview from\n growing the row, and stretching fills it exactly. */\n &.mode-preview {\n :global(.flow--text-area--input) {\n opacity: 0;\n pointer-events: none;\n }\n\n .markdown {\n contain: size;\n }\n }\n\n /* States */\n\n &:has(:global(.flow--text-area--input:hover)) .toolbar {\n background-color: var(--form-control--background-color--hover);\n }\n\n &:has(:global(.flow--text-area--input[data-invalid])) .toolbar,\n &:has(:global(.flow--text-area--input[data-invalid])) .markdown {\n background-color: var(--form-control--background-color--invalid);\n border-color: var(--form-control--border-color--invalid);\n }\n\n &:has(:global(.flow--text-area--input[data-focused=\"true\"])) .toolbar,\n &:has(:global(.flow--text-area--input[data-focused=\"true\"])) .markdown {\n background-color: var(--form-control--background-color--focused);\n border-color: var(--form-control--border-color--focused);\n }\n\n &:has(:global(.flow--text-area--input[data-disabled])).mode-editor .toolbar {\n background-color: var(--form-control--background-color--disabled);\n border-color: var(--form-control--border-color--disabled);\n }\n\n /* A drag over the editor reads as its focused state -- dropping focuses it. */\n &.dropTarget {\n .toolbar,\n .markdown,\n :global(.flow--text-area--input) {\n background-color: var(--form-control--background-color--focused);\n border-color: var(--form-control--border-color--focused);\n }\n }\n\n /* SkeletonMode: toolbar and text area keep their size under one surface */\n\n &.skeleton {\n .toolbar,\n .markdown,\n :global(.flow--text-area--input) {\n visibility: hidden;\n }\n }\n\n .skeletonSurface {\n @include skeleton.surface;\n\n --skeleton-radius: var(--form-control--corner-radius);\n\n grid-row: toolbar-start / content-end;\n grid-column: toolbar;\n }\n}\n\n@include skeleton.keyframes;\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Modal.module.mjs","names":[],"sources":["../../../../../../../src/components/Modal/Modal.module.scss"],"sourcesContent":["@use \"@/styles/mixins/scrollbar\";\n\n/* Caps the dialog width per size token (`size-s` / `size-m` / `size-l`). */\n@mixin size($size) {\n &.size-#{$size} {\n [role=\"dialog\"] {\n width: inherit;\n max-width: var(--modal--size--#{$size});\n }\n }\n}\n\n/* ===========================================================================\n Base — shared by Modal (centered / bottom sheet) and OffCanvas (side panel).\n =========================================================================== */\n.modal,\n.offCanvas {\n /* Overlay.module.scss lays the viewport out; the dialog inside it is the only\n pointer target. */\n > :global(.flow--overlay--viewport) {\n pointer-events: none;\n\n /* react-aria's own modal wrapper — it gets no className from Flow, so\n its default `react-aria-Modal` class is the handle. */\n > :global(.react-aria-Modal) {\n display: flex;\n justify-content: center;\n width: inherit;\n max-height: var(--visual-viewport-height);\n padding: var(--size-px--xl);\n }\n }\n\n /* Close button: hidden when an action group is present, unless forced. */\n &:has(.actionGroup) {\n .closeButton:not(.alwaysVisible) {\n display: none;\n }\n }\n\n .closeButton.alwaysHidden {\n display: none;\n }\n\n /* The dialog card itself — a flex column. It is also the scroll container on\n mobile, and the sticky header/footer stack against its content only. */\n [role=\"dialog\"] {\n display: flex;\n flex-direction: column;\n isolation: isolate;\n max-height: 100%;\n overflow: hidden;\n outline: none;\n pointer-events: all;\n background-color: var(--modal--background-color);\n border: var(--modal--border-width) var(--modal--border-style)\n var(--modal--border-color);\n\n // A consumer `Form` (or raw `<form>`) wrapping the modal content. `Form`\n // is a plain FC, so the props context cannot give it a class.\n // stylelint-disable-next-line selector-max-type -- consumer form, no class\n > form {\n display: contents;\n }\n }\n\n /* Header */\n // A `Header`/`SectionHeader` — or a raw `<header>` — the consumer places in\n // the modal; both must match.\n // stylelint-disable-next-line selector-max-type -- consumer-placed header\n header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n\n .header {\n display: flex;\n align-items: center;\n gap: var(--heading--icon-to-text-spacing);\n padding-top: var(--modal--header-padding-top);\n padding-inline: var(--modal--padding);\n\n /* Flatten the heading's text and content spans into the header row, so\n badges stay behind the title instead of wrapping onto their own line.\n Heading's spans do carry classes, but `.flow--heading--heading-content`\n already sets `display: none` on `:empty` at the same specificity a class\n selector here would reach — source order would then decide. */\n // stylelint-disable-next-line selector-max-type -- see above\n > span {\n display: contents;\n }\n\n :global(.flow--heading--heading-text-spacer) {\n display: none;\n }\n\n :global(.flow--heading--heading-content)\n :global(.flow--heading--heading-content-item):not(:last-child) {\n margin-inline-end: 0;\n }\n\n .headerTitle {\n min-width: 0;\n }\n\n /* Remote apps built against Flow < 1.2.0 send the close button without\n ClearPropsContext, so the Heading tunnels it into a content item — that\n item is the flex item then — and passes it its button size `s`. */\n .closeButton,\n :global(.flow--heading--heading-content-item):has(.closeButton) {\n order: 1;\n margin-inline-start: auto;\n }\n\n .closeButton:global(.flow--button--size-s) {\n padding: var(--button--padding-icon-only);\n border-radius: var(--button--corner-radius);\n\n :global(.flow--icon) {\n width: var(--icon--size--m);\n height: var(--icon--size--m);\n }\n }\n }\n\n /* Content — the scrollable body */\n .content,\n .columnLayout {\n @include scrollbar.scrollbar;\n\n flex-grow: 1;\n min-height: var(--modal--content-min-height);\n padding: var(--modal--padding);\n overflow: hidden auto;\n background-color: var(--modal--background-color);\n }\n\n .columnLayout .accentBox {\n position: sticky;\n top: 0;\n height: fit-content;\n }\n\n /* Action group — the footer */\n .actionGroup {\n padding: var(--modal--padding);\n background-color: var(--modal--footer-background-color);\n }\n\n /* ActionGroup's \"sorted\" layout sets flex-grow:1 on itself; the modal footer\n must keep its natural height (otherwise it fills the full-height off-canvas\n panel). Scope via the dialog so flex-grow:0 wins the equal-specificity /\n source-order battle — without raising the specificity of the padding above,\n which the mobile rules override. */\n [role=\"dialog\"] .actionGroup {\n flex-grow: 0;\n }\n}\n\n/* ===========================================================================\n Modal — desktop (centered dialog, zoom in/out).\n =========================================================================== */\n@media (width > 768px) {\n .modal {\n @include size(s);\n @include size(m);\n @include size(l);\n\n [role=\"dialog\"] {\n border-radius: var(--modal--corner-radius);\n }\n\n > :global(.flow--overlay--viewport) > :global(.react-aria-Modal) {\n &[data-entering] {\n animation: modal-zoom var(--transition--duration--slow)\n cubic-bezier(0.1, 0.8, 0.3, 1.2);\n }\n\n &[data-exiting] {\n animation: modal-zoom var(--transition--duration--default)\n cubic-bezier(0.1, 0.8, 0.3, 1.2) reverse;\n }\n }\n }\n}\n\n/* ===========================================================================\n OffCanvas — side panel (all widths), full height, slides in from the side.\n =========================================================================== */\n.offCanvas {\n @include size(s);\n @include size(m);\n @include size(l);\n\n [role=\"dialog\"] {\n height: 100%;\n border-radius: 0;\n }\n\n > :global(.flow--overlay--viewport) {\n padding-inline-start: var(--size-px--m);\n\n > :global(.react-aria-Modal) {\n justify-content: flex-end;\n width: inherit;\n height: inherit;\n padding: unset;\n\n &[data-entering] {\n animation: modal-slide-in-from-right var(--transition--duration--slow);\n }\n\n &[data-exiting] {\n animation: modal-slide-in-from-right\n var(--transition--duration--default) reverse;\n }\n }\n }\n\n &.left {\n > :global(.flow--overlay--viewport) {\n padding-inline: 0 var(--size-px--m);\n\n > :global(.react-aria-Modal) {\n justify-content: flex-start;\n padding: unset;\n\n &[data-entering] {\n animation: modal-slide-in-from-left var(--transition--duration--slow);\n }\n\n &[data-exiting] {\n animation: modal-slide-in-from-left\n var(--transition--duration--default) reverse;\n }\n }\n }\n }\n}\n\n/* ===========================================================================\n Modal — mobile (bottom sheet), issue #2423.\n\n One scroll container: the dialog scrolls while the header sticks to the top\n and the footer to the bottom. While the virtual keyboard is open\n (.keyboardVisible) both un-stick so header + content + footer flow normally\n and the content gets the full available space.\n =========================================================================== */\n@media (max-width: 768px) {\n .modal {\n /* Bottom-anchored sheet: rounded top corners + slide-up animation. */\n > :global(.flow--overlay--viewport) > :global(.react-aria-Modal) {\n margin-top: auto;\n width: 100%;\n padding: unset;\n overflow: hidden;\n border-start-start-radius: var(--modal--corner-radius);\n border-start-end-radius: var(--modal--corner-radius);\n pointer-events: all;\n\n &[data-entering] {\n animation: modal-slide-up var(--transition--duration--slow);\n }\n\n &[data-exiting] {\n animation: modal-slide-up var(--transition--duration--default) reverse;\n }\n }\n\n /* The dialog is the single scroll container. Capped just below the visual\n viewport so a full-height sheet keeps a small gap from the top edge. */\n [role=\"dialog\"] {\n @include scrollbar.scrollbar;\n\n width: inherit;\n max-height: calc(\n var(--visual-viewport-height) - var(--modal--tray-top-spacing)\n );\n overflow: hidden auto;\n }\n\n // stylelint-disable-next-line selector-max-type -- consumer form, see above\n [role=\"dialog\"] > form {\n width: inherit;\n }\n\n /* flex: 0 0 auto keeps natural heights; without flex-shrink:0 the flex\n column compresses the content box and the (overflow:visible) fields\n spill over the footer. */\n .header,\n .content,\n .columnLayout,\n .actionGroup {\n flex: 0 0 auto;\n }\n\n .content,\n .columnLayout {\n min-height: 0;\n overflow: visible;\n }\n\n /* Docked header + footer (sticky within the single scroll container). */\n .header {\n position: sticky;\n top: 0;\n z-index: 1;\n background-color: var(--modal--background-color);\n }\n\n .actionGroup {\n position: sticky;\n bottom: 0;\n z-index: 1;\n }\n }\n\n /* Keyboard open: un-stick both so everything flows for maximum typing space.\n The dialog fills the available height and the footer uses margin-top:auto,\n so with SHORT content the footer still sits at the bottom (not mid-air) and\n with tall content it scrolls away with everything else. Never hidden. */\n .modal.keyboardVisible {\n [role=\"dialog\"] {\n min-height: calc(\n var(--visual-viewport-height) - var(--modal--tray-top-spacing)\n );\n }\n\n .header,\n .actionGroup {\n position: static;\n }\n\n .actionGroup {\n margin-top: auto;\n }\n }\n\n /* Shared mobile spacing + full-width stacked actions (Modal + OffCanvas). */\n .modal,\n .offCanvas {\n .header {\n padding-inline: var(--modal--padding-mobile);\n }\n\n .content,\n .columnLayout,\n .actionGroup {\n padding: var(--modal--padding-mobile);\n }\n\n .actionGroup {\n flex-direction: column;\n\n // The footer's buttons are consumer `Button`/`Action` children; a raw\n // `<button>` matches today too.\n // stylelint-disable-next-line selector-max-type -- consumer children\n button {\n width: 100%;\n }\n }\n }\n}\n\n/* ===========================================================================\n Animations\n =========================================================================== */\n@keyframes modal-zoom {\n /* Start with scale(1) to let ResizeObservers take the correct width on mount. */\n 0% {\n opacity: 0;\n transform: scale(1);\n }\n\n 0.1% {\n opacity: 1;\n transform: scale(0.8);\n }\n\n 100% {\n transform: scale(1);\n }\n}\n\n@keyframes modal-slide-up {\n from {\n translate: 0 30%;\n }\n\n to {\n translate: 0 0;\n }\n}\n\n@keyframes modal-slide-in-from-right {\n from {\n translate: 30% 0;\n }\n\n to {\n translate: 0 0;\n }\n}\n\n@keyframes modal-slide-in-from-left {\n from {\n translate: -30% 0;\n }\n\n to {\n translate: 0 0;\n }\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"Modal.module.mjs","names":[],"sources":["../../../../../../../src/components/Modal/Modal.module.scss"],"sourcesContent":["@use \"@/styles/mixins/scrollbar\";\n@use \"@/styles/mixins/skeleton\";\n\n@include skeleton.keyframes;\n\n/* Caps the dialog width per size token (`size-s` / `size-m` / `size-l`). */\n@mixin size($size) {\n &.size-#{$size} {\n [role=\"dialog\"] {\n width: inherit;\n max-width: var(--modal--size--#{$size});\n }\n }\n}\n\n/* ===========================================================================\n Base — shared by Modal (centered / bottom sheet) and OffCanvas (side panel).\n =========================================================================== */\n.modal,\n.offCanvas {\n /* Overlay.module.scss lays the viewport out; the dialog inside it is the only\n pointer target. */\n > :global(.flow--overlay--viewport) {\n pointer-events: none;\n\n /* react-aria's own modal wrapper — it gets no className from Flow, so\n its default `react-aria-Modal` class is the handle. */\n > :global(.react-aria-Modal) {\n display: flex;\n justify-content: center;\n width: inherit;\n max-height: var(--visual-viewport-height);\n padding: var(--size-px--xl);\n }\n }\n\n /* Close button: hidden when an action group is present, unless forced. */\n &:has(.actionGroup) {\n .closeButton:not(.alwaysVisible) {\n display: none;\n }\n }\n\n .closeButton.alwaysHidden {\n display: none;\n }\n\n /* The dialog card itself — a flex column. It is also the scroll container on\n mobile, and the sticky header/footer stack against its content only. */\n [role=\"dialog\"] {\n display: flex;\n flex-direction: column;\n isolation: isolate;\n max-height: 100%;\n overflow: hidden;\n outline: none;\n pointer-events: all;\n background-color: var(--modal--background-color);\n border: var(--modal--border-width) var(--modal--border-style)\n var(--modal--border-color);\n\n // A consumer `Form` (or raw `<form>`) wrapping the modal content. `Form`\n // is a plain FC, so the props context cannot give it a class.\n // stylelint-disable-next-line selector-max-type -- consumer form, no class\n > form {\n display: contents;\n }\n }\n\n /* Header */\n // A `Header`/`SectionHeader` — or a raw `<header>` — the consumer places in\n // the modal; both must match.\n // stylelint-disable-next-line selector-max-type -- consumer-placed header\n header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n\n .header {\n display: flex;\n align-items: center;\n gap: var(--heading--icon-to-text-spacing);\n padding-top: var(--modal--header-padding-top);\n padding-inline: var(--modal--padding);\n\n /* Flatten the heading's text and content spans into the header row, so\n badges stay behind the title instead of wrapping onto their own line.\n Heading's spans do carry classes, but `.flow--heading--heading-content`\n already sets `display: none` on `:empty` at the same specificity a class\n selector here would reach — source order would then decide. */\n // stylelint-disable-next-line selector-max-type -- see above\n > span {\n display: contents;\n }\n\n :global(.flow--heading--heading-text-spacer) {\n display: none;\n }\n\n :global(.flow--heading--heading-content)\n :global(.flow--heading--heading-content-item):not(:last-child) {\n margin-inline-end: 0;\n }\n\n .headerTitle {\n min-width: 0;\n }\n\n /* Remote apps built against Flow < 1.2.0 send the close button without\n ClearPropsContext, so the Heading tunnels it into a content item — that\n item is the flex item then — and passes it its button size `s`. */\n .closeButton,\n :global(.flow--heading--heading-content-item):has(.closeButton) {\n order: 1;\n margin-inline-start: auto;\n }\n\n .closeButton:global(.flow--button--size-s) {\n padding: var(--button--padding-icon-only);\n border-radius: var(--button--corner-radius);\n\n :global(.flow--icon) {\n width: var(--icon--size--m);\n height: var(--icon--size--m);\n }\n }\n\n /* SkeletonMode: the heading's text bar wraps title and close button. It\n gives up its box, so both stay in the header row, and each draws its\n own skeleton. So does the span the bar sits in. */\n :has(> :global(.flow--skeleton-mode--skeleton-text-content)) {\n display: contents;\n }\n\n :global(.flow--skeleton-mode--skeleton-text-content) {\n display: contents;\n\n > .headerTitle {\n @include skeleton.text;\n\n visibility: visible;\n }\n\n > .closeButton {\n @include skeleton.shape;\n\n --skeleton-radius: var(--button--corner-radius);\n\n visibility: visible;\n }\n }\n }\n\n /* Content — the scrollable body */\n .content,\n .columnLayout {\n @include scrollbar.scrollbar;\n\n flex-grow: 1;\n min-height: var(--modal--content-min-height);\n padding: var(--modal--padding);\n overflow: hidden auto;\n background-color: var(--modal--background-color);\n }\n\n .columnLayout .accentBox {\n position: sticky;\n top: 0;\n height: fit-content;\n }\n\n /* Action group — the footer */\n .actionGroup {\n padding: var(--modal--padding);\n background-color: var(--modal--footer-background-color);\n }\n\n /* ActionGroup's \"sorted\" layout sets flex-grow:1 on itself; the modal footer\n must keep its natural height (otherwise it fills the full-height off-canvas\n panel). Scope via the dialog so flex-grow:0 wins the equal-specificity /\n source-order battle — without raising the specificity of the padding above,\n which the mobile rules override. */\n [role=\"dialog\"] .actionGroup {\n flex-grow: 0;\n }\n}\n\n/* ===========================================================================\n Modal — desktop (centered dialog, zoom in/out).\n =========================================================================== */\n@media (width > 768px) {\n .modal {\n @include size(s);\n @include size(m);\n @include size(l);\n\n [role=\"dialog\"] {\n border-radius: var(--modal--corner-radius);\n }\n\n > :global(.flow--overlay--viewport) > :global(.react-aria-Modal) {\n &[data-entering] {\n animation: modal-zoom var(--transition--duration--slow)\n cubic-bezier(0.1, 0.8, 0.3, 1.2);\n }\n\n &[data-exiting] {\n animation: modal-zoom var(--transition--duration--default)\n cubic-bezier(0.1, 0.8, 0.3, 1.2) reverse;\n }\n }\n }\n}\n\n/* ===========================================================================\n OffCanvas — side panel (all widths), full height, slides in from the side.\n =========================================================================== */\n.offCanvas {\n @include size(s);\n @include size(m);\n @include size(l);\n\n [role=\"dialog\"] {\n height: 100%;\n border-radius: 0;\n }\n\n > :global(.flow--overlay--viewport) {\n padding-inline-start: var(--size-px--m);\n\n > :global(.react-aria-Modal) {\n justify-content: flex-end;\n width: inherit;\n height: inherit;\n padding: unset;\n\n &[data-entering] {\n animation: modal-slide-in-from-right var(--transition--duration--slow);\n }\n\n &[data-exiting] {\n animation: modal-slide-in-from-right\n var(--transition--duration--default) reverse;\n }\n }\n }\n\n &.left {\n > :global(.flow--overlay--viewport) {\n padding-inline: 0 var(--size-px--m);\n\n > :global(.react-aria-Modal) {\n justify-content: flex-start;\n padding: unset;\n\n &[data-entering] {\n animation: modal-slide-in-from-left var(--transition--duration--slow);\n }\n\n &[data-exiting] {\n animation: modal-slide-in-from-left\n var(--transition--duration--default) reverse;\n }\n }\n }\n }\n}\n\n/* ===========================================================================\n Modal — mobile (bottom sheet), issue #2423.\n\n One scroll container: the dialog scrolls while the header sticks to the top\n and the footer to the bottom. While the virtual keyboard is open\n (.keyboardVisible) both un-stick so header + content + footer flow normally\n and the content gets the full available space.\n =========================================================================== */\n@media (max-width: 768px) {\n .modal {\n /* Bottom-anchored sheet: rounded top corners + slide-up animation. */\n > :global(.flow--overlay--viewport) > :global(.react-aria-Modal) {\n margin-top: auto;\n width: 100%;\n padding: unset;\n overflow: hidden;\n border-start-start-radius: var(--modal--corner-radius);\n border-start-end-radius: var(--modal--corner-radius);\n pointer-events: all;\n\n &[data-entering] {\n animation: modal-slide-up var(--transition--duration--slow);\n }\n\n &[data-exiting] {\n animation: modal-slide-up var(--transition--duration--default) reverse;\n }\n }\n\n /* The dialog is the single scroll container. Capped just below the visual\n viewport so a full-height sheet keeps a small gap from the top edge. */\n [role=\"dialog\"] {\n @include scrollbar.scrollbar;\n\n width: inherit;\n max-height: calc(\n var(--visual-viewport-height) - var(--modal--tray-top-spacing)\n );\n overflow: hidden auto;\n }\n\n // stylelint-disable-next-line selector-max-type -- consumer form, see above\n [role=\"dialog\"] > form {\n width: inherit;\n }\n\n /* flex: 0 0 auto keeps natural heights; without flex-shrink:0 the flex\n column compresses the content box and the (overflow:visible) fields\n spill over the footer. */\n .header,\n .content,\n .columnLayout,\n .actionGroup {\n flex: 0 0 auto;\n }\n\n .content,\n .columnLayout {\n min-height: 0;\n overflow: visible;\n }\n\n /* Docked header + footer (sticky within the single scroll container). */\n .header {\n position: sticky;\n top: 0;\n z-index: 1;\n background-color: var(--modal--background-color);\n }\n\n .actionGroup {\n position: sticky;\n bottom: 0;\n z-index: 1;\n }\n }\n\n /* Keyboard open: un-stick both so everything flows for maximum typing space.\n The dialog fills the available height and the footer uses margin-top:auto,\n so with SHORT content the footer still sits at the bottom (not mid-air) and\n with tall content it scrolls away with everything else. Never hidden. */\n .modal.keyboardVisible {\n [role=\"dialog\"] {\n min-height: calc(\n var(--visual-viewport-height) - var(--modal--tray-top-spacing)\n );\n }\n\n .header,\n .actionGroup {\n position: static;\n }\n\n .actionGroup {\n margin-top: auto;\n }\n }\n\n /* Shared mobile spacing + full-width stacked actions (Modal + OffCanvas). */\n .modal,\n .offCanvas {\n .header {\n padding-inline: var(--modal--padding-mobile);\n }\n\n .content,\n .columnLayout,\n .actionGroup {\n padding: var(--modal--padding-mobile);\n }\n\n .actionGroup {\n flex-direction: column;\n\n // The footer's buttons are consumer `Button`/`Action` children; a raw\n // `<button>` matches today too.\n // stylelint-disable-next-line selector-max-type -- consumer children\n button {\n width: 100%;\n }\n }\n }\n}\n\n/* ===========================================================================\n Animations\n =========================================================================== */\n@keyframes modal-zoom {\n /* Start with scale(1) to let ResizeObservers take the correct width on mount. */\n 0% {\n opacity: 0;\n transform: scale(1);\n }\n\n 0.1% {\n opacity: 1;\n transform: scale(0.8);\n }\n\n 100% {\n transform: scale(1);\n }\n}\n\n@keyframes modal-slide-up {\n from {\n translate: 0 30%;\n }\n\n to {\n translate: 0 0;\n }\n}\n\n@keyframes modal-slide-in-from-right {\n from {\n translate: 30% 0;\n }\n\n to {\n translate: 0 0;\n }\n}\n\n@keyframes modal-slide-in-from-left {\n from {\n translate: -30% 0;\n }\n\n to {\n translate: 0 0;\n }\n}\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SkeletonTextContent.module.mjs","names":[],"sources":["../../../../../../../../../src/components/SkeletonMode/components/SkeletonTextContent/SkeletonTextContent.module.scss"],"sourcesContent":["@use \"@/styles/mixins/skeleton\";\n\n.skeletonTextContent {\n @include skeleton.text;\n}\n\n@include skeleton.keyframes;\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"SkeletonTextContent.module.mjs","names":[],"sources":["../../../../../../../../../src/components/SkeletonMode/components/SkeletonTextContent/SkeletonTextContent.module.scss"],"sourcesContent":["@use \"@/styles/mixins/skeleton\";\n\n.skeletonTextContent {\n @include skeleton.text;\n}\n\n/* An ancestor that truncates the text paints its ellipsis in its own color,\n outside the bar. The bar sits one level deeper when a flex parent needs an\n outer span. `!important`: the truncation comes from the component, with any\n specificity. */\n*:has(> .skeletonTextContent),\n*:has(> * > .skeletonTextContent) {\n text-overflow: clip !important;\n}\n\n@include skeleton.keyframes;\n"],"mappings":""}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
/* */
|
|
3
3
|
import { SkeletonText } from "../../../SkeletonText/SkeletonText.mjs";
|
|
4
|
+
import { SkeletonRawText } from "../../../SkeletonMode/components/SkeletonRawText/SkeletonRawText.mjs";
|
|
4
5
|
import Table_module_default from "../../Table.module.mjs";
|
|
5
6
|
import { TableColumn } from "../TableColumn/TableColumn.mjs";
|
|
6
7
|
import clsx from "clsx";
|
|
@@ -14,7 +15,7 @@ var TableCell = (props) => {
|
|
|
14
15
|
const rootClassName = clsx(Table_module_default.cell, horizontalAlign !== "start" && Table_module_default[`horizontal-align-${horizontalAlign}`], className);
|
|
15
16
|
const content = /* @__PURE__ */ jsx(Suspense, {
|
|
16
17
|
fallback: /* @__PURE__ */ jsx(SkeletonText, { width: "100px" }),
|
|
17
|
-
children
|
|
18
|
+
children: /* @__PURE__ */ jsx(SkeletonRawText, { children })
|
|
18
19
|
});
|
|
19
20
|
if (rowHeader) return /* @__PURE__ */ jsx(TableColumn, {
|
|
20
21
|
className: rootClassName,
|
package/dist/js/packages/components/src/components/Table/components/TableCell/TableCell.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TableCell.mjs","names":["styles"],"sources":["../../../../../../../../../src/components/Table/components/TableCell/TableCell.tsx"],"sourcesContent":["import type { FC, PropsWithChildren } from \"react\";\nimport { Suspense } from \"react\";\nimport * as Aria from \"react-aria-components\";\nimport clsx from \"clsx\";\nimport styles from \"../../Table.module.scss\";\nimport { SkeletonText } from \"@/components/SkeletonText\";\nimport { TableColumn } from \"@/components/Table/components/TableColumn/TableColumn\";\n\nexport interface TableCellProps\n extends\n Omit<Aria.CellProps, \"children\" | \"style\" | \"render\">,\n PropsWithChildren {\n /** Use cell as row header */\n rowHeader?: boolean;\n /** Horizontal alignment of the cell content @default \"start\" */\n horizontalAlign?: \"start\" | \"center\" | \"end\";\n}\n\n/** @flr-generate all */\nexport const TableCell: FC<TableCellProps> = (props) => {\n const {\n children,\n className,\n rowHeader,\n horizontalAlign = \"start\",\n ...rest\n } = props;\n\n const rootClassName = clsx(\n styles.cell,\n horizontalAlign !== \"start\" &&\n styles[`horizontal-align-${horizontalAlign}`],\n className,\n );\n\n const content = (\n <Suspense fallback={<SkeletonText width=\"100px\" />}>{children}</Suspense>\n );\n\n if (rowHeader) {\n return (\n <TableColumn className={rootClassName} {...rest}>\n {content}\n </TableColumn>\n );\n }\n\n return (\n <Aria.Cell className={rootClassName} {...rest}>\n {content}\n </Aria.Cell>\n );\n};\n\nexport default TableCell;\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"TableCell.mjs","names":["styles"],"sources":["../../../../../../../../../src/components/Table/components/TableCell/TableCell.tsx"],"sourcesContent":["import type { FC, PropsWithChildren } from \"react\";\nimport { Suspense } from \"react\";\nimport * as Aria from \"react-aria-components\";\nimport clsx from \"clsx\";\nimport styles from \"../../Table.module.scss\";\nimport { SkeletonText } from \"@/components/SkeletonText\";\nimport { TableColumn } from \"@/components/Table/components/TableColumn/TableColumn\";\nimport { SkeletonRawText } from \"@/components/SkeletonMode/components/SkeletonRawText\";\n\nexport interface TableCellProps\n extends\n Omit<Aria.CellProps, \"children\" | \"style\" | \"render\">,\n PropsWithChildren {\n /** Use cell as row header */\n rowHeader?: boolean;\n /** Horizontal alignment of the cell content @default \"start\" */\n horizontalAlign?: \"start\" | \"center\" | \"end\";\n}\n\n/** @flr-generate all */\nexport const TableCell: FC<TableCellProps> = (props) => {\n const {\n children,\n className,\n rowHeader,\n horizontalAlign = \"start\",\n ...rest\n } = props;\n\n const rootClassName = clsx(\n styles.cell,\n horizontalAlign !== \"start\" &&\n styles[`horizontal-align-${horizontalAlign}`],\n className,\n );\n\n const content = (\n <Suspense fallback={<SkeletonText width=\"100px\" />}>\n <SkeletonRawText>{children}</SkeletonRawText>\n </Suspense>\n );\n\n if (rowHeader) {\n return (\n <TableColumn className={rootClassName} {...rest}>\n {content}\n </TableColumn>\n );\n }\n\n return (\n <Aria.Cell className={rootClassName} {...rest}>\n {content}\n </Aria.Cell>\n );\n};\n\nexport default TableCell;\n"],"mappings":";;;;;;;;;;;;AAoBA,IAAa,aAAiC,UAAU;CACtD,MAAM,EACJ,UACA,WACA,WACA,kBAAkB,SAClB,GAAG,SACD;CAEJ,MAAM,gBAAgB,KACpBA,qBAAO,MACP,oBAAoB,WAClBA,qBAAO,oBAAoB,oBAC7B,SACF;CAEA,MAAM,UACJ,oBAAC,UAAD;EAAU,UAAU,oBAAC,cAAD,EAAc,OAAM,QAAS,CAAA;EAC/C,UAAA,oBAAC,iBAAD,EAAkB,SAA0B,CAAA;CACpC,CAAA;CAGZ,IAAI,WACF,OACE,oBAAC,aAAD;EAAa,WAAW;EAAe,GAAI;EACxC,UAAA;CACU,CAAA;CAIjB,OACE,oBAAC,KAAK,MAAN;EAAW,WAAW;EAAe,GAAI;EACtC,UAAA;CACQ,CAAA;AAEf"}
|
package/dist/js/packages/components/src/components/Table/components/TableColumn/TableColumn.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
/* */
|
|
3
3
|
import { PropsContextProvider } from "../../../../lib/propsContext/components/PropsContextProvider.mjs";
|
|
4
|
+
import { SkeletonRawText } from "../../../SkeletonMode/components/SkeletonRawText/SkeletonRawText.mjs";
|
|
4
5
|
import Table_module_default from "../../Table.module.mjs";
|
|
5
6
|
import clsx from "clsx";
|
|
6
7
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -21,7 +22,7 @@ var TableColumn = (props) => {
|
|
|
21
22
|
},
|
|
22
23
|
children: /* @__PURE__ */ jsx(PropsContextProvider, {
|
|
23
24
|
props: propsContext,
|
|
24
|
-
children
|
|
25
|
+
children: /* @__PURE__ */ jsx(SkeletonRawText, { children })
|
|
25
26
|
})
|
|
26
27
|
});
|
|
27
28
|
};
|
package/dist/js/packages/components/src/components/Table/components/TableColumn/TableColumn.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TableColumn.mjs","names":["styles"],"sources":["../../../../../../../../../src/components/Table/components/TableColumn/TableColumn.tsx"],"sourcesContent":["import type { FC, PropsWithChildren } from \"react\";\nimport * as Aria from \"react-aria-components\";\nimport clsx from \"clsx\";\nimport styles from \"../../Table.module.scss\";\nimport { type PropsContext, PropsContextProvider } from \"@/lib/propsContext\";\n\nexport interface TableColumnProps\n extends\n Omit<\n Aria.ColumnProps,\n \"children\" | \"width\" | \"minWidth\" | \"maxWidth\" | \"style\"\n >,\n PropsWithChildren {\n /** Horizontal alignment of the cell content @default \"start\" */\n horizontalAlign?: \"start\" | \"center\" | \"end\";\n /** The width of the column. */\n width?: number | string;\n /** The minimum width of the column. */\n minWidth?: number | string;\n}\n\n/** @flr-generate all */\nexport const TableColumn: FC<TableColumnProps> = (props) => {\n const {\n children,\n className,\n horizontalAlign = \"start\",\n width,\n minWidth,\n ...rest\n } = props;\n const rootClassName = clsx(\n styles.column,\n horizontalAlign !== \"start\" &&\n styles[`horizontal-align-${horizontalAlign}`],\n className,\n );\n\n const propsContext: PropsContext = { Checkbox: { slot: null } };\n\n return (\n <Aria.Column\n isRowHeader\n className={rootClassName}\n {...rest}\n style={{ width, minWidth }}\n >\n <PropsContextProvider props={propsContext}>\n {children}
|
|
1
|
+
{"version":3,"file":"TableColumn.mjs","names":["styles"],"sources":["../../../../../../../../../src/components/Table/components/TableColumn/TableColumn.tsx"],"sourcesContent":["import type { FC, PropsWithChildren } from \"react\";\nimport * as Aria from \"react-aria-components\";\nimport clsx from \"clsx\";\nimport styles from \"../../Table.module.scss\";\nimport { type PropsContext, PropsContextProvider } from \"@/lib/propsContext\";\nimport { SkeletonRawText } from \"@/components/SkeletonMode/components/SkeletonRawText\";\n\nexport interface TableColumnProps\n extends\n Omit<\n Aria.ColumnProps,\n \"children\" | \"width\" | \"minWidth\" | \"maxWidth\" | \"style\"\n >,\n PropsWithChildren {\n /** Horizontal alignment of the cell content @default \"start\" */\n horizontalAlign?: \"start\" | \"center\" | \"end\";\n /** The width of the column. */\n width?: number | string;\n /** The minimum width of the column. */\n minWidth?: number | string;\n}\n\n/** @flr-generate all */\nexport const TableColumn: FC<TableColumnProps> = (props) => {\n const {\n children,\n className,\n horizontalAlign = \"start\",\n width,\n minWidth,\n ...rest\n } = props;\n const rootClassName = clsx(\n styles.column,\n horizontalAlign !== \"start\" &&\n styles[`horizontal-align-${horizontalAlign}`],\n className,\n );\n\n const propsContext: PropsContext = { Checkbox: { slot: null } };\n\n return (\n <Aria.Column\n isRowHeader\n className={rootClassName}\n {...rest}\n style={{ width, minWidth }}\n >\n <PropsContextProvider props={propsContext}>\n <SkeletonRawText>{children}</SkeletonRawText>\n </PropsContextProvider>\n </Aria.Column>\n );\n};\n\nexport default TableColumn;\n"],"mappings":";;;;;;;;;;AAuBA,IAAa,eAAqC,UAAU;CAC1D,MAAM,EACJ,UACA,WACA,kBAAkB,SAClB,OACA,UACA,GAAG,SACD;CACJ,MAAM,gBAAgB,KACpBA,qBAAO,QACP,oBAAoB,WAClBA,qBAAO,oBAAoB,oBAC7B,SACF;CAEA,MAAM,eAA6B,EAAE,UAAU,EAAE,MAAM,KAAK,EAAE;CAE9D,OACE,oBAAC,KAAK,QAAN;EACE,aAAA;EACA,WAAW;EACX,GAAI;EACJ,OAAO;GAAE;GAAO;EAAS;EAEzB,UAAA,oBAAC,sBAAD;GAAsB,OAAO;GAC3B,UAAA,oBAAC,iBAAD,EAAkB,SAA0B,CAAA;EACxB,CAAA;CACX,CAAA;AAEjB"}
|
package/dist/js/packages/components/src/integrations/react-hook-form/components/Field/Field.mjs
CHANGED
|
@@ -75,7 +75,6 @@ function Field(props) {
|
|
|
75
75
|
return /* @__PURE__ */ jsxs(Fragment$1, { children: [p.children, /* @__PURE__ */ jsx(FieldErrorView, { children: controller.fieldState.error?.message })] });
|
|
76
76
|
})
|
|
77
77
|
};
|
|
78
|
-
const { isDisabled: ignoredIsDisabled, ...codeEditorFieldProps } = fieldProps;
|
|
79
78
|
const propsContext = {
|
|
80
79
|
Autocomplete: {
|
|
81
80
|
SearchField: fieldProps,
|
|
@@ -85,7 +84,7 @@ function Field(props) {
|
|
|
85
84
|
TextField: fieldProps,
|
|
86
85
|
TextArea: fieldProps,
|
|
87
86
|
MarkdownEditor: fieldProps,
|
|
88
|
-
CodeEditor:
|
|
87
|
+
CodeEditor: fieldProps,
|
|
89
88
|
Checkbox: {
|
|
90
89
|
...fieldProps,
|
|
91
90
|
isSelected: value
|
package/dist/js/packages/components/src/integrations/react-hook-form/components/Field/Field.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Field.mjs","names":["locales","_Fragment"],"sources":["../../../../../../../../../src/integrations/react-hook-form/components/Field/Field.tsx"],"sourcesContent":["import { useFormContext } from \"@/integrations/react-hook-form/components/FormContextProvider/FormContextProvider\";\nimport {\n dynamic,\n type PropsContext,\n PropsContextProvider,\n} from \"@/lib/propsContext\";\nimport { type PropsWithChildren } from \"react\";\nimport {\n type ControllerProps,\n type FieldValues,\n useController,\n type UseFormReturn,\n useWatch,\n} from \"react-hook-form\";\nimport { useLocalizedStringFormatter } from \"@/components/TranslationProvider/useLocalizedStringFormatter\";\nimport locales from \"./locales/*.locale.json\";\nimport FieldErrorView from \"@/views/FieldErrorView\";\nimport { useUpdateFormDefaultValue } from \"@/integrations/react-hook-form/components/Field/hooks/useUpdateFormDefaultValue\";\nimport type {\n FlowComponentName,\n FlowComponentPropName,\n} from \"@/components/propTypes\";\n\ntype DisableableComponentName = {\n [C in FlowComponentName]: \"isDisabled\" extends FlowComponentPropName<C>\n ? C\n : never;\n}[FlowComponentName];\n\nexport interface FieldProps<T extends FieldValues>\n extends Omit<ControllerProps<T>, \"render\">, PropsWithChildren {}\n\nexport function Field<T extends FieldValues>(props: FieldProps<T>) {\n const { children, name, defaultValue, ...rest } = props;\n\n const stringFormatter = useLocalizedStringFormatter(\n locales,\n \"ReactHookForm.Field\",\n );\n\n const controller = useController({\n ...props,\n rules: {\n ...props.rules,\n min:\n typeof rest.rules?.min === \"number\"\n ? {\n value: rest.rules.min,\n message: stringFormatter.format(\"validation.min\", {\n number: rest.rules.min,\n }),\n }\n : rest.rules?.min,\n max:\n typeof rest.rules?.max === \"number\"\n ? {\n value: rest.rules.max,\n message: stringFormatter.format(\"validation.max\", {\n number: rest.rules.max,\n }),\n }\n : rest.rules?.max,\n required:\n typeof rest.rules?.required === \"boolean\"\n ? stringFormatter.format(\"validation.required\")\n : rest.rules?.required,\n pattern:\n rest.rules?.pattern instanceof RegExp\n ? {\n value: rest.rules.pattern,\n message: stringFormatter.format(\"validation.pattern\", {\n pattern: rest.rules.pattern.source,\n }),\n }\n : rest.rules?.pattern,\n minLength:\n typeof rest.rules?.minLength === \"number\"\n ? {\n value: rest.rules.minLength,\n message: stringFormatter.format(\"validation.minLength\", {\n number: rest.rules.minLength,\n }),\n }\n : rest.rules?.minLength,\n maxLength:\n typeof rest.rules?.maxLength === \"number\"\n ? {\n value: rest.rules.maxLength,\n message: stringFormatter.format(\"validation.maxLength\", {\n number: rest.rules.maxLength,\n }),\n }\n : rest.rules?.maxLength,\n },\n });\n const formContext = useFormContext<T>();\n\n useUpdateFormDefaultValue(props, formContext.form);\n\n /**\n * We don't use controller.field.value here, because it doesn't update when\n * the form value is updated outside of this field (e.g. when setting values\n * with form.setValue or resetting the form), and the Field unmounts in\n * between. This is generally a feature of React Hook Form, but this breaks\n * dynamic forms where fields are conditionally rendered.\n *\n * By using formContext.form.watch(name), we ensure that the field value is\n * always in sync with the form state. See:\n * https://react-hook-form.com/api/usecontroller/controller/\n */\n const value =\n useWatch({\n control: formContext.form.control,\n name,\n }) ?? controller.field.value;\n\n const isFieldInvalid = controller.fieldState.invalid;\n\n const { disabled, ...controllerFieldProps } = controller.field;\n\n const fieldProps = {\n ...controllerFieldProps,\n // Dynamic, so a local `isDisabled={false}` cannot enable a field whose\n // value React Hook Form drops on submit\n ...(disabled && {\n isDisabled: dynamic<DisableableComponentName, \"isDisabled\">(() => true),\n }),\n value,\n name,\n form: formContext.id,\n isRequired: !!rest.rules?.required,\n isReadOnly: formContext.isReadOnly,\n validationBehavior: \"aria\" as const,\n defaultValue,\n isInvalid: isFieldInvalid,\n children: dynamic((p) => {\n return (\n <>\n {p.children}\n <FieldErrorView>\n {controller.fieldState.error?.message}\n </FieldErrorView>\n </>\n );\n }),\n };\n\n
|
|
1
|
+
{"version":3,"file":"Field.mjs","names":["locales","_Fragment"],"sources":["../../../../../../../../../src/integrations/react-hook-form/components/Field/Field.tsx"],"sourcesContent":["import { useFormContext } from \"@/integrations/react-hook-form/components/FormContextProvider/FormContextProvider\";\nimport {\n dynamic,\n type PropsContext,\n PropsContextProvider,\n} from \"@/lib/propsContext\";\nimport { type PropsWithChildren } from \"react\";\nimport {\n type ControllerProps,\n type FieldValues,\n useController,\n type UseFormReturn,\n useWatch,\n} from \"react-hook-form\";\nimport { useLocalizedStringFormatter } from \"@/components/TranslationProvider/useLocalizedStringFormatter\";\nimport locales from \"./locales/*.locale.json\";\nimport FieldErrorView from \"@/views/FieldErrorView\";\nimport { useUpdateFormDefaultValue } from \"@/integrations/react-hook-form/components/Field/hooks/useUpdateFormDefaultValue\";\nimport type {\n FlowComponentName,\n FlowComponentPropName,\n} from \"@/components/propTypes\";\n\ntype DisableableComponentName = {\n [C in FlowComponentName]: \"isDisabled\" extends FlowComponentPropName<C>\n ? C\n : never;\n}[FlowComponentName];\n\nexport interface FieldProps<T extends FieldValues>\n extends Omit<ControllerProps<T>, \"render\">, PropsWithChildren {}\n\nexport function Field<T extends FieldValues>(props: FieldProps<T>) {\n const { children, name, defaultValue, ...rest } = props;\n\n const stringFormatter = useLocalizedStringFormatter(\n locales,\n \"ReactHookForm.Field\",\n );\n\n const controller = useController({\n ...props,\n rules: {\n ...props.rules,\n min:\n typeof rest.rules?.min === \"number\"\n ? {\n value: rest.rules.min,\n message: stringFormatter.format(\"validation.min\", {\n number: rest.rules.min,\n }),\n }\n : rest.rules?.min,\n max:\n typeof rest.rules?.max === \"number\"\n ? {\n value: rest.rules.max,\n message: stringFormatter.format(\"validation.max\", {\n number: rest.rules.max,\n }),\n }\n : rest.rules?.max,\n required:\n typeof rest.rules?.required === \"boolean\"\n ? stringFormatter.format(\"validation.required\")\n : rest.rules?.required,\n pattern:\n rest.rules?.pattern instanceof RegExp\n ? {\n value: rest.rules.pattern,\n message: stringFormatter.format(\"validation.pattern\", {\n pattern: rest.rules.pattern.source,\n }),\n }\n : rest.rules?.pattern,\n minLength:\n typeof rest.rules?.minLength === \"number\"\n ? {\n value: rest.rules.minLength,\n message: stringFormatter.format(\"validation.minLength\", {\n number: rest.rules.minLength,\n }),\n }\n : rest.rules?.minLength,\n maxLength:\n typeof rest.rules?.maxLength === \"number\"\n ? {\n value: rest.rules.maxLength,\n message: stringFormatter.format(\"validation.maxLength\", {\n number: rest.rules.maxLength,\n }),\n }\n : rest.rules?.maxLength,\n },\n });\n const formContext = useFormContext<T>();\n\n useUpdateFormDefaultValue(props, formContext.form);\n\n /**\n * We don't use controller.field.value here, because it doesn't update when\n * the form value is updated outside of this field (e.g. when setting values\n * with form.setValue or resetting the form), and the Field unmounts in\n * between. This is generally a feature of React Hook Form, but this breaks\n * dynamic forms where fields are conditionally rendered.\n *\n * By using formContext.form.watch(name), we ensure that the field value is\n * always in sync with the form state. See:\n * https://react-hook-form.com/api/usecontroller/controller/\n */\n const value =\n useWatch({\n control: formContext.form.control,\n name,\n }) ?? controller.field.value;\n\n const isFieldInvalid = controller.fieldState.invalid;\n\n const { disabled, ...controllerFieldProps } = controller.field;\n\n const fieldProps = {\n ...controllerFieldProps,\n // Dynamic, so a local `isDisabled={false}` cannot enable a field whose\n // value React Hook Form drops on submit\n ...(disabled && {\n isDisabled: dynamic<DisableableComponentName, \"isDisabled\">(() => true),\n }),\n value,\n name,\n form: formContext.id,\n isRequired: !!rest.rules?.required,\n isReadOnly: formContext.isReadOnly,\n validationBehavior: \"aria\" as const,\n defaultValue,\n isInvalid: isFieldInvalid,\n children: dynamic((p) => {\n return (\n <>\n {p.children}\n <FieldErrorView>\n {controller.fieldState.error?.message}\n </FieldErrorView>\n </>\n );\n }),\n };\n\n const propsContext: PropsContext = {\n Autocomplete: {\n SearchField: fieldProps,\n TextField: fieldProps,\n },\n SearchField: fieldProps,\n TextField: fieldProps,\n TextArea: fieldProps,\n MarkdownEditor: fieldProps,\n CodeEditor: fieldProps,\n Checkbox: {\n ...fieldProps,\n isSelected: value,\n },\n CheckboxGroup: {\n ...fieldProps,\n },\n CheckboxButton: {\n ...fieldProps,\n isSelected: value,\n },\n FileField: fieldProps,\n FileDropZone: fieldProps,\n NumberField: fieldProps,\n RadioGroup: fieldProps,\n Switch: {\n ...fieldProps,\n isSelected: value,\n },\n Slider: fieldProps,\n PasswordCreationField: fieldProps,\n DatePicker: fieldProps,\n DateRangePicker: fieldProps,\n TimeField: fieldProps,\n SegmentedControl: fieldProps,\n Select: {\n ...fieldProps,\n selectedKey: value,\n },\n ComboBox: {\n ...fieldProps,\n selectedKey: value,\n },\n Rating: fieldProps,\n };\n\n return (\n <PropsContextProvider\n props={propsContext}\n dependencies={[\n controller.fieldState,\n controller.field,\n value,\n formContext.isReadOnly,\n ]}\n >\n {children}\n </PropsContextProvider>\n );\n}\n\nexport const typedField = <T extends FieldValues>(\n ignoredForm: UseFormReturn<T> | UseFormReturn<T>[\"control\"],\n): typeof Field<T> => Field;\n\nexport default Field;\n"],"mappings":"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"}
|
|
@@ -3,5 +3,7 @@ import { DonutChartProps } from '..';
|
|
|
3
3
|
interface Props extends Pick<DonutChartProps, "segments" | "size" | "maxValue"> {
|
|
4
4
|
value?: number;
|
|
5
5
|
}
|
|
6
|
+
/** The width and height of the rendered donut in px. */
|
|
7
|
+
export declare const getDonutSize: (size: DonutChartProps["size"]) => number;
|
|
6
8
|
export declare const Donut: FC<Props>;
|
|
7
9
|
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FC, PropsWithChildren } from 'react';
|
|
2
|
+
import { TextProps } from '../../Text';
|
|
3
|
+
/**
|
|
4
|
+
* A text bar is an inline element and cannot wrap blocks. Markdown puts lists
|
|
5
|
+
* and quotes into a `Text`, so in `SkeletonMode` this `Text` renders as real
|
|
6
|
+
* text, and the blocks inside follow the skeleton rules on their own.
|
|
7
|
+
*/
|
|
8
|
+
export declare const SkeletonBlockText: FC<TextProps>;
|
|
9
|
+
/**
|
|
10
|
+
* The content of a list item or a table cell: each run of inline content
|
|
11
|
+
* becomes one text bar, blocks inside — a nested list, the paragraphs of a
|
|
12
|
+
* loose list — keep their own skeleton rules. Outside an enabled `SkeletonMode`
|
|
13
|
+
* it renders its children unchanged.
|
|
14
|
+
*/
|
|
15
|
+
export declare const SkeletonInlineContent: FC<PropsWithChildren>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mittwald/flow-react-components",
|
|
3
|
-
"version": "1.5.0-next.
|
|
3
|
+
"version": "1.5.0-next.48",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A React implementation of Flow, mittwald’s design system",
|
|
6
6
|
"homepage": "https://flow.mittwald.de",
|
|
@@ -84,9 +84,9 @@
|
|
|
84
84
|
"@internationalized/string-compiler": "^3.4.1",
|
|
85
85
|
"@lezer/common": "^1.5.2",
|
|
86
86
|
"@lezer/highlight": "^1.2.3",
|
|
87
|
-
"@mittwald/flow-icons": "^1.5.0-next.
|
|
87
|
+
"@mittwald/flow-icons": "^1.5.0-next.48",
|
|
88
88
|
"@mittwald/password-tools-js": "^3.0.0",
|
|
89
|
-
"@mittwald/react-tunnel": "^1.5.0-next.
|
|
89
|
+
"@mittwald/react-tunnel": "^1.5.0-next.48",
|
|
90
90
|
"@mittwald/react-use-promise": "^4.2.2",
|
|
91
91
|
"@react-aria/form": "^3.2.1",
|
|
92
92
|
"@react-aria/i18n": "^3.13.1",
|
|
@@ -139,12 +139,12 @@
|
|
|
139
139
|
"@internationalized/date": "^3.12.3",
|
|
140
140
|
"@lezer/generator": "^1.8.0",
|
|
141
141
|
"@lezer/lr": "^1.4.10",
|
|
142
|
-
"@mittwald/flow-core": "1.5.0-next.
|
|
143
|
-
"@mittwald/flow-design-tokens": "1.5.0-next.
|
|
144
|
-
"@mittwald/flow-icons-base": "1.5.0-next.
|
|
142
|
+
"@mittwald/flow-core": "1.5.0-next.48",
|
|
143
|
+
"@mittwald/flow-design-tokens": "1.5.0-next.48",
|
|
144
|
+
"@mittwald/flow-icons-base": "1.5.0-next.48",
|
|
145
145
|
"@mittwald/react-use-promise": "^4.2.2",
|
|
146
146
|
"@mittwald/remote-dom-react": "1.2.2-mittwald.10",
|
|
147
|
-
"@mittwald/typescript-config": "1.5.0-next.
|
|
147
|
+
"@mittwald/typescript-config": "1.5.0-next.48",
|
|
148
148
|
"@nx/storybook": "^22.7.6",
|
|
149
149
|
"@storybook/addon-a11y": "^10.5.10",
|
|
150
150
|
"@storybook/addon-actions": "^9.0.8",
|
|
@@ -198,7 +198,7 @@
|
|
|
198
198
|
},
|
|
199
199
|
"peerDependencies": {
|
|
200
200
|
"@internationalized/date": "^3.12.2",
|
|
201
|
-
"@mittwald/flow-icons-pro": "1.5.0-next.
|
|
201
|
+
"@mittwald/flow-icons-pro": "1.5.0-next.48",
|
|
202
202
|
"@mittwald/react-use-promise": "^4.2.2",
|
|
203
203
|
"next": "^16.2.3",
|
|
204
204
|
"react": "^19.2.0",
|
|
@@ -222,5 +222,5 @@
|
|
|
222
222
|
"browserslist": [
|
|
223
223
|
"baseline widely available"
|
|
224
224
|
],
|
|
225
|
-
"gitHead": "
|
|
225
|
+
"gitHead": "46076de9b84cd055c3fdffa5d043a0ffcc76195e"
|
|
226
226
|
}
|