@mittwald/flow-react-components 1.5.0-next.1 → 1.5.0-next.2

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.
@@ -93,7 +93,6 @@ var MarkdownEditor = flowComponent("MarkdownEditor", (props) => {
93
93
  mode === "preview" && /* @__PURE__ */ jsx(MarkdownComponent, {
94
94
  headingOffset,
95
95
  className: MarkdownEditor_module_default.markdown,
96
- style: { height: inputRef.current?.offsetHeight },
97
96
  children: value
98
97
  }),
99
98
  /* @__PURE__ */ jsx(Toolbar, {
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownEditor.mjs","names":[],"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 {...dropProps} className={rootClassName}>\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 style={{\n height: inputRef.current?.offsetHeight,\n }}\n >\n {value}\n </MarkdownComponent>\n )}\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 </PropsContextProvider>\n </TextArea>\n </div>\n );\n});\n\nexport default MarkdownEditor;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAgCA,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,oBAAoB,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,gBAAgB,KACpB,8BAAO,gBACP,8BAAO,QAAQ,SACf,gBAAgB,8BAAO,YACvB,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,oBAAC,OAAD;EAAK,GAAI;EAAW,WAAW;EAC7B,UAAA,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,WAAW,8BAAO;MAClB,OAAO,EACL,QAAQ,SAAS,SAAS,aAC5B;MAEC,UAAA;KACgB,CAAA;KAErB,oBAAC,SAAD;MACE,aAAa;MACD;MACZ,cAAc;MACd,eAAe;MACP;MACI;MACZ,iBAAiB;KAClB,CAAA;IACmB;;EACd,CAAA;CACP,CAAA;AAET,CAAC"}
1
+ {"version":3,"file":"MarkdownEditor.mjs","names":[],"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 {...dropProps} className={rootClassName}>\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 <Toolbar\n currentMode={mode}\n isDisabled={isDisabled}\n onModeChange={setMode}\n onToolPressed={handleToolButtonPressed}\n accept={accept}\n isReadOnly={isReadOnly}\n onFilesSelected={uploadFiles}\n />\n </PropsContextProvider>\n </TextArea>\n </div>\n );\n});\n\nexport default MarkdownEditor;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAgCA,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,oBAAoB,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,gBAAgB,KACpB,8BAAO,gBACP,8BAAO,QAAQ,SACf,gBAAgB,8BAAO,YACvB,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,oBAAC,OAAD;EAAK,GAAI;EAAW,WAAW;EAC7B,UAAA,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,WAAW,8BAAO;MAEjB,UAAA;KACgB,CAAA;KAErB,oBAAC,SAAD;MACE,aAAa;MACD;MACZ,cAAc;MACd,eAAe;MACP;MACI;MACZ,iBAAiB;KAClB,CAAA;IACmB;;EACd,CAAA;CACP,CAAA;AAET,CAAC"}
@@ -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 &.mode-preview {\n :global(.flow--text-area--input) {\n position: absolute;\n opacity: 0;\n pointer-events: none;\n width: 1px;\n height: 1px;\n inset-inline-start: 0;\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\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":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mittwald/flow-react-components",
3
- "version": "1.5.0-next.1",
3
+ "version": "1.5.0-next.2",
4
4
  "type": "module",
5
5
  "description": "A React implementation of Flow, mittwald’s design system",
6
6
  "homepage": "https://flow.mittwald.de",
@@ -83,9 +83,9 @@
83
83
  "@internationalized/string-compiler": "^3.4.1",
84
84
  "@lezer/common": "^1.5.2",
85
85
  "@lezer/highlight": "^1.2.3",
86
- "@mittwald/flow-icons": "^1.5.0-next.1",
86
+ "@mittwald/flow-icons": "^1.5.0-next.2",
87
87
  "@mittwald/password-tools-js": "^3.0.0",
88
- "@mittwald/react-tunnel": "^1.5.0-next.1",
88
+ "@mittwald/react-tunnel": "^1.5.0-next.2",
89
89
  "@mittwald/react-use-promise": "^4.2.2",
90
90
  "@react-aria/form": "^3.2.1",
91
91
  "@react-aria/i18n": "^3.13.1",
@@ -138,12 +138,12 @@
138
138
  "@internationalized/date": "^3.12.3",
139
139
  "@lezer/generator": "^1.8.0",
140
140
  "@lezer/lr": "^1.4.10",
141
- "@mittwald/flow-core": "1.5.0-next.1",
142
- "@mittwald/flow-design-tokens": "1.5.0-next.1",
143
- "@mittwald/flow-icons-base": "1.5.0-next.1",
141
+ "@mittwald/flow-core": "1.5.0-next.2",
142
+ "@mittwald/flow-design-tokens": "1.5.0-next.2",
143
+ "@mittwald/flow-icons-base": "1.5.0-next.2",
144
144
  "@mittwald/react-use-promise": "^4.2.2",
145
145
  "@mittwald/remote-dom-react": "1.2.2-mittwald.10",
146
- "@mittwald/typescript-config": "1.5.0-next.1",
146
+ "@mittwald/typescript-config": "1.5.0-next.2",
147
147
  "@nx/storybook": "^22.7.6",
148
148
  "@storybook/addon-a11y": "^10.5.10",
149
149
  "@storybook/addon-actions": "^9.0.8",
@@ -195,7 +195,7 @@
195
195
  },
196
196
  "peerDependencies": {
197
197
  "@internationalized/date": "^3.12.2",
198
- "@mittwald/flow-icons-pro": "1.5.0-next.1",
198
+ "@mittwald/flow-icons-pro": "1.5.0-next.2",
199
199
  "@mittwald/react-use-promise": "^4.2.2",
200
200
  "next": "^16.2.3",
201
201
  "react": "^19.2.0",
@@ -219,5 +219,5 @@
219
219
  "browserslist": [
220
220
  "baseline widely available"
221
221
  ],
222
- "gitHead": "960225094d5ee4e519ccdd7020d4dd138fa3bceb"
222
+ "gitHead": "a1b587c6c7bab8380d608aaed55331348f36d3d8"
223
223
  }