@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,5 +1,6 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
/* */
|
|
3
|
+
import { SkeletonModeReset, useSkeletonMode } from "../SkeletonMode/skeletonModeContext.mjs";
|
|
3
4
|
import Calendar_module_default from "./Calendar.module.mjs";
|
|
4
5
|
import { CalendarHeader } from "./components/CalendarHeader/CalendarHeader.mjs";
|
|
5
6
|
import clsx from "clsx";
|
|
@@ -8,13 +9,15 @@ import * as Aria from "react-aria-components";
|
|
|
8
9
|
//#region src/components/Calendar/Calendar.tsx
|
|
9
10
|
var Calendar = (props) => {
|
|
10
11
|
const { className } = props;
|
|
11
|
-
const
|
|
12
|
-
|
|
12
|
+
const isSkeleton = useSkeletonMode();
|
|
13
|
+
const rootClassName = clsx(Calendar_module_default.calendar, isSkeleton && Calendar_module_default.skeleton, className);
|
|
14
|
+
return /* @__PURE__ */ jsx(Aria.Calendar, {
|
|
13
15
|
className: rootClassName,
|
|
14
|
-
|
|
16
|
+
inert: isSkeleton || void 0,
|
|
17
|
+
children: /* @__PURE__ */ jsxs(SkeletonModeReset, { children: [/* @__PURE__ */ jsx(CalendarHeader, {}), /* @__PURE__ */ jsx(Aria.CalendarGrid, {
|
|
15
18
|
weekdayStyle: "short",
|
|
16
19
|
children: (date) => /* @__PURE__ */ jsx(Aria.CalendarCell, { date })
|
|
17
|
-
})]
|
|
20
|
+
})] })
|
|
18
21
|
});
|
|
19
22
|
};
|
|
20
23
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Calendar.mjs","names":["styles"],"sources":["../../../../../../../src/components/Calendar/Calendar.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport * as Aria from \"react-aria-components\";\nimport styles from \"@/components/Calendar/Calendar.module.scss\";\nimport CalendarHeader from \"./components/CalendarHeader\";\nimport type { PropsWithClassName } from \"@/lib/types/props\";\nimport clsx from \"clsx\";\n\nexport const Calendar: FC<PropsWithClassName> = (props) => {\n const { className } = props;\n\n const rootClassName = clsx(styles.calendar
|
|
1
|
+
{"version":3,"file":"Calendar.mjs","names":["styles"],"sources":["../../../../../../../src/components/Calendar/Calendar.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport * as Aria from \"react-aria-components\";\nimport styles from \"@/components/Calendar/Calendar.module.scss\";\nimport CalendarHeader from \"./components/CalendarHeader\";\nimport type { PropsWithClassName } from \"@/lib/types/props\";\nimport clsx from \"clsx\";\nimport {\n SkeletonModeReset,\n useSkeletonMode,\n} from \"@/components/SkeletonMode/skeletonModeContext\";\n\nexport const Calendar: FC<PropsWithClassName> = (props) => {\n const { className } = props;\n\n const isSkeleton = useSkeletonMode();\n\n const rootClassName = clsx(\n styles.calendar,\n isSkeleton && styles.skeleton,\n className,\n );\n\n return (\n <Aria.Calendar className={rootClassName} inert={isSkeleton || undefined}>\n {/* The calendar is one skeleton surface, its content draws none. */}\n <SkeletonModeReset>\n <CalendarHeader />\n <Aria.CalendarGrid weekdayStyle=\"short\">\n {(date) => <Aria.CalendarCell date={date} />}\n </Aria.CalendarGrid>\n </SkeletonModeReset>\n </Aria.Calendar>\n );\n};\n\nexport default Calendar;\n"],"mappings":";;;;;;;;;AAWA,IAAa,YAAoC,UAAU;CACzD,MAAM,EAAE,cAAc;CAEtB,MAAM,aAAa,gBAAgB;CAEnC,MAAM,gBAAgB,KACpBA,wBAAO,UACP,cAAcA,wBAAO,UACrB,SACF;CAEA,OACE,oBAAC,KAAK,UAAN;EAAe,WAAW;EAAe,OAAO,cAAc,KAAA;EAE5D,UAAA,qBAAC,mBAAD,EAAA,UAAA,CACE,oBAAC,gBAAD,CAAiB,CAAA,GACjB,oBAAC,KAAK,cAAN;GAAmB,cAAa;GAC5B,WAAA,SAAS,oBAAC,KAAK,cAAN,EAAyB,KAAO,CAAA;EAC1B,CAAA,CACF,EAAA,CAAA;CACN,CAAA;AAEnB"}
|
|
@@ -7,15 +7,19 @@ var container = "flow--calendar--container";
|
|
|
7
7
|
var presetMenu = "flow--calendar--preset-menu";
|
|
8
8
|
var presetSeparator = "flow--calendar--preset-separator";
|
|
9
9
|
var range = "flow--calendar--range";
|
|
10
|
+
var skeleton = "flow--calendar--skeleton";
|
|
10
11
|
var Calendar_module_default = {
|
|
11
12
|
calendar,
|
|
12
13
|
calendarHeader,
|
|
13
14
|
container,
|
|
14
15
|
presetMenu,
|
|
15
16
|
presetSeparator,
|
|
16
|
-
range
|
|
17
|
+
range,
|
|
18
|
+
skeleton,
|
|
19
|
+
"skeleton-surface-shimmer": "flow--calendar--skeleton-surface-shimmer",
|
|
20
|
+
"skeleton-text-shimmer": "flow--calendar--skeleton-text-shimmer"
|
|
17
21
|
};
|
|
18
22
|
//#endregion
|
|
19
|
-
export { calendar, calendarHeader, container, Calendar_module_default as default, presetMenu, presetSeparator, range };
|
|
23
|
+
export { calendar, calendarHeader, container, Calendar_module_default as default, presetMenu, presetSeparator, range, skeleton };
|
|
20
24
|
|
|
21
25
|
//# sourceMappingURL=Calendar.module.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Calendar.module.mjs","names":[],"sources":["../../../../../../../src/components/Calendar/Calendar.module.scss"],"sourcesContent":["@use \"@/styles/mixins/focus\";\n\n.calendar {\n width: fit-content;\n\n .calendarHeader {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: var(--calendar--spacing);\n\n /* react-aria's Heading — CalendarHeader passes no className, so its\n default class is the handle. */\n :global(.react-aria-Heading) {\n font-size: var(--calendar--heading-font-size);\n }\n }\n\n .container {\n display: flex;\n flex-direction: row;\n gap: var(--popover--padding--m);\n\n .presetMenu {\n max-width: 200px;\n\n /*\n * With an auto width, WebKit resolved the menu one item padding wider on\n * every layout. Each reposition of the popover then resized it again,\n * inside react-aria's resize observer on the popover: a\n * \"ResizeObserver loop\" error per step.\n */\n width: max-content;\n }\n }\n\n @media (max-width: 530px) {\n .container {\n flex-direction: column-reverse;\n\n .presetMenu {\n width: auto;\n }\n\n /* The presets move below the grid, so the separator turns horizontal. */\n .presetSeparator {\n border-inline-end: 0;\n border-top: var(--separator--height) var(--separator--border-style)\n var(--separator--color);\n width: 100%;\n }\n }\n }\n\n :global(.react-aria-CalendarHeaderCell) {\n font-size: var(--calendar--cell-font-size);\n height: var(--calendar--cell-size);\n }\n\n :global(.react-aria-CalendarGrid) {\n border-spacing: var(--calendar--spacing);\n }\n\n :global(.react-aria-CalendarCell) {\n width: var(--calendar--cell-size);\n height: var(--calendar--cell-size);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: default;\n border-radius: var(--calendar--cell-corner-radius);\n font-size: var(--calendar--cell-font-size);\n transition-property: background-color;\n transition-duration: var(--transition--duration--default);\n\n @include focus.focus;\n\n &[data-outside-month] {\n display: none;\n }\n\n &:hover {\n background: var(--calendar--cell-background-color--hover);\n }\n\n &[data-pressed] {\n background: var(--calendar--cell-background-color--pressed);\n }\n\n &[data-selected] {\n background: var(--calendar--cell-background-color--selected);\n color: var(--calendar--cell-content-color--selected);\n }\n\n &[data-disabled],\n &[data-unavailable=\"true\"] {\n background: var(--calendar--cell-background-color--disabled);\n color: var(--calendar--cell-content-color--disabled);\n }\n\n @include focus.focus;\n }\n\n &.range {\n :global(.react-aria-CalendarCell) {\n position: relative;\n isolation: isolate;\n transition-duration: 0s;\n\n &[data-selected] {\n &::before {\n content: \"\";\n background: var(--calendar--range-background-color);\n border-block: var(--calendar--range-border-width)\n var(--calendar--range-border-style)\n var(--calendar--range-border-color);\n width: calc(100% + 0.375rem);\n height: 100%;\n position: absolute;\n z-index: -1;\n }\n\n &::after {\n content: \"\";\n width: 100%;\n height: 100%;\n position: absolute;\n z-index: -1;\n border-radius: var(--calendar--cell-corner-radius);\n }\n\n &:hover {\n &::after {\n background: var(--calendar--cell-background-color--hover);\n }\n }\n\n &[data-pressed] {\n &::after {\n background: var(--calendar--cell-background-color--pressed);\n }\n }\n\n &[data-selection-start],\n &[data-selection-end] {\n &::after {\n background: var(--calendar--cell-background-color--selected);\n }\n }\n\n &[data-selection-start] {\n &::before {\n border-start-start-radius: var(--calendar--cell-corner-radius);\n border-end-start-radius: var(--calendar--cell-corner-radius);\n inset-inline-start: 0;\n }\n }\n\n &[data-selection-end] {\n &::before {\n border-start-end-radius: var(--calendar--cell-corner-radius);\n border-end-end-radius: var(--calendar--cell-corner-radius);\n inset-inline-end: 0;\n }\n }\n\n &:not([data-selection-start], [data-selection-end]) {\n color: var(--text--color--default);\n background: none;\n }\n\n &[data-selection-start][data-selection-end] {\n &::before {\n display: none;\n }\n }\n }\n }\n }\n}\n\n@media (max-width: 360px) {\n .calendar {\n --calendar--cell-size: 2.1rem;\n --calendar--cell-font-size: 0.8rem;\n }\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"Calendar.module.mjs","names":[],"sources":["../../../../../../../src/components/Calendar/Calendar.module.scss"],"sourcesContent":["@use \"@/styles/mixins/focus\";\n@use \"@/styles/mixins/skeleton\";\n\n.calendar {\n width: fit-content;\n\n .calendarHeader {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: var(--calendar--spacing);\n\n /* react-aria's Heading — CalendarHeader passes no className, so its\n default class is the handle. */\n :global(.react-aria-Heading) {\n font-size: var(--calendar--heading-font-size);\n }\n }\n\n .container {\n display: flex;\n flex-direction: row;\n gap: var(--popover--padding--m);\n\n .presetMenu {\n max-width: 200px;\n\n /*\n * With an auto width, WebKit resolved the menu one item padding wider on\n * every layout. Each reposition of the popover then resized it again,\n * inside react-aria's resize observer on the popover: a\n * \"ResizeObserver loop\" error per step.\n */\n width: max-content;\n }\n }\n\n @media (max-width: 530px) {\n .container {\n flex-direction: column-reverse;\n\n .presetMenu {\n width: auto;\n }\n\n /* The presets move below the grid, so the separator turns horizontal. */\n .presetSeparator {\n border-inline-end: 0;\n border-top: var(--separator--height) var(--separator--border-style)\n var(--separator--color);\n width: 100%;\n }\n }\n }\n\n :global(.react-aria-CalendarHeaderCell) {\n font-size: var(--calendar--cell-font-size);\n height: var(--calendar--cell-size);\n }\n\n :global(.react-aria-CalendarGrid) {\n border-spacing: var(--calendar--spacing);\n }\n\n :global(.react-aria-CalendarCell) {\n width: var(--calendar--cell-size);\n height: var(--calendar--cell-size);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: default;\n border-radius: var(--calendar--cell-corner-radius);\n font-size: var(--calendar--cell-font-size);\n transition-property: background-color;\n transition-duration: var(--transition--duration--default);\n\n @include focus.focus;\n\n &[data-outside-month] {\n display: none;\n }\n\n &:hover {\n background: var(--calendar--cell-background-color--hover);\n }\n\n &[data-pressed] {\n background: var(--calendar--cell-background-color--pressed);\n }\n\n &[data-selected] {\n background: var(--calendar--cell-background-color--selected);\n color: var(--calendar--cell-content-color--selected);\n }\n\n &[data-disabled],\n &[data-unavailable=\"true\"] {\n background: var(--calendar--cell-background-color--disabled);\n color: var(--calendar--cell-content-color--disabled);\n }\n\n @include focus.focus;\n }\n\n &.range {\n :global(.react-aria-CalendarCell) {\n position: relative;\n isolation: isolate;\n transition-duration: 0s;\n\n &[data-selected] {\n &::before {\n content: \"\";\n background: var(--calendar--range-background-color);\n border-block: var(--calendar--range-border-width)\n var(--calendar--range-border-style)\n var(--calendar--range-border-color);\n width: calc(100% + 0.375rem);\n height: 100%;\n position: absolute;\n z-index: -1;\n }\n\n &::after {\n content: \"\";\n width: 100%;\n height: 100%;\n position: absolute;\n z-index: -1;\n border-radius: var(--calendar--cell-corner-radius);\n }\n\n &:hover {\n &::after {\n background: var(--calendar--cell-background-color--hover);\n }\n }\n\n &[data-pressed] {\n &::after {\n background: var(--calendar--cell-background-color--pressed);\n }\n }\n\n &[data-selection-start],\n &[data-selection-end] {\n &::after {\n background: var(--calendar--cell-background-color--selected);\n }\n }\n\n &[data-selection-start] {\n &::before {\n border-start-start-radius: var(--calendar--cell-corner-radius);\n border-end-start-radius: var(--calendar--cell-corner-radius);\n inset-inline-start: 0;\n }\n }\n\n &[data-selection-end] {\n &::before {\n border-start-end-radius: var(--calendar--cell-corner-radius);\n border-end-end-radius: var(--calendar--cell-corner-radius);\n inset-inline-end: 0;\n }\n }\n\n &:not([data-selection-start], [data-selection-end]) {\n color: var(--text--color--default);\n background: none;\n }\n\n &[data-selection-start][data-selection-end] {\n &::before {\n display: none;\n }\n }\n }\n }\n }\n\n /* SkeletonMode */\n\n &.skeleton {\n @include skeleton.shape;\n }\n}\n\n@include skeleton.keyframes;\n\n@media (max-width: 360px) {\n .calendar {\n --calendar--cell-size: 2.1rem;\n --calendar--cell-font-size: 0.8rem;\n }\n}\n"],"mappings":""}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
/* */
|
|
3
|
+
import { SkeletonModeReset, useSkeletonMode } from "../../../SkeletonMode/skeletonModeContext.mjs";
|
|
3
4
|
import Calendar_module_default from "../../Calendar.module.mjs";
|
|
4
5
|
import { CalendarHeader } from "../CalendarHeader/CalendarHeader.mjs";
|
|
5
6
|
import { MenuItem } from "../../../MenuItem/MenuItem.mjs";
|
|
@@ -34,11 +35,13 @@ var InnerRangeCalendar = ({ withDatePickerPresets }) => {
|
|
|
34
35
|
/** @flr-generate all */
|
|
35
36
|
var RangeCalendar = (props) => {
|
|
36
37
|
const { className, withDatePickerPresets, ...rest } = props;
|
|
37
|
-
const
|
|
38
|
+
const isSkeleton = useSkeletonMode();
|
|
39
|
+
const rootClassName = clsx(Calendar_module_default.calendar, Calendar_module_default.range, isSkeleton && Calendar_module_default.skeleton, className);
|
|
38
40
|
return /* @__PURE__ */ jsx(Aria.RangeCalendar, {
|
|
39
41
|
...rest,
|
|
40
42
|
className: rootClassName,
|
|
41
|
-
|
|
43
|
+
inert: isSkeleton || void 0,
|
|
44
|
+
children: /* @__PURE__ */ jsx(SkeletonModeReset, { children: /* @__PURE__ */ jsx(InnerRangeCalendar, { withDatePickerPresets }) })
|
|
42
45
|
});
|
|
43
46
|
};
|
|
44
47
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RangeCalendar.mjs","names":["styles","_Fragment"],"sources":["../../../../../../../../../src/components/Calendar/components/RangeCalendar/RangeCalendar.tsx"],"sourcesContent":["import { type FC } from \"react\";\nimport * as Aria from \"react-aria-components\";\nimport styles from \"@/components/Calendar/Calendar.module.scss\";\nimport CalendarHeader from \"../CalendarHeader\";\nimport clsx from \"clsx\";\nimport { MenuItem } from \"@/components/MenuItem\";\nimport { useCalendarDateRangePresets } from \"@/components/Calendar/components/RangeCalendar/helpers/useCalendarDateRangePresets\";\nimport { Separator } from \"@/components/Separator\";\nimport type { DateRangePickerProps } from \"@/components/DateRangePicker\";\n\nexport type RangeCalendarProps = Omit<\n Aria.RangeCalendarProps<Aria.DateValue>,\n \"children\"\n> &\n Pick<DateRangePickerProps, \"withDatePickerPresets\">;\n\n/** @internal */\nconst InnerRangeCalendar: FC<RangeCalendarProps> = ({\n withDatePickerPresets,\n}) => {\n const dateRangeHelper = useCalendarDateRangePresets(withDatePickerPresets);\n\n const predefinedDateHelperItems = dateRangeHelper.map((present) => {\n return (\n <MenuItem\n key={present.label}\n isDisabled={present.disabled}\n onPress={present.onPress}\n aria-label={present.label}\n >\n {present.label}\n </MenuItem>\n );\n });\n\n return (\n <div className={styles.container}>\n {withDatePickerPresets && (\n <>\n <Aria.Menu className={styles.presetMenu}>\n {predefinedDateHelperItems}\n </Aria.Menu>\n <Separator\n orientation=\"vertical\"\n className={styles.presetSeparator}\n />\n </>\n )}\n <div>\n <CalendarHeader />\n <Aria.CalendarGrid>\n {(date) => <Aria.CalendarCell date={date} />}\n </Aria.CalendarGrid>\n </div>\n </div>\n );\n};\n\n/** @flr-generate all */\nexport const RangeCalendar: FC<RangeCalendarProps> = (props) => {\n const { className, withDatePickerPresets, ...rest } = props;\n const rootClassName = clsx(styles.calendar
|
|
1
|
+
{"version":3,"file":"RangeCalendar.mjs","names":["styles","_Fragment"],"sources":["../../../../../../../../../src/components/Calendar/components/RangeCalendar/RangeCalendar.tsx"],"sourcesContent":["import { type FC } from \"react\";\nimport * as Aria from \"react-aria-components\";\nimport styles from \"@/components/Calendar/Calendar.module.scss\";\nimport CalendarHeader from \"../CalendarHeader\";\nimport clsx from \"clsx\";\nimport { MenuItem } from \"@/components/MenuItem\";\nimport { useCalendarDateRangePresets } from \"@/components/Calendar/components/RangeCalendar/helpers/useCalendarDateRangePresets\";\nimport { Separator } from \"@/components/Separator\";\nimport type { DateRangePickerProps } from \"@/components/DateRangePicker\";\nimport {\n SkeletonModeReset,\n useSkeletonMode,\n} from \"@/components/SkeletonMode/skeletonModeContext\";\n\nexport type RangeCalendarProps = Omit<\n Aria.RangeCalendarProps<Aria.DateValue>,\n \"children\"\n> &\n Pick<DateRangePickerProps, \"withDatePickerPresets\">;\n\n/** @internal */\nconst InnerRangeCalendar: FC<RangeCalendarProps> = ({\n withDatePickerPresets,\n}) => {\n const dateRangeHelper = useCalendarDateRangePresets(withDatePickerPresets);\n\n const predefinedDateHelperItems = dateRangeHelper.map((present) => {\n return (\n <MenuItem\n key={present.label}\n isDisabled={present.disabled}\n onPress={present.onPress}\n aria-label={present.label}\n >\n {present.label}\n </MenuItem>\n );\n });\n\n return (\n <div className={styles.container}>\n {withDatePickerPresets && (\n <>\n <Aria.Menu className={styles.presetMenu}>\n {predefinedDateHelperItems}\n </Aria.Menu>\n <Separator\n orientation=\"vertical\"\n className={styles.presetSeparator}\n />\n </>\n )}\n <div>\n <CalendarHeader />\n <Aria.CalendarGrid>\n {(date) => <Aria.CalendarCell date={date} />}\n </Aria.CalendarGrid>\n </div>\n </div>\n );\n};\n\n/** @flr-generate all */\nexport const RangeCalendar: FC<RangeCalendarProps> = (props) => {\n const { className, withDatePickerPresets, ...rest } = props;\n const isSkeleton = useSkeletonMode();\n\n const rootClassName = clsx(\n styles.calendar,\n styles.range,\n isSkeleton && styles.skeleton,\n className,\n );\n\n return (\n <Aria.RangeCalendar\n {...rest}\n className={rootClassName}\n inert={isSkeleton || undefined}\n >\n {/* The calendar is one skeleton surface, its content draws none. */}\n <SkeletonModeReset>\n <InnerRangeCalendar withDatePickerPresets={withDatePickerPresets} />\n </SkeletonModeReset>\n </Aria.RangeCalendar>\n );\n};\n\nexport default RangeCalendar;\n"],"mappings":";;;;;;;;;;;;;;AAqBA,IAAM,sBAA8C,EAClD,4BACI;CAGJ,MAAM,4BAFkB,4BAA4B,qBAElB,CAAA,CAAgB,KAAK,YAAY;EACjE,OACE,oBAAC,UAAD;GAEE,YAAY,QAAQ;GACpB,SAAS,QAAQ;GACjB,cAAY,QAAQ;GAEnB,UAAA,QAAQ;EACD,GANH,QAAQ,KAML;CAEd,CAAC;CAED,OACE,qBAAC,OAAD;EAAK,WAAWA,wBAAO;EAAvB,UAAA,CACG,yBACC,qBAAAC,YAAA,EAAA,UAAA,CACE,oBAAC,KAAK,MAAN;GAAW,WAAWD,wBAAO;GAC1B,UAAA;EACQ,CAAA,GACX,oBAAC,WAAD;GACE,aAAY;GACZ,WAAWA,wBAAO;EACnB,CAAA,CACD,EAAA,CAAA,GAEJ,qBAAC,OAAD,EAAA,UAAA,CACE,oBAAC,gBAAD,CAAiB,CAAA,GACjB,oBAAC,KAAK,cAAN,EAAA,WACI,SAAS,oBAAC,KAAK,cAAN,EAAyB,KAAO,CAAA,EAC1B,CAAA,CAChB,EAAA,CAAA,CACF;;AAET;;AAGA,IAAa,iBAAyC,UAAU;CAC9D,MAAM,EAAE,WAAW,uBAAuB,GAAG,SAAS;CACtD,MAAM,aAAa,gBAAgB;CAEnC,MAAM,gBAAgB,KACpBA,wBAAO,UACPA,wBAAO,OACP,cAAcA,wBAAO,UACrB,SACF;CAEA,OACE,oBAAC,KAAK,eAAN;EACE,GAAI;EACJ,WAAW;EACX,OAAO,cAAc,KAAA;EAGrB,UAAA,oBAAC,mBAAD,EAAA,UACE,oBAAC,oBAAD,EAA2C,sBAAwB,CAAA,EAClD,CAAA;CACD,CAAA;AAExB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
/* */
|
|
3
3
|
import { useWarnDeprecation } from "../DeprecationWarningProvider/DeprecationWarningProvider.mjs";
|
|
4
|
+
import { useSkeletonMode } from "../SkeletonMode/skeletonModeContext.mjs";
|
|
4
5
|
import { Wrap } from "../Wrap/Wrap.mjs";
|
|
5
6
|
import CartesianChart_module_default from "./CartesianChart.module.mjs";
|
|
6
7
|
import { useChartClipRect } from "./hooks/useChartClipRect.mjs";
|
|
@@ -37,6 +38,16 @@ var CartesianChart = (props) => {
|
|
|
37
38
|
layout,
|
|
38
39
|
stackIdPrefix: `${chartId}-`
|
|
39
40
|
}), [layout, chartId]);
|
|
41
|
+
if (useSkeletonMode()) return /* @__PURE__ */ jsx("div", {
|
|
42
|
+
className: CartesianChart_module_default.skeleton,
|
|
43
|
+
style: {
|
|
44
|
+
height,
|
|
45
|
+
aspectRatio: height ? void 0 : 3,
|
|
46
|
+
flex: flexGrow ? 1 : void 0
|
|
47
|
+
},
|
|
48
|
+
"aria-hidden": true,
|
|
49
|
+
inert: true
|
|
50
|
+
});
|
|
40
51
|
return /* @__PURE__ */ jsx(CartesianChartContextProvider, {
|
|
41
52
|
value: contextValue,
|
|
42
53
|
children: /* @__PURE__ */ jsx(Wrap, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CartesianChart.mjs","names":["styles"],"sources":["../../../../../../../src/components/CartesianChart/CartesianChart.tsx"],"sourcesContent":["import { ComposedChart, ResponsiveContainer } from \"recharts\";\nimport {\n type ComponentProps,\n type ComponentType,\n type FC,\n isValidElement,\n type PropsWithChildren,\n type ReactNode,\n useId,\n useMemo,\n} from \"react\";\nimport clsx from \"clsx\";\nimport styles from \"./CartesianChart.module.scss\";\nimport { useChartClipRect } from \"@/components/CartesianChart/hooks/useChartClipRect\";\nimport DivView from \"@/views/DivView\";\nimport Wrap from \"@/components/Wrap\";\nimport type {\n CartesianChartLayout,\n ChartDataValue,\n DataKeyProp,\n} from \"@/components/CartesianChart/types\";\nimport { CartesianChartContextProvider } from \"@/components/CartesianChart/context\";\nimport { TypedArea } from \"@/components/CartesianChart/components/Area\";\nimport { TypedBar } from \"@/components/CartesianChart/components/Bar\";\nimport { TypedXAxis } from \"@/components/CartesianChart/components/XAxis\";\nimport { TypedYAxis } from \"@/components/CartesianChart/components/YAxis\";\nimport { TypedChartGrid } from \"@/components/CartesianChart/components/ChartGrid\";\nimport { TypedChartLegend } from \"@/components/CartesianChart/components/ChartLegend\";\nimport { TypedChartTooltip } from \"@/components/CartesianChart/components/ChartTooltip\";\nimport { TypedLine } from \"@/components/CartesianChart/components/Line\";\nimport { useWarnDeprecation } from \"@/components/DeprecationWarningProvider\";\n\n/** @deprecated Use a ReactNode instead */\nexport interface CartesianChartEmptyViewProps {\n data?: ComponentProps<typeof ComposedChart>[\"data\"];\n}\n\nexport interface CartesianChartProps<TData = ChartDataValue>\n extends\n Pick<\n ComponentProps<typeof ComposedChart>,\n \"className\" | \"syncId\" | \"syncMethod\"\n >,\n PropsWithChildren {\n /** The data points rendered by the chart. */\n data?: TData[];\n\n /** The height of the chart. */\n height?: string;\n\n /**\n * The orientation of the axes and graphical items. `\"horizontal\"` puts the\n * category axis on the x-axis — bars grow upwards. `\"vertical\"` puts it on\n * the y-axis — bars grow to the side. `XAxis` and `YAxis` follow the layout\n * on their own; only the `dataKey` moves to whichever axis is the categorical\n * one.\n *\n * @default \"horizontal\"\n */\n layout?: CartesianChartLayout;\n\n /** View that is provided when data is empty/undefined */\n emptyView?: ReactNode;\n\n /**\n * Allow the height controlling container to set flex-grow: 1. Can only be\n * used in combination with `height`\n */\n flexGrow?: boolean;\n}\n\n/** @flr-generate all */\nexport const CartesianChart: FC<CartesianChartProps> = (props) => {\n const {\n children,\n data,\n className,\n height,\n flexGrow,\n emptyView,\n layout = \"horizontal\",\n ...rest\n } = props;\n const warnDeprecation = useWarnDeprecation();\n\n const { viewDimensions, ref: containerRef } = useChartClipRect();\n\n const showEmptyView = !!((!data || data.length === 0) && emptyView);\n const rootClassName = clsx(\n styles.cartesianChart,\n showEmptyView && styles.emptyView,\n className,\n );\n const usesDeprecatedEmptyView = !!emptyView && !isValidElement(emptyView);\n\n if (usesDeprecatedEmptyView) {\n warnDeprecation(\n \"CartesianChart: emptyView as a non-element is deprecated and will be removed in a future release. Please provide an element as emptyView.\",\n );\n }\n\n const emptyElement = useMemo(() => {\n if (isValidElement(emptyView)) {\n return emptyView;\n }\n\n if (!emptyView) {\n return;\n }\n\n return null;\n }, [emptyView]);\n\n const chartId = useId().replaceAll(/[^\\w-]/g, \"\");\n const contextValue = useMemo(\n () => ({ layout, stackIdPrefix: `${chartId}-` }),\n [layout, chartId],\n );\n\n return (\n <CartesianChartContextProvider value={contextValue}>\n <Wrap if={height}>\n <div style={{ height, flex: flexGrow ? 1 : undefined }}>\n <ResponsiveContainer\n initialDimension={{\n // fix warning on initial render\n width: 1,\n height: 1,\n }}\n width={height ? undefined : \"100%\"}\n aspect={height ? undefined : 3}\n ref={containerRef}\n >\n <ComposedChart\n data={data}\n className={rootClassName}\n layout={layout}\n {...rest}\n >\n {children}\n {showEmptyView && viewDimensions && (\n <foreignObject {...viewDimensions}>\n <DivView className={styles.emptyViewContainer}>\n {emptyElement}\n </DivView>\n </foreignObject>\n )}\n </ComposedChart>\n </ResponsiveContainer>\n </div>\n </Wrap>\n </CartesianChartContextProvider>\n );\n};\n\nexport const typedCartesianChart = <\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n TData extends ChartDataValue<any> = ChartDataValue<any>,\n XAxisDataKey extends DataKeyProp<TData> = DataKeyProp<TData>,\n>() => ({\n Chart: CartesianChart as ComponentType<CartesianChartProps<TData>>,\n Area: TypedArea<TData>(),\n Bar: TypedBar<TData>(),\n XAxis: TypedXAxis<TData, XAxisDataKey>(),\n YAxis: TypedYAxis<TData>(),\n Grid: TypedChartGrid(),\n Legend: TypedChartLegend(),\n Tooltip: TypedChartTooltip<TData, XAxisDataKey>(),\n Line: TypedLine<TData>(),\n});\n\nexport default CartesianChart;\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"CartesianChart.mjs","names":["styles"],"sources":["../../../../../../../src/components/CartesianChart/CartesianChart.tsx"],"sourcesContent":["import { ComposedChart, ResponsiveContainer } from \"recharts\";\nimport {\n type ComponentProps,\n type ComponentType,\n type FC,\n isValidElement,\n type PropsWithChildren,\n type ReactNode,\n useId,\n useMemo,\n} from \"react\";\nimport clsx from \"clsx\";\nimport styles from \"./CartesianChart.module.scss\";\nimport { useChartClipRect } from \"@/components/CartesianChart/hooks/useChartClipRect\";\nimport DivView from \"@/views/DivView\";\nimport Wrap from \"@/components/Wrap\";\nimport type {\n CartesianChartLayout,\n ChartDataValue,\n DataKeyProp,\n} from \"@/components/CartesianChart/types\";\nimport { CartesianChartContextProvider } from \"@/components/CartesianChart/context\";\nimport { TypedArea } from \"@/components/CartesianChart/components/Area\";\nimport { TypedBar } from \"@/components/CartesianChart/components/Bar\";\nimport { TypedXAxis } from \"@/components/CartesianChart/components/XAxis\";\nimport { TypedYAxis } from \"@/components/CartesianChart/components/YAxis\";\nimport { TypedChartGrid } from \"@/components/CartesianChart/components/ChartGrid\";\nimport { TypedChartLegend } from \"@/components/CartesianChart/components/ChartLegend\";\nimport { TypedChartTooltip } from \"@/components/CartesianChart/components/ChartTooltip\";\nimport { TypedLine } from \"@/components/CartesianChart/components/Line\";\nimport { useWarnDeprecation } from \"@/components/DeprecationWarningProvider\";\nimport { useSkeletonMode } from \"@/components/SkeletonMode/skeletonModeContext\";\n\n/** @deprecated Use a ReactNode instead */\nexport interface CartesianChartEmptyViewProps {\n data?: ComponentProps<typeof ComposedChart>[\"data\"];\n}\n\nexport interface CartesianChartProps<TData = ChartDataValue>\n extends\n Pick<\n ComponentProps<typeof ComposedChart>,\n \"className\" | \"syncId\" | \"syncMethod\"\n >,\n PropsWithChildren {\n /** The data points rendered by the chart. */\n data?: TData[];\n\n /** The height of the chart. */\n height?: string;\n\n /**\n * The orientation of the axes and graphical items. `\"horizontal\"` puts the\n * category axis on the x-axis — bars grow upwards. `\"vertical\"` puts it on\n * the y-axis — bars grow to the side. `XAxis` and `YAxis` follow the layout\n * on their own; only the `dataKey` moves to whichever axis is the categorical\n * one.\n *\n * @default \"horizontal\"\n */\n layout?: CartesianChartLayout;\n\n /** View that is provided when data is empty/undefined */\n emptyView?: ReactNode;\n\n /**\n * Allow the height controlling container to set flex-grow: 1. Can only be\n * used in combination with `height`\n */\n flexGrow?: boolean;\n}\n\n/** @flr-generate all */\nexport const CartesianChart: FC<CartesianChartProps> = (props) => {\n const {\n children,\n data,\n className,\n height,\n flexGrow,\n emptyView,\n layout = \"horizontal\",\n ...rest\n } = props;\n const warnDeprecation = useWarnDeprecation();\n\n const { viewDimensions, ref: containerRef } = useChartClipRect();\n\n const showEmptyView = !!((!data || data.length === 0) && emptyView);\n const rootClassName = clsx(\n styles.cartesianChart,\n showEmptyView && styles.emptyView,\n className,\n );\n const usesDeprecatedEmptyView = !!emptyView && !isValidElement(emptyView);\n\n if (usesDeprecatedEmptyView) {\n warnDeprecation(\n \"CartesianChart: emptyView as a non-element is deprecated and will be removed in a future release. Please provide an element as emptyView.\",\n );\n }\n\n const emptyElement = useMemo(() => {\n if (isValidElement(emptyView)) {\n return emptyView;\n }\n\n if (!emptyView) {\n return;\n }\n\n return null;\n }, [emptyView]);\n\n const chartId = useId().replaceAll(/[^\\w-]/g, \"\");\n const contextValue = useMemo(\n () => ({ layout, stackIdPrefix: `${chartId}-` }),\n [layout, chartId],\n );\n\n const isSkeleton = useSkeletonMode();\n\n /* No recharts and no svg: one surface in the size the chart would take. */\n if (isSkeleton) {\n return (\n <div\n className={styles.skeleton}\n style={{\n height,\n aspectRatio: height ? undefined : 3,\n flex: flexGrow ? 1 : undefined,\n }}\n aria-hidden\n inert\n />\n );\n }\n\n return (\n <CartesianChartContextProvider value={contextValue}>\n <Wrap if={height}>\n <div style={{ height, flex: flexGrow ? 1 : undefined }}>\n <ResponsiveContainer\n initialDimension={{\n // fix warning on initial render\n width: 1,\n height: 1,\n }}\n width={height ? undefined : \"100%\"}\n aspect={height ? undefined : 3}\n ref={containerRef}\n >\n <ComposedChart\n data={data}\n className={rootClassName}\n layout={layout}\n {...rest}\n >\n {children}\n {showEmptyView && viewDimensions && (\n <foreignObject {...viewDimensions}>\n <DivView className={styles.emptyViewContainer}>\n {emptyElement}\n </DivView>\n </foreignObject>\n )}\n </ComposedChart>\n </ResponsiveContainer>\n </div>\n </Wrap>\n </CartesianChartContextProvider>\n );\n};\n\nexport const typedCartesianChart = <\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n TData extends ChartDataValue<any> = ChartDataValue<any>,\n XAxisDataKey extends DataKeyProp<TData> = DataKeyProp<TData>,\n>() => ({\n Chart: CartesianChart as ComponentType<CartesianChartProps<TData>>,\n Area: TypedArea<TData>(),\n Bar: TypedBar<TData>(),\n XAxis: TypedXAxis<TData, XAxisDataKey>(),\n YAxis: TypedYAxis<TData>(),\n Grid: TypedChartGrid(),\n Legend: TypedChartLegend(),\n Tooltip: TypedChartTooltip<TData, XAxisDataKey>(),\n Line: TypedLine<TData>(),\n});\n\nexport default CartesianChart;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAyEA,IAAa,kBAA2C,UAAU;CAChE,MAAM,EACJ,UACA,MACA,WACA,QACA,UACA,WACA,SAAS,cACT,GAAG,SACD;CACJ,MAAM,kBAAkB,mBAAmB;CAE3C,MAAM,EAAE,gBAAgB,KAAK,iBAAiB,iBAAiB;CAE/D,MAAM,gBAAgB,CAAC,GAAG,CAAC,QAAQ,KAAK,WAAW,MAAM;CACzD,MAAM,gBAAgB,KACpBA,8BAAO,gBACP,iBAAiBA,8BAAO,WACxB,SACF;CAGA,IAFgC,CAAC,CAAC,aAAa,CAAC,eAAe,SAAS,GAGtE,gBACE,2IACF;CAGF,MAAM,eAAe,cAAc;EACjC,IAAI,eAAe,SAAS,GAC1B,OAAO;EAGT,IAAI,CAAC,WACH;EAGF,OAAO;CACT,GAAG,CAAC,SAAS,CAAC;CAEd,MAAM,UAAU,MAAM,CAAC,CAAC,WAAW,WAAW,EAAE;CAChD,MAAM,eAAe,eACZ;EAAE;EAAQ,eAAe,GAAG,QAAQ;CAAG,IAC9C,CAAC,QAAQ,OAAO,CAClB;CAKA,IAHmB,gBAGf,GACF,OACE,oBAAC,OAAD;EACE,WAAWA,8BAAO;EAClB,OAAO;GACL;GACA,aAAa,SAAS,KAAA,IAAY;GAClC,MAAM,WAAW,IAAI,KAAA;EACvB;EACA,eAAA;EACA,OAAA;CACD,CAAA;CAIL,OACE,oBAAC,+BAAD;EAA+B,OAAO;EACpC,UAAA,oBAAC,MAAD;GAAM,IAAI;GACR,UAAA,oBAAC,OAAD;IAAK,OAAO;KAAE;KAAQ,MAAM,WAAW,IAAI,KAAA;IAAU;IACnD,UAAA,oBAAC,qBAAD;KACE,kBAAkB;MAEhB,OAAO;MACP,QAAQ;KACV;KACA,OAAO,SAAS,KAAA,IAAY;KAC5B,QAAQ,SAAS,KAAA,IAAY;KAC7B,KAAK;KAEL,UAAA,qBAAC,eAAD;MACQ;MACN,WAAW;MACH;MACR,GAAI;MAJN,UAAA,CAMG,UACA,iBAAiB,kBAChB,oBAAC,iBAAD;OAAe,GAAI;OACjB,UAAA,oBAAC,SAAD;QAAS,WAAWA,8BAAO;QACxB,UAAA;OACM,CAAA;MACI,CAAA,CAEJ;;IACI,CAAA;GAClB,CAAA;EACD,CAAA;CACuB,CAAA;AAEnC;AAEA,IAAa,6BAIL;CACN,OAAO;CACP,MAAM,UAAiB;CACvB,KAAK,SAAgB;CACrB,OAAO,WAAgC;CACvC,OAAO,WAAkB;CACzB,MAAM,eAAe;CACrB,QAAQ,iBAAiB;CACzB,SAAS,kBAAuC;CAChD,MAAM,UAAiB;AACzB"}
|
|
@@ -4,12 +4,16 @@
|
|
|
4
4
|
var cartesianChart = "flow--cartesian-chart";
|
|
5
5
|
var emptyViewContainer = "flow--cartesian-chart--empty-view-container";
|
|
6
6
|
var emptyView = "flow--cartesian-chart--empty-view";
|
|
7
|
+
var skeleton = "flow--cartesian-chart--skeleton";
|
|
7
8
|
var CartesianChart_module_default = {
|
|
8
9
|
cartesianChart,
|
|
9
10
|
emptyViewContainer,
|
|
10
|
-
emptyView
|
|
11
|
+
emptyView,
|
|
12
|
+
skeleton,
|
|
13
|
+
"skeleton-surface-shimmer": "flow--cartesian-chart--skeleton-surface-shimmer",
|
|
14
|
+
"skeleton-text-shimmer": "flow--cartesian-chart--skeleton-text-shimmer"
|
|
11
15
|
};
|
|
12
16
|
//#endregion
|
|
13
|
-
export { cartesianChart, CartesianChart_module_default as default, emptyView, emptyViewContainer };
|
|
17
|
+
export { cartesianChart, CartesianChart_module_default as default, emptyView, emptyViewContainer, skeleton };
|
|
14
18
|
|
|
15
19
|
//# sourceMappingURL=CartesianChart.module.mjs.map
|
package/dist/js/packages/components/src/components/CartesianChart/CartesianChart.module.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CartesianChart.module.mjs","names":[],"sources":["../../../../../../../src/components/CartesianChart/CartesianChart.module.scss"],"sourcesContent":[".cartesianChart {\n font-family: Inter, sans-serif;\n isolation: isolate;\n\n *:focus:not(:focus-visible) {\n outline: none !important;\n }\n\n .emptyViewContainer {\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n }\n\n &.emptyView {\n :global(.recharts-cartesian-grid) {\n display: none;\n }\n }\n\n // recharts renders every svg here; only its outermost surface is classed.\n // stylelint-disable-next-line selector-max-type -- third-party svgs\n svg {\n overflow: visible;\n }\n\n :global(.recharts-tooltip-wrapper) {\n z-index: 1;\n }\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"CartesianChart.module.mjs","names":[],"sources":["../../../../../../../src/components/CartesianChart/CartesianChart.module.scss"],"sourcesContent":["@use \"@/styles/mixins/skeleton\";\n\n.cartesianChart {\n font-family: Inter, sans-serif;\n isolation: isolate;\n\n *:focus:not(:focus-visible) {\n outline: none !important;\n }\n\n .emptyViewContainer {\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n }\n\n &.emptyView {\n :global(.recharts-cartesian-grid) {\n display: none;\n }\n }\n\n // recharts renders every svg here; only its outermost surface is classed.\n // stylelint-disable-next-line selector-max-type -- third-party svgs\n svg {\n overflow: visible;\n }\n\n :global(.recharts-tooltip-wrapper) {\n z-index: 1;\n }\n}\n\n/* SkeletonMode */\n\n.skeleton {\n @include skeleton.surface;\n\n width: 100%;\n}\n\n@include skeleton.keyframes;\n"],"mappings":""}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
/* */
|
|
3
|
+
import { SkeletonModeReset, useSkeletonMode } from "../SkeletonMode/skeletonModeContext.mjs";
|
|
3
4
|
import { useLocalizedStringFormatter } from "../TranslationProvider/useLocalizedStringFormatter.mjs";
|
|
4
5
|
import { Button } from "../Button/Button.mjs";
|
|
5
6
|
import CodeBlock_module_default from "./CodeBlock.module.mjs";
|
|
@@ -18,11 +19,13 @@ var CodeBlock = (props) => {
|
|
|
18
19
|
const [expandedHeight, setExpandedHeight] = useState();
|
|
19
20
|
const editorRef = useRef(null);
|
|
20
21
|
const stringFormatter = useLocalizedStringFormatter(__locale_default, "CodeBlock");
|
|
21
|
-
const
|
|
22
|
+
const isSkeleton = useSkeletonMode();
|
|
23
|
+
const rootClassName = clsx(CodeBlock_module_default.codeBlock, isSkeleton && CodeBlock_module_default.skeleton, className);
|
|
22
24
|
const id = useId();
|
|
23
25
|
if (!code) return /* @__PURE__ */ jsx("div", {
|
|
24
26
|
className: clsx(rootClassName, CodeBlock_module_default.withChildren),
|
|
25
|
-
|
|
27
|
+
inert: isSkeleton || void 0,
|
|
28
|
+
children: /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: /* @__PURE__ */ jsx(SkeletonModeReset, { children }) }) })
|
|
26
29
|
});
|
|
27
30
|
const heightVariables = {
|
|
28
31
|
...maxHeight ? { "--max-height": `${maxHeight}px` } : {},
|
|
@@ -50,7 +53,8 @@ var CodeBlock = (props) => {
|
|
|
50
53
|
onTransitionEnd: (event) => {
|
|
51
54
|
if (event.propertyName === "max-height") setExpandedHeight(void 0);
|
|
52
55
|
},
|
|
53
|
-
|
|
56
|
+
inert: isSkeleton || void 0,
|
|
57
|
+
children: /* @__PURE__ */ jsx(SkeletonModeReset, { children: /* @__PURE__ */ jsx(CodeEditor, {
|
|
54
58
|
...rest,
|
|
55
59
|
value: code,
|
|
56
60
|
editable: false,
|
|
@@ -81,7 +85,7 @@ var CodeBlock = (props) => {
|
|
|
81
85
|
children: stringFormatter.format(folded ? "showMore" : "showLess")
|
|
82
86
|
})
|
|
83
87
|
})
|
|
84
|
-
})
|
|
88
|
+
}) })
|
|
85
89
|
});
|
|
86
90
|
};
|
|
87
91
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlock.mjs","names":["locales","styles"],"sources":["../../../../../../../src/components/CodeBlock/CodeBlock.tsx"],"sourcesContent":["import {\n type FC,\n type PropsWithChildren,\n useId,\n useRef,\n useState,\n} from \"react\";\nimport { flushSync } from \"react-dom\";\nimport type { PropsWithClassName } from \"@/lib/types/props\";\nimport clsx from \"clsx\";\nimport styles from \"./CodeBlock.module.scss\";\nimport { CodeEditor, type CodeEditorProps } from \"@/components/CodeEditor\";\nimport { Button } from \"@/components/Button\";\nimport { useLocalizedStringFormatter } from \"@/components/TranslationProvider\";\nimport locales from \"./locales/*.locale.json\";\n\nexport interface CodeBlockProps\n extends\n PropsWithClassName,\n PropsWithChildren,\n Partial<\n Pick<CodeEditorProps, \"language\" | \"showLineNumbers\" | \"copyable\">\n > {\n /** The code displayed in the block. */\n code?: string;\n /**\n * Controls truncation of long code blocks. `false` disables it, `true`\n * truncates after 8 lines, and a number sets the maximum line count.\n *\n * @default: false\n */\n truncateLines?: boolean | number;\n}\n\n/** @flr-generate all */\nexport const CodeBlock: FC<CodeBlockProps> = (props) => {\n const {\n code,\n className,\n copyable = false,\n showLineNumbers = false,\n children,\n truncateLines = false,\n ...rest\n } = props;\n\n const [folded, setFolded] = useState(truncateLines !== false);\n const [maxHeight, setMaxHeight] = useState<number>();\n /* The full height, only while the toggle animates to or from it. */\n const [expandedHeight, setExpandedHeight] = useState<number>();\n const editorRef = useRef<HTMLElement>(null);\n\n const stringFormatter = useLocalizedStringFormatter(locales, \"CodeBlock\");\n\n const rootClassName = clsx(styles.codeBlock
|
|
1
|
+
{"version":3,"file":"CodeBlock.mjs","names":["locales","styles"],"sources":["../../../../../../../src/components/CodeBlock/CodeBlock.tsx"],"sourcesContent":["import {\n type FC,\n type PropsWithChildren,\n useId,\n useRef,\n useState,\n} from \"react\";\nimport { flushSync } from \"react-dom\";\nimport type { PropsWithClassName } from \"@/lib/types/props\";\nimport clsx from \"clsx\";\nimport styles from \"./CodeBlock.module.scss\";\nimport { CodeEditor, type CodeEditorProps } from \"@/components/CodeEditor\";\nimport { Button } from \"@/components/Button\";\nimport { useLocalizedStringFormatter } from \"@/components/TranslationProvider\";\nimport locales from \"./locales/*.locale.json\";\nimport {\n SkeletonModeReset,\n useSkeletonMode,\n} from \"@/components/SkeletonMode/skeletonModeContext\";\n\nexport interface CodeBlockProps\n extends\n PropsWithClassName,\n PropsWithChildren,\n Partial<\n Pick<CodeEditorProps, \"language\" | \"showLineNumbers\" | \"copyable\">\n > {\n /** The code displayed in the block. */\n code?: string;\n /**\n * Controls truncation of long code blocks. `false` disables it, `true`\n * truncates after 8 lines, and a number sets the maximum line count.\n *\n * @default: false\n */\n truncateLines?: boolean | number;\n}\n\n/** @flr-generate all */\nexport const CodeBlock: FC<CodeBlockProps> = (props) => {\n const {\n code,\n className,\n copyable = false,\n showLineNumbers = false,\n children,\n truncateLines = false,\n ...rest\n } = props;\n\n const [folded, setFolded] = useState(truncateLines !== false);\n const [maxHeight, setMaxHeight] = useState<number>();\n /* The full height, only while the toggle animates to or from it. */\n const [expandedHeight, setExpandedHeight] = useState<number>();\n const editorRef = useRef<HTMLElement>(null);\n\n const stringFormatter = useLocalizedStringFormatter(locales, \"CodeBlock\");\n const isSkeleton = useSkeletonMode();\n\n const rootClassName = clsx(\n styles.codeBlock,\n isSkeleton && styles.skeleton,\n className,\n );\n\n const id = useId();\n\n if (!code) {\n return (\n <div\n className={clsx(rootClassName, styles.withChildren)}\n inert={isSkeleton || undefined}\n >\n {/* Deliberately class-less: a `flow--` class would make the global\n reset's `font: inherit` apply and replace the UA monospace\n metrics. See CodeBlock.module.scss. */}\n <pre>\n <code>\n <SkeletonModeReset>{children}</SkeletonModeReset>\n </code>\n </pre>\n </div>\n );\n }\n\n const heightVariables: React.CSSProperties = {\n ...(maxHeight ? { \"--max-height\": `${maxHeight}px` } : {}),\n ...(expandedHeight\n ? { \"--expanded-max-height\": `${expandedHeight}px` }\n : {}),\n };\n\n /* A height transition needs a length on both ends – `none` does not\n interpolate. So the full height is measured for the transition and\n released once it ended, and code that changes later is not clipped. */\n const toggleFolded = () => {\n const editor = editorRef.current;\n\n if (!editor) {\n setFolded((folded) => !folded);\n return;\n }\n\n const animates = getComputedStyle(editor)\n .transitionDuration.split(\",\")\n .some((duration) => parseFloat(duration) > 0);\n\n if (folded) {\n setExpandedHeight(animates ? editor.scrollHeight : undefined);\n setFolded(false);\n } else {\n flushSync(() => setExpandedHeight(editor.scrollHeight));\n // Applies the start height before the folded one replaces it.\n editor.getBoundingClientRect();\n setFolded(true);\n }\n };\n\n return (\n <div\n className={clsx(\n rootClassName,\n maxHeight && styles.truncated,\n folded && styles.folded,\n )}\n style={heightVariables}\n onTransitionEnd={(event) => {\n if (event.propertyName === \"max-height\") {\n setExpandedHeight(undefined);\n }\n }}\n inert={isSkeleton || undefined}\n >\n {/* The code block is one skeleton surface in the size of its code, so\n the editor inside renders for real, but invisibly. */}\n <SkeletonModeReset>\n <CodeEditor\n {...rest}\n value={code}\n editable={false}\n copyable={copyable}\n showLineNumbers={showLineNumbers}\n showLinterMarkers={false}\n showCodeFolding={false}\n showActiveLineMarker={false}\n isReadOnly\n onCreateEditor={(view) => {\n editorRef.current = view.dom;\n\n if (!truncateLines) {\n return;\n }\n\n const lineHeight = 20;\n const padding = 12;\n\n const visibleLines =\n typeof truncateLines === \"number\" ? truncateLines : 8;\n\n const totalLines = view.state.doc.lines;\n\n if (totalLines > visibleLines)\n setMaxHeight(lineHeight * visibleLines + padding);\n }}\n id={id}\n >\n {truncateLines && maxHeight && (\n <div className={clsx(styles.buttonContainer)}>\n <Button\n variant=\"plain\"\n color=\"secondary\"\n size=\"s\"\n onPress={toggleFolded}\n aria-expanded={!folded}\n aria-controls={id}\n >\n {stringFormatter.format(folded ? \"showMore\" : \"showLess\")}\n </Button>\n </div>\n )}\n </CodeEditor>\n </SkeletonModeReset>\n </div>\n );\n};\n\nexport default CodeBlock;\n"],"mappings":";;;;;;;;;;;;;;AAuCA,IAAa,aAAiC,UAAU;CACtD,MAAM,EACJ,MACA,WACA,WAAW,OACX,kBAAkB,OAClB,UACA,gBAAgB,OAChB,GAAG,SACD;CAEJ,MAAM,CAAC,QAAQ,aAAa,SAAS,kBAAkB,KAAK;CAC5D,MAAM,CAAC,WAAW,gBAAgB,SAAiB;CAEnD,MAAM,CAAC,gBAAgB,qBAAqB,SAAiB;CAC7D,MAAM,YAAY,OAAoB,IAAI;CAE1C,MAAM,kBAAkB,4BAA4BA,kBAAS,WAAW;CACxE,MAAM,aAAa,gBAAgB;CAEnC,MAAM,gBAAgB,KACpBC,yBAAO,WACP,cAAcA,yBAAO,UACrB,SACF;CAEA,MAAM,KAAK,MAAM;CAEjB,IAAI,CAAC,MACH,OACE,oBAAC,OAAD;EACE,WAAW,KAAK,eAAeA,yBAAO,YAAY;EAClD,OAAO,cAAc,KAAA;EAKrB,UAAA,oBAAC,OAAD,EAAA,UACE,oBAAC,QAAD,EAAA,UACE,oBAAC,mBAAD,EAAoB,SAA4B,CAAA,EAC5C,CAAA,EACH,CAAA;CACF,CAAA;CAIT,MAAM,kBAAuC;EAC3C,GAAI,YAAY,EAAE,gBAAgB,GAAG,UAAU,IAAI,IAAI,CAAC;EACxD,GAAI,iBACA,EAAE,yBAAyB,GAAG,eAAe,IAAI,IACjD,CAAC;CACP;CAKA,MAAM,qBAAqB;EACzB,MAAM,SAAS,UAAU;EAEzB,IAAI,CAAC,QAAQ;GACX,WAAW,WAAW,CAAC,MAAM;GAC7B;EACF;EAEA,MAAM,WAAW,iBAAiB,MAAM,CAAC,CACtC,mBAAmB,MAAM,GAAG,CAAC,CAC7B,MAAM,aAAa,WAAW,QAAQ,IAAI,CAAC;EAE9C,IAAI,QAAQ;GACV,kBAAkB,WAAW,OAAO,eAAe,KAAA,CAAS;GAC5D,UAAU,KAAK;EACjB,OAAO;GACL,gBAAgB,kBAAkB,OAAO,YAAY,CAAC;GAEtD,OAAO,sBAAsB;GAC7B,UAAU,IAAI;EAChB;CACF;CAEA,OACE,oBAAC,OAAD;EACE,WAAW,KACT,eACA,aAAaA,yBAAO,WACpB,UAAUA,yBAAO,MACnB;EACA,OAAO;EACP,kBAAkB,UAAU;GAC1B,IAAI,MAAM,iBAAiB,cACzB,kBAAkB,KAAA,CAAS;EAE/B;EACA,OAAO,cAAc,KAAA;EAIrB,UAAA,oBAAC,mBAAD,EAAA,UACE,oBAAC,YAAD;GACE,GAAI;GACJ,OAAO;GACP,UAAU;GACA;GACO;GACjB,mBAAmB;GACnB,iBAAiB;GACjB,sBAAsB;GACtB,YAAA;GACA,iBAAiB,SAAS;IACxB,UAAU,UAAU,KAAK;IAEzB,IAAI,CAAC,eACH;IAGF,MAAM,aAAa;IACnB,MAAM,UAAU;IAEhB,MAAM,eACJ,OAAO,kBAAkB,WAAW,gBAAgB;IAItD,IAFmB,KAAK,MAAM,IAAI,QAEjB,cACf,aAAa,aAAa,eAAe,OAAO;GACpD;GACI;GAEH,UAAA,iBAAiB,aAChB,oBAAC,OAAD;IAAK,WAAW,KAAKA,yBAAO,eAAe;IACzC,UAAA,oBAAC,QAAD;KACE,SAAQ;KACR,OAAM;KACN,MAAK;KACL,SAAS;KACT,iBAAe,CAAC;KAChB,iBAAe;KAEd,UAAA,gBAAgB,OAAO,SAAS,aAAa,UAAU;IAClD,CAAA;GACL,CAAA;EAEG,CAAA,EACK,CAAA;CAChB,CAAA;AAET"}
|
|
@@ -6,14 +6,18 @@ var withChildren = "flow--code-block--with-children";
|
|
|
6
6
|
var truncated = "flow--code-block--truncated";
|
|
7
7
|
var buttonContainer = "flow--code-block--button-container";
|
|
8
8
|
var folded = "flow--code-block--folded";
|
|
9
|
+
var skeleton = "flow--code-block--skeleton";
|
|
9
10
|
var CodeBlock_module_default = {
|
|
10
11
|
codeBlock,
|
|
11
12
|
withChildren,
|
|
12
13
|
truncated,
|
|
13
14
|
buttonContainer,
|
|
14
|
-
folded
|
|
15
|
+
folded,
|
|
16
|
+
skeleton,
|
|
17
|
+
"skeleton-surface-shimmer": "flow--code-block--skeleton-surface-shimmer",
|
|
18
|
+
"skeleton-text-shimmer": "flow--code-block--skeleton-text-shimmer"
|
|
15
19
|
};
|
|
16
20
|
//#endregion
|
|
17
|
-
export { buttonContainer, codeBlock, CodeBlock_module_default as default, folded, truncated, withChildren };
|
|
21
|
+
export { buttonContainer, codeBlock, CodeBlock_module_default as default, folded, skeleton, truncated, withChildren };
|
|
18
22
|
|
|
19
23
|
//# sourceMappingURL=CodeBlock.module.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlock.module.mjs","names":[],"sources":["../../../../../../../src/components/CodeBlock/CodeBlock.module.scss"],"sourcesContent":["@use \"@/styles/mixins/expandTransition\";\n@use \"@/styles/mixins/scrollbar\";\n\n/* The show-more strip: a size-s button plus the container's padding. */\n$button-height-s: calc(\n var(--button--line-height-s) + 2 * var(--button--padding-s-y)\n);\n$show-more-height: calc(\n #{$button-height-s} + 2 * var(--code-block--show-more-padding)\n);\n$inner-corner-radius: calc(\n var(--code-block--corner-radius) - var(--form-control--border-width)\n);\n\n@function fade-color($amount) {\n @return color-mix(\n in srgb,\n var(--code-block--background-color) $amount,\n transparent\n );\n}\n\n.codeBlock {\n display: block;\n font-size: var(--code-block--font-size);\n font-family: var(--code-block--font-family);\n overflow: hidden;\n min-width: 0;\n\n &.withChildren {\n color: var(--code-block--content-color);\n background-color: var(--code-block--background-color);\n border: var(--code-block--border-width) var(--code-block--border-style)\n var(--code-block--border-color);\n border-radius: var(--code-block--corner-radius);\n\n /* These stay element selectors on purpose. Classing them would give them a\n `flow--` class, and the global reset's\n `*:where([class*=\"flow--\"] [class*=\"flow--\"]) { font: inherit }` would\n then replace the UA monospace metrics — the code text visibly reflows.\n Fixing that is a design decision for UX, not a lint cleanup. */\n // stylelint-disable selector-max-type -- see above\n > pre {\n @include scrollbar.scrollbar;\n\n overflow-x: auto;\n padding: var(--code-block--padding);\n\n > code {\n text-shadow: none;\n }\n }\n // stylelint-enable selector-max-type\n }\n\n /* Truncatable: collapsed, the show-more button lies over the code, which\n runs down to the border and fades out behind it. Toggling animates the\n height, the fade and the button's position together. */\n &.truncated {\n :global(.flow--code-editor--code-mirror) {\n transition-property:\n color, background-color, border-color, padding-block-end;\n\n @include expandTransition.expandTransition;\n }\n\n /* The editor holds the code and the line numbers, so both are clipped\n and fade out together. */\n :global(.cm-editor) {\n max-height: var(--expanded-max-height, none);\n overflow: hidden;\n border-end-start-radius: $inner-corner-radius;\n border-end-end-radius: $inner-corner-radius;\n transition-property: max-height;\n\n @include expandTransition.expandTransition;\n\n &::after {\n content: \"\";\n position: absolute;\n inset-inline: 0;\n bottom: 0;\n height: min(calc(var(--size-px--xxl) + #{$show-more-height}), 75%);\n pointer-events: none;\n opacity: 0;\n transition-property: opacity;\n\n @include expandTransition.expandTransition;\n\n /* Eased stops: no visible edge on top, the code only shimmers through\n behind the button. */\n background: linear-gradient(\n to bottom,\n transparent,\n fade-color(10%) 15%,\n fade-color(30%) 30%,\n fade-color(60%) 45%,\n fade-color(82%) 58%,\n fade-color(92%) 68%,\n fade-color(95%) 85%,\n fade-color(96%)\n );\n }\n }\n\n /* Keeps its full height instead of shrinking into the editor, so the\n editor clips it rather than the scroller scrolling within. The\n scroller's own z-index (CodeMirror's) keeps the line numbers under the\n fade. */\n :global(.cm-scroller) {\n flex-shrink: 0;\n }\n\n .buttonContainer {\n transition-property: margin-top, margin-bottom;\n\n @include expandTransition.expandTransition;\n }\n }\n\n &.folded {\n :global(.flow--code-editor--code-mirror) {\n padding-block-end: 0;\n }\n\n /* Grows by the button strip, so the button covers none of the lines. */\n :global(.cm-editor) {\n max-height: calc(var(--max-height) + #{$show-more-height});\n\n &::after {\n opacity: 1;\n }\n }\n\n .buttonContainer {\n margin-top: calc(#{$show-more-height} * -1);\n margin-bottom: 0;\n }\n }\n\n /* A code block is not an input – both axes use its own padding. The repeated\n root class only buys specificity over CodeEditor's own `.codeMirror` rules\n (incl. `.readonly`); it identifies nothing. */\n &.codeBlock.codeBlock :global(.flow--code-editor--code-mirror) {\n --form-control--padding-y: var(--code-block--padding);\n --form-control--padding-x: var(--code-block--padding);\n\n border-color: var(--code-block--border-color);\n }\n\n .buttonContainer {\n position: relative;\n margin-top: calc(var(--code-block--show-more-padding) * -1);\n\n /* Covers the editor's bottom padding – the container brings its own. */\n margin-bottom: calc(\n var(--form-control--border-width) - var(--form-control--padding-y)\n );\n display: flex;\n justify-content: center;\n padding-block: var(--code-block--show-more-padding);\n }\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"CodeBlock.module.mjs","names":[],"sources":["../../../../../../../src/components/CodeBlock/CodeBlock.module.scss"],"sourcesContent":["@use \"@/styles/mixins/expandTransition\";\n@use \"@/styles/mixins/scrollbar\";\n@use \"@/styles/mixins/skeleton\";\n\n/* The show-more strip: a size-s button plus the container's padding. */\n$button-height-s: calc(\n var(--button--line-height-s) + 2 * var(--button--padding-s-y)\n);\n$show-more-height: calc(\n #{$button-height-s} + 2 * var(--code-block--show-more-padding)\n);\n$inner-corner-radius: calc(\n var(--code-block--corner-radius) - var(--form-control--border-width)\n);\n\n@function fade-color($amount) {\n @return color-mix(\n in srgb,\n var(--code-block--background-color) $amount,\n transparent\n );\n}\n\n.codeBlock {\n display: block;\n font-size: var(--code-block--font-size);\n font-family: var(--code-block--font-family);\n overflow: hidden;\n min-width: 0;\n\n &.withChildren {\n color: var(--code-block--content-color);\n background-color: var(--code-block--background-color);\n border: var(--code-block--border-width) var(--code-block--border-style)\n var(--code-block--border-color);\n border-radius: var(--code-block--corner-radius);\n\n /* These stay element selectors on purpose. Classing them would give them a\n `flow--` class, and the global reset's\n `*:where([class*=\"flow--\"] [class*=\"flow--\"]) { font: inherit }` would\n then replace the UA monospace metrics — the code text visibly reflows.\n Fixing that is a design decision for UX, not a lint cleanup. */\n // stylelint-disable selector-max-type -- see above\n > pre {\n @include scrollbar.scrollbar;\n\n overflow-x: auto;\n padding: var(--code-block--padding);\n\n > code {\n text-shadow: none;\n }\n }\n // stylelint-enable selector-max-type\n }\n\n /* Truncatable: collapsed, the show-more button lies over the code, which\n runs down to the border and fades out behind it. Toggling animates the\n height, the fade and the button's position together. */\n &.truncated {\n :global(.flow--code-editor--code-mirror) {\n transition-property:\n color, background-color, border-color, padding-block-end;\n\n @include expandTransition.expandTransition;\n }\n\n /* The editor holds the code and the line numbers, so both are clipped\n and fade out together. */\n :global(.cm-editor) {\n max-height: var(--expanded-max-height, none);\n overflow: hidden;\n border-end-start-radius: $inner-corner-radius;\n border-end-end-radius: $inner-corner-radius;\n transition-property: max-height;\n\n @include expandTransition.expandTransition;\n\n &::after {\n content: \"\";\n position: absolute;\n inset-inline: 0;\n bottom: 0;\n height: min(calc(var(--size-px--xxl) + #{$show-more-height}), 75%);\n pointer-events: none;\n opacity: 0;\n transition-property: opacity;\n\n @include expandTransition.expandTransition;\n\n /* Eased stops: no visible edge on top, the code only shimmers through\n behind the button. */\n background: linear-gradient(\n to bottom,\n transparent,\n fade-color(10%) 15%,\n fade-color(30%) 30%,\n fade-color(60%) 45%,\n fade-color(82%) 58%,\n fade-color(92%) 68%,\n fade-color(95%) 85%,\n fade-color(96%)\n );\n }\n }\n\n /* Keeps its full height instead of shrinking into the editor, so the\n editor clips it rather than the scroller scrolling within. The\n scroller's own z-index (CodeMirror's) keeps the line numbers under the\n fade. */\n :global(.cm-scroller) {\n flex-shrink: 0;\n }\n\n .buttonContainer {\n transition-property: margin-top, margin-bottom;\n\n @include expandTransition.expandTransition;\n }\n }\n\n &.folded {\n :global(.flow--code-editor--code-mirror) {\n padding-block-end: 0;\n }\n\n /* Grows by the button strip, so the button covers none of the lines. */\n :global(.cm-editor) {\n max-height: calc(var(--max-height) + #{$show-more-height});\n\n &::after {\n opacity: 1;\n }\n }\n\n .buttonContainer {\n margin-top: calc(#{$show-more-height} * -1);\n margin-bottom: 0;\n }\n }\n\n /* A code block is not an input – both axes use its own padding. The repeated\n root class only buys specificity over CodeEditor's own `.codeMirror` rules\n (incl. `.readonly`); it identifies nothing. */\n &.codeBlock.codeBlock :global(.flow--code-editor--code-mirror) {\n --form-control--padding-y: var(--code-block--padding);\n --form-control--padding-x: var(--code-block--padding);\n\n border-color: var(--code-block--border-color);\n }\n\n .buttonContainer {\n position: relative;\n margin-top: calc(var(--code-block--show-more-padding) * -1);\n\n /* Covers the editor's bottom padding – the container brings its own. */\n margin-bottom: calc(\n var(--form-control--border-width) - var(--form-control--padding-y)\n );\n display: flex;\n justify-content: center;\n padding-block: var(--code-block--show-more-padding);\n }\n\n /* SkeletonMode — after the variants, so the surface wins over their colors */\n\n &.skeleton {\n @include skeleton.shape;\n\n --skeleton-radius: var(--code-block--corner-radius);\n }\n}\n\n@include skeleton.keyframes;\n"],"mappings":""}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
/* */
|
|
3
3
|
import { PropsContextProvider } from "../../lib/propsContext/components/PropsContextProvider.mjs";
|
|
4
4
|
import { flowComponent } from "../../lib/componentFactory/flowComponent.mjs";
|
|
5
|
+
import { useSkeletonMode } from "../SkeletonMode/skeletonModeContext.mjs";
|
|
5
6
|
import { UiComponentTunnelExit } from "../UiComponentTunnel/UiComponentTunnelExit.mjs";
|
|
6
7
|
import { joinIds, useFieldComponent } from "../../lib/hooks/useFieldComponent.mjs";
|
|
7
8
|
import { useMakeFocusable } from "../../lib/hooks/dom/useMakeFocusable.mjs";
|
|
@@ -92,9 +93,49 @@ var CodeEditor = flowComponent("CodeEditor", (props) => {
|
|
|
92
93
|
});
|
|
93
94
|
const localRef = useObjectRef(ref);
|
|
94
95
|
useMakeFocusable(localRef);
|
|
96
|
+
const isSkeleton = useSkeletonMode();
|
|
97
|
+
const skeleton = /* @__PURE__ */ jsxs("div", {
|
|
98
|
+
className: clsx(CodeEditor_module_default.codeMirror, isReadOnly && CodeEditor_module_default.readonly, CodeEditor_module_default.skeleton),
|
|
99
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
100
|
+
className: CodeEditor_module_default.skeletonLines,
|
|
101
|
+
style: { height: height ?? minHeight },
|
|
102
|
+
children: (value ?? "").split("\n").map((line, index) => /* @__PURE__ */ jsx("div", { children: line || " " }, index))
|
|
103
|
+
}), children]
|
|
104
|
+
});
|
|
105
|
+
const editor = /* @__PURE__ */ jsxs(CodeMirror, {
|
|
106
|
+
...rest,
|
|
107
|
+
value,
|
|
108
|
+
basicSetup: {
|
|
109
|
+
highlightActiveLine: showActiveLineMarker && !isDisabled,
|
|
110
|
+
highlightActiveLineGutter: showActiveLineMarker && !isDisabled,
|
|
111
|
+
autocompletion: false,
|
|
112
|
+
lineNumbers: false,
|
|
113
|
+
foldGutter: false,
|
|
114
|
+
highlightSelectionMatches: false
|
|
115
|
+
},
|
|
116
|
+
theme: defaultLightTheme,
|
|
117
|
+
"data-invalid": isInvalid || void 0,
|
|
118
|
+
"data-disabled": isDisabled || void 0,
|
|
119
|
+
readOnly: isReadOnly || isDisabled,
|
|
120
|
+
editable: !isDisabled,
|
|
121
|
+
className: clsx(CodeEditor_module_default.codeMirror, isReadOnly && CodeEditor_module_default.readonly),
|
|
122
|
+
ref: (codeMirrorRef) => {
|
|
123
|
+
if (codeMirrorRef?.editor) localRef.current = codeMirrorRef.editor;
|
|
124
|
+
},
|
|
125
|
+
extensions: [...enabledExtensions, contentAttributes],
|
|
126
|
+
height: height ?? minHeight,
|
|
127
|
+
children: [copyable && /* @__PURE__ */ jsx(CopyButton, {
|
|
128
|
+
className: CodeEditor_module_default.copyButton,
|
|
129
|
+
size: "s",
|
|
130
|
+
variant: "soft",
|
|
131
|
+
text: value,
|
|
132
|
+
isDisabled
|
|
133
|
+
}), children]
|
|
134
|
+
});
|
|
95
135
|
return /* @__PURE__ */ jsx("div", {
|
|
96
136
|
className: rootClassName,
|
|
97
137
|
"data-disabled": isDisabled || void 0,
|
|
138
|
+
inert: isSkeleton || void 0,
|
|
98
139
|
children: /* @__PURE__ */ jsxs(PropsContextProvider, {
|
|
99
140
|
props: propsContext,
|
|
100
141
|
children: [
|
|
@@ -102,36 +143,7 @@ var CodeEditor = flowComponent("CodeEditor", (props) => {
|
|
|
102
143
|
id: "label",
|
|
103
144
|
component: "CodeEditor"
|
|
104
145
|
}),
|
|
105
|
-
/* @__PURE__ */ jsx(FieldErrorCaptureContext, { children:
|
|
106
|
-
...rest,
|
|
107
|
-
value,
|
|
108
|
-
basicSetup: {
|
|
109
|
-
highlightActiveLine: showActiveLineMarker && !isDisabled,
|
|
110
|
-
highlightActiveLineGutter: showActiveLineMarker && !isDisabled,
|
|
111
|
-
autocompletion: false,
|
|
112
|
-
lineNumbers: false,
|
|
113
|
-
foldGutter: false,
|
|
114
|
-
highlightSelectionMatches: false
|
|
115
|
-
},
|
|
116
|
-
theme: defaultLightTheme,
|
|
117
|
-
"data-invalid": isInvalid || void 0,
|
|
118
|
-
"data-disabled": isDisabled || void 0,
|
|
119
|
-
readOnly: isReadOnly || isDisabled,
|
|
120
|
-
editable: !isDisabled,
|
|
121
|
-
className: clsx(CodeEditor_module_default.codeMirror, isReadOnly && CodeEditor_module_default.readonly),
|
|
122
|
-
ref: (codeMirrorRef) => {
|
|
123
|
-
if (codeMirrorRef?.editor) localRef.current = codeMirrorRef.editor;
|
|
124
|
-
},
|
|
125
|
-
extensions: [...enabledExtensions, contentAttributes],
|
|
126
|
-
height: height ?? minHeight,
|
|
127
|
-
children: [copyable && /* @__PURE__ */ jsx(CopyButton, {
|
|
128
|
-
className: CodeEditor_module_default.copyButton,
|
|
129
|
-
size: "s",
|
|
130
|
-
variant: "soft",
|
|
131
|
-
text: value,
|
|
132
|
-
isDisabled
|
|
133
|
-
}), children]
|
|
134
|
-
}) }),
|
|
146
|
+
/* @__PURE__ */ jsx(FieldErrorCaptureContext, { children: isSkeleton ? skeleton : editor }),
|
|
135
147
|
/* @__PURE__ */ jsx(UiComponentTunnelExit, {
|
|
136
148
|
id: "fieldDescription",
|
|
137
149
|
component: "CodeEditor"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeEditor.mjs","names":["styles"],"sources":["../../../../../../../src/components/CodeEditor/CodeEditor.tsx"],"sourcesContent":["import type { ReactCodeMirrorProps } from \"@uiw/react-codemirror\";\nimport CodeMirror, { EditorView } from \"@uiw/react-codemirror\";\nimport { useCallback, useId, useState } from \"react\";\nimport {\n flowComponent,\n type FlowComponentProps,\n} from \"@/lib/componentFactory/flowComponent\";\nimport { useControlledHostValueProps } from \"@/lib/remote/useControlledHostValueProps\";\nimport { joinIds, useFieldComponent } from \"@/lib/hooks/useFieldComponent\";\nimport { type PropsContext, PropsContextProvider } from \"@/lib/propsContext\";\nimport clsx from \"clsx\";\nimport styles from \"./CodeEditor.module.scss\";\nimport { type CodeEditorLanguage } from \"@/components/CodeEditor/languages\";\nimport { useMakeFocusable } from \"@/lib/hooks/dom/useMakeFocusable\";\nimport { useObjectRef } from \"react-aria\";\nimport { defaultLightTheme } from \"@/components/CodeEditor/themes/defaultEditorTheme\";\nimport {\n type CodeEditorSetup,\n useCodeEditorExtensions,\n} from \"@/components/CodeEditor/hooks/useCodeEditorExtensions\";\nimport { CopyButton } from \"@/components/CopyButton\";\nimport { UiComponentTunnelExit } from \"@/components/UiComponentTunnel/UiComponentTunnelExit\";\n\nexport interface CodeEditorProps\n extends\n Omit<ReactCodeMirrorProps, \"theme\" | \"lang\" | \"basicSetup\" | \"readOnly\">,\n CodeEditorSetup,\n FlowComponentProps {\n /** The initial code of an uncontrolled editor. */\n defaultValue?: string;\n /**\n * Whether the code can be read but not edited.\n *\n * @default false\n */\n isReadOnly?: boolean;\n /**\n * Whether the editor is disabled. The code can neither be edited, focused nor\n * copied.\n *\n * @default false\n */\n isDisabled?: boolean;\n /**\n * Whether the editor is displayed as invalid.\n *\n * @default false\n */\n isInvalid?: boolean;\n /** The elements class name. */\n className?: string;\n /**\n * The language the code is highlighted as. A language the editor does not\n * know is shown as plain text.\n */\n language?: CodeEditorLanguage | (string & {});\n /**\n * Whether a button to copy the code to the clipboard is shown.\n *\n * @default true\n */\n copyable?: boolean;\n /**\n * Whether the field must be filled in. Only marks the editor as required for\n * assistive technology — the editor does not validate itself.\n *\n * @default false\n */\n isRequired?: boolean;\n /**\n * @internal Set by `<Field />` on every form field. The editor has no\n * react-aria validation to forward it to and drops it.\n */\n validationBehavior?: unknown;\n}\n\n/**\n * @flr-generate all\n * @flowStatus new\n */\nexport const CodeEditor = flowComponent(\"CodeEditor\", (props) => {\n const {\n ref,\n children,\n className,\n language,\n extensions,\n isReadOnly,\n isDisabled,\n isInvalid,\n isRequired,\n validationBehavior: _ignoredValidationBehavior,\n value,\n showLineNumbers = true,\n showCodeFolding = true,\n showCodeIndentationMakers = true,\n showLinterMarkers = true,\n showActiveLineMarker = true,\n copyable = true,\n height,\n minHeight,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n ...rest\n } = useControlledHostValueProps(props, \"\");\n\n const {\n FieldErrorView,\n FieldErrorCaptureContext,\n wrapperProps,\n controlProps,\n fieldPropsContext,\n } = useFieldComponent(props, \"CodeEditor\");\n\n const rootClassName = clsx(\n wrapperProps.className,\n styles.codeEditor,\n className,\n );\n\n const labelId = useId();\n const descriptionId = useId();\n\n /**\n * Both are optional. Their refs tell whether they are rendered, so the editor\n * never references an element that does not exist – a dangling id fails HTML\n * validators and a11y checks. The callbacks are stable: a new one per render\n * would detach and re-attach on every render.\n */\n const [hasLabel, setHasLabel] = useState(false);\n const [hasDescription, setHasDescription] = useState(false);\n const labelRef = useCallback((element: Element | null) => {\n setHasLabel(!!element);\n }, []);\n const descriptionRef = useCallback((element: Element | null) => {\n setHasDescription(!!element);\n }, []);\n\n /**\n * The label and the field description are declared as children of the code\n * editor, but must be rendered outside of the editor itself. They are\n * tunneled out of the editor – just like the field error. Their ids are the\n * ones the editor references.\n */\n const propsContext: PropsContext = {\n ...fieldPropsContext,\n Label: {\n ...fieldPropsContext.Label,\n id: labelId,\n ref: labelRef,\n tunnel: { id: \"label\", component: \"CodeEditor\" },\n },\n FieldDescription: {\n ...fieldPropsContext.FieldDescription,\n id: descriptionId,\n ref: descriptionRef,\n tunnel: { id: \"fieldDescription\", component: \"CodeEditor\" },\n },\n };\n\n const enabledExtensions = useCodeEditorExtensions(language, extensions, {\n showLineNumbers: showLineNumbers,\n showCodeIndentationMakers: showCodeIndentationMakers,\n showCodeFolding: showCodeFolding,\n showLinterMarkers: showLinterMarkers,\n });\n\n /**\n * The editable element of CodeMirror is the `.cm-content` element – not the\n * root element the props are applied to. Its ARIA attributes are set through\n * the content attributes facet.\n *\n * Without a label, an `aria-label` names the editor instead.\n */\n const labelledBy = joinIds(ariaLabelledBy, hasLabel && labelId);\n const describedBy = joinIds(\n hasDescription && descriptionId,\n controlProps[\"aria-describedby\"],\n );\n\n const contentAttributes = EditorView.contentAttributes.of({\n ...(labelledBy ? { \"aria-labelledby\": labelledBy } : {}),\n ...(ariaLabel ? { \"aria-label\": ariaLabel } : {}),\n ...(describedBy ? { \"aria-describedby\": describedBy } : {}),\n ...(isRequired ? { \"aria-required\": \"true\" } : {}),\n ...(isInvalid ? { \"aria-invalid\": \"true\" } : {}),\n ...(isDisabled ? { \"aria-disabled\": \"true\" } : {}),\n });\n\n const localRef = useObjectRef(ref);\n\n useMakeFocusable(localRef);\n\n return (\n <div className={rootClassName} data-disabled={isDisabled || undefined}>\n <PropsContextProvider props={propsContext}>\n <UiComponentTunnelExit id=\"label\" component=\"CodeEditor\" />\n <FieldErrorCaptureContext>\n <CodeMirror\n {...rest}\n value={value}\n basicSetup={{\n highlightActiveLine: showActiveLineMarker && !isDisabled,\n highlightActiveLineGutter: showActiveLineMarker && !isDisabled,\n autocompletion: false,\n lineNumbers: false,\n foldGutter: false,\n highlightSelectionMatches: false,\n }}\n theme={defaultLightTheme}\n data-invalid={isInvalid || undefined}\n data-disabled={isDisabled || undefined}\n readOnly={isReadOnly || isDisabled}\n editable={!isDisabled}\n className={clsx(styles.codeMirror, isReadOnly && styles.readonly)}\n ref={(codeMirrorRef) => {\n if (codeMirrorRef?.editor) {\n localRef.current = codeMirrorRef.editor;\n }\n }}\n extensions={[...enabledExtensions, contentAttributes]}\n height={height ?? minHeight}\n >\n {copyable && (\n <CopyButton\n className={styles.copyButton}\n size=\"s\"\n variant=\"soft\"\n text={value}\n isDisabled={isDisabled}\n />\n )}\n {children}\n </CodeMirror>\n </FieldErrorCaptureContext>\n <UiComponentTunnelExit id=\"fieldDescription\" component=\"CodeEditor\" />\n <FieldErrorView />\n </PropsContextProvider>\n </div>\n );\n});\n\nexport default CodeEditor;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CodeEditor.mjs","names":["styles"],"sources":["../../../../../../../src/components/CodeEditor/CodeEditor.tsx"],"sourcesContent":["import type { ReactCodeMirrorProps } from \"@uiw/react-codemirror\";\nimport CodeMirror, { EditorView } from \"@uiw/react-codemirror\";\nimport { useCallback, useId, useState } from \"react\";\nimport {\n flowComponent,\n type FlowComponentProps,\n} from \"@/lib/componentFactory/flowComponent\";\nimport { useControlledHostValueProps } from \"@/lib/remote/useControlledHostValueProps\";\nimport { joinIds, useFieldComponent } from \"@/lib/hooks/useFieldComponent\";\nimport { type PropsContext, PropsContextProvider } from \"@/lib/propsContext\";\nimport clsx from \"clsx\";\nimport styles from \"./CodeEditor.module.scss\";\nimport { type CodeEditorLanguage } from \"@/components/CodeEditor/languages\";\nimport { useMakeFocusable } from \"@/lib/hooks/dom/useMakeFocusable\";\nimport { useObjectRef } from \"react-aria\";\nimport { defaultLightTheme } from \"@/components/CodeEditor/themes/defaultEditorTheme\";\nimport {\n type CodeEditorSetup,\n useCodeEditorExtensions,\n} from \"@/components/CodeEditor/hooks/useCodeEditorExtensions\";\nimport { CopyButton } from \"@/components/CopyButton\";\nimport { UiComponentTunnelExit } from \"@/components/UiComponentTunnel/UiComponentTunnelExit\";\nimport { useSkeletonMode } from \"@/components/SkeletonMode/skeletonModeContext\";\n\nexport interface CodeEditorProps\n extends\n Omit<ReactCodeMirrorProps, \"theme\" | \"lang\" | \"basicSetup\" | \"readOnly\">,\n CodeEditorSetup,\n FlowComponentProps {\n /** The initial code of an uncontrolled editor. */\n defaultValue?: string;\n /**\n * Whether the code can be read but not edited.\n *\n * @default false\n */\n isReadOnly?: boolean;\n /**\n * Whether the editor is disabled. The code can neither be edited, focused nor\n * copied.\n *\n * @default false\n */\n isDisabled?: boolean;\n /**\n * Whether the editor is displayed as invalid.\n *\n * @default false\n */\n isInvalid?: boolean;\n /** The elements class name. */\n className?: string;\n /**\n * The language the code is highlighted as. A language the editor does not\n * know is shown as plain text.\n */\n language?: CodeEditorLanguage | (string & {});\n /**\n * Whether a button to copy the code to the clipboard is shown.\n *\n * @default true\n */\n copyable?: boolean;\n /**\n * Whether the field must be filled in. Only marks the editor as required for\n * assistive technology — the editor does not validate itself.\n *\n * @default false\n */\n isRequired?: boolean;\n /**\n * @internal Set by `<Field />` on every form field. The editor has no\n * react-aria validation to forward it to and drops it.\n */\n validationBehavior?: unknown;\n}\n\n/**\n * @flr-generate all\n * @flowStatus new\n */\nexport const CodeEditor = flowComponent(\"CodeEditor\", (props) => {\n const {\n ref,\n children,\n className,\n language,\n extensions,\n isReadOnly,\n isDisabled,\n isInvalid,\n isRequired,\n validationBehavior: _ignoredValidationBehavior,\n value,\n showLineNumbers = true,\n showCodeFolding = true,\n showCodeIndentationMakers = true,\n showLinterMarkers = true,\n showActiveLineMarker = true,\n copyable = true,\n height,\n minHeight,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n ...rest\n } = useControlledHostValueProps(props, \"\");\n\n const {\n FieldErrorView,\n FieldErrorCaptureContext,\n wrapperProps,\n controlProps,\n fieldPropsContext,\n } = useFieldComponent(props, \"CodeEditor\");\n\n const rootClassName = clsx(\n wrapperProps.className,\n styles.codeEditor,\n className,\n );\n\n const labelId = useId();\n const descriptionId = useId();\n\n /**\n * Both are optional. Their refs tell whether they are rendered, so the editor\n * never references an element that does not exist – a dangling id fails HTML\n * validators and a11y checks. The callbacks are stable: a new one per render\n * would detach and re-attach on every render.\n */\n const [hasLabel, setHasLabel] = useState(false);\n const [hasDescription, setHasDescription] = useState(false);\n const labelRef = useCallback((element: Element | null) => {\n setHasLabel(!!element);\n }, []);\n const descriptionRef = useCallback((element: Element | null) => {\n setHasDescription(!!element);\n }, []);\n\n /**\n * The label and the field description are declared as children of the code\n * editor, but must be rendered outside of the editor itself. They are\n * tunneled out of the editor – just like the field error. Their ids are the\n * ones the editor references.\n */\n const propsContext: PropsContext = {\n ...fieldPropsContext,\n Label: {\n ...fieldPropsContext.Label,\n id: labelId,\n ref: labelRef,\n tunnel: { id: \"label\", component: \"CodeEditor\" },\n },\n FieldDescription: {\n ...fieldPropsContext.FieldDescription,\n id: descriptionId,\n ref: descriptionRef,\n tunnel: { id: \"fieldDescription\", component: \"CodeEditor\" },\n },\n };\n\n const enabledExtensions = useCodeEditorExtensions(language, extensions, {\n showLineNumbers: showLineNumbers,\n showCodeIndentationMakers: showCodeIndentationMakers,\n showCodeFolding: showCodeFolding,\n showLinterMarkers: showLinterMarkers,\n });\n\n /**\n * The editable element of CodeMirror is the `.cm-content` element – not the\n * root element the props are applied to. Its ARIA attributes are set through\n * the content attributes facet.\n *\n * Without a label, an `aria-label` names the editor instead.\n */\n const labelledBy = joinIds(ariaLabelledBy, hasLabel && labelId);\n const describedBy = joinIds(\n hasDescription && descriptionId,\n controlProps[\"aria-describedby\"],\n );\n\n const contentAttributes = EditorView.contentAttributes.of({\n ...(labelledBy ? { \"aria-labelledby\": labelledBy } : {}),\n ...(ariaLabel ? { \"aria-label\": ariaLabel } : {}),\n ...(describedBy ? { \"aria-describedby\": describedBy } : {}),\n ...(isRequired ? { \"aria-required\": \"true\" } : {}),\n ...(isInvalid ? { \"aria-invalid\": \"true\" } : {}),\n ...(isDisabled ? { \"aria-disabled\": \"true\" } : {}),\n });\n\n const localRef = useObjectRef(ref);\n\n useMakeFocusable(localRef);\n\n const isSkeleton = useSkeletonMode();\n\n /* No CodeMirror: one surface, as high as the code in the editor's line\n height. The children still render, so a label or a field description\n tunnels out and follows its own skeleton rule. */\n const skeleton = (\n <div\n className={clsx(\n styles.codeMirror,\n isReadOnly && styles.readonly,\n styles.skeleton,\n )}\n >\n <div\n className={styles.skeletonLines}\n style={{ height: height ?? minHeight }}\n >\n {(value ?? \"\").split(\"\\n\").map((line, index) => (\n <div key={index}>{line || \" \"}</div>\n ))}\n </div>\n {children}\n </div>\n );\n\n const editor = (\n <CodeMirror\n {...rest}\n value={value}\n basicSetup={{\n highlightActiveLine: showActiveLineMarker && !isDisabled,\n highlightActiveLineGutter: showActiveLineMarker && !isDisabled,\n autocompletion: false,\n lineNumbers: false,\n foldGutter: false,\n highlightSelectionMatches: false,\n }}\n theme={defaultLightTheme}\n data-invalid={isInvalid || undefined}\n data-disabled={isDisabled || undefined}\n readOnly={isReadOnly || isDisabled}\n editable={!isDisabled}\n className={clsx(styles.codeMirror, isReadOnly && styles.readonly)}\n ref={(codeMirrorRef) => {\n if (codeMirrorRef?.editor) {\n localRef.current = codeMirrorRef.editor;\n }\n }}\n extensions={[...enabledExtensions, contentAttributes]}\n height={height ?? minHeight}\n >\n {copyable && (\n <CopyButton\n className={styles.copyButton}\n size=\"s\"\n variant=\"soft\"\n text={value}\n isDisabled={isDisabled}\n />\n )}\n {children}\n </CodeMirror>\n );\n\n return (\n <div\n className={rootClassName}\n data-disabled={isDisabled || undefined}\n inert={isSkeleton || undefined}\n >\n <PropsContextProvider props={propsContext}>\n <UiComponentTunnelExit id=\"label\" component=\"CodeEditor\" />\n <FieldErrorCaptureContext>\n {isSkeleton ? skeleton : editor}\n </FieldErrorCaptureContext>\n <UiComponentTunnelExit id=\"fieldDescription\" component=\"CodeEditor\" />\n <FieldErrorView />\n </PropsContextProvider>\n </div>\n );\n});\n\nexport default CodeEditor;\n"],"mappings":"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"}
|
|
@@ -5,13 +5,19 @@ var codeEditor = "flow--code-editor";
|
|
|
5
5
|
var codeMirror = "flow--code-editor--code-mirror";
|
|
6
6
|
var readonly = "flow--code-editor--readonly";
|
|
7
7
|
var copyButton = "flow--code-editor--copy-button";
|
|
8
|
+
var skeleton = "flow--code-editor--skeleton";
|
|
9
|
+
var skeletonLines = "flow--code-editor--skeleton-lines";
|
|
8
10
|
var CodeEditor_module_default = {
|
|
9
11
|
codeEditor,
|
|
10
12
|
codeMirror,
|
|
11
13
|
readonly,
|
|
12
|
-
copyButton
|
|
14
|
+
copyButton,
|
|
15
|
+
skeleton,
|
|
16
|
+
"skeleton-surface-shimmer": "flow--code-editor--skeleton-surface-shimmer",
|
|
17
|
+
skeletonLines,
|
|
18
|
+
"skeleton-text-shimmer": "flow--code-editor--skeleton-text-shimmer"
|
|
13
19
|
};
|
|
14
20
|
//#endregion
|
|
15
|
-
export { codeEditor, codeMirror, copyButton, CodeEditor_module_default as default, readonly };
|
|
21
|
+
export { codeEditor, codeMirror, copyButton, CodeEditor_module_default as default, readonly, skeleton, skeletonLines };
|
|
16
22
|
|
|
17
23
|
//# sourceMappingURL=CodeEditor.module.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeEditor.module.mjs","names":[],"sources":["../../../../../../../src/components/CodeEditor/CodeEditor.module.scss"],"sourcesContent":["@use \"@/styles/mixins/formControl\";\n@use \"@/styles/mixins/scrollbar\";\n\n.codeEditor {\n outline: none;\n isolation: isolate;\n\n .codeMirror {\n @include formControl.formControl();\n\n position: relative;\n order: 2;\n\n /*\n * The inline padding is applied by the lines and the gutter instead, so\n * that the highlight of the active line spans the full editor width.\n */\n padding-inline: unset;\n\n /* the vertical padding applied by the form control mixin */\n --editor-padding: calc(\n var(--form-control--padding-y) - var(--form-control--border-width)\n );\n\n min-height: calc(var(--form-control--padding-y) * 2 + var(--line-height-m));\n\n &:hover {\n background-color: var(--form-control--background-color--default);\n }\n\n &.readonly {\n border-color: var(--form-control--border-color--default);\n }\n\n &[data-disabled] {\n --code-editor--gutter-separator-color: var(\n --form-control--border-color--disabled\n );\n --code-editor--indentation-marker-color: var(\n --form-control--border-color--disabled\n );\n\n background-color: var(--form-control--background-color--disabled);\n }\n\n .copyButton {\n position: absolute;\n inset-block-start: var(--editor-padding);\n inset-inline-end: var(--form-control--padding-x);\n z-index: 1;\n }\n }\n}\n\n/*\n * CodeMirror ships its theme as unlayered `<style>` elements that it injects\n * into the document at runtime, outside of Flow's build. Unlayered CSS beats\n * layered CSS regardless of specificity, so these overrides only apply in the\n * layered stylesheet variant if they leave the cascade layer as well.\n */\n@layer flow.unlayered {\n .codeEditor .codeMirror {\n /*\n * The gutter needs an opaque background – the content scrolls underneath\n * it – but it must follow the background of the editor, which changes with\n * its state (invalid, disabled, …). Inheriting it down from the editor\n * beats the background the CodeMirror theme applies, which only serves as\n * a fallback.\n */\n & :global(.cm-editor),\n & :global(.cm-scroller),\n & :global(.cm-gutters) {\n background-color: inherit;\n }\n\n /* The same goes for the text color of the code and the line numbers. */\n & :global(.cm-editor),\n & :global(.cm-gutters) {\n color: inherit;\n }\n\n /* Syntax highlighting would make disabled code look editable. */\n &[data-disabled] :global(.cm-content *) {\n color: inherit;\n }\n\n & :global(.cm-editor) {\n outline: none;\n\n & :global(.cm-scroller) {\n @include scrollbar.scrollbar;\n }\n\n & :global(.cm-lineNumbers .cm-gutterElement) {\n min-width: var(--code-editor--gutter-element-min-width);\n }\n\n & :global(.cm-foldGutter) {\n min-width: var(--code-editor--gutter-element-min-width);\n text-align: center;\n }\n\n & :global(.cm-panels) {\n display: none;\n }\n\n /* the block padding is applied by the editor itself */\n & :global(.cm-content) {\n padding-block: unset;\n }\n\n & :global(.cm-line) {\n padding-inline: var(--form-control--padding-x);\n }\n\n /*\n * The elements of the first gutter carry the inline start padding, so\n * that the highlight of the active line reaches the editor border.\n */\n & :global(.cm-gutters > .cm-gutter:first-child .cm-gutterElement) {\n padding-inline-start: var(--form-control--padding-x);\n }\n\n & :global(.cm-activeLineGutter),\n & :global(.cm-activeLine) {\n background-color: color-mix(\n in srgb,\n var(--form-control--background-color--hover) 65%,\n transparent\n );\n }\n }\n }\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"CodeEditor.module.mjs","names":[],"sources":["../../../../../../../src/components/CodeEditor/CodeEditor.module.scss"],"sourcesContent":["@use \"@/styles/mixins/formControl\";\n@use \"@/styles/mixins/scrollbar\";\n@use \"@/styles/mixins/skeleton\";\n\n.codeEditor {\n outline: none;\n isolation: isolate;\n\n .codeMirror {\n @include formControl.formControl();\n\n position: relative;\n order: 2;\n\n /*\n * The inline padding is applied by the lines and the gutter instead, so\n * that the highlight of the active line spans the full editor width.\n */\n padding-inline: unset;\n\n /* the vertical padding applied by the form control mixin */\n --editor-padding: calc(\n var(--form-control--padding-y) - var(--form-control--border-width)\n );\n\n min-height: calc(var(--form-control--padding-y) * 2 + var(--line-height-m));\n\n &:hover {\n background-color: var(--form-control--background-color--default);\n }\n\n &.readonly {\n border-color: var(--form-control--border-color--default);\n }\n\n &[data-disabled] {\n --code-editor--gutter-separator-color: var(\n --form-control--border-color--disabled\n );\n --code-editor--indentation-marker-color: var(\n --form-control--border-color--disabled\n );\n\n background-color: var(--form-control--background-color--disabled);\n }\n\n .copyButton {\n position: absolute;\n inset-block-start: var(--editor-padding);\n inset-inline-end: var(--form-control--padding-x);\n z-index: 1;\n }\n\n /* SkeletonMode — after the states, so the surface wins over their colors */\n\n &.skeleton {\n @include skeleton.shape;\n\n --skeleton-radius: var(--form-control--corner-radius);\n }\n\n /* Stands in for CodeMirror's lines, so the surface is as high as the code. */\n .skeletonLines {\n font-family: var(--code-editor--font-family);\n font-size: var(--code-editor--font-size);\n line-height: 1.4;\n white-space: pre;\n }\n }\n}\n\n@include skeleton.keyframes;\n\n/*\n * CodeMirror ships its theme as unlayered `<style>` elements that it injects\n * into the document at runtime, outside of Flow's build. Unlayered CSS beats\n * layered CSS regardless of specificity, so these overrides only apply in the\n * layered stylesheet variant if they leave the cascade layer as well.\n */\n@layer flow.unlayered {\n .codeEditor .codeMirror {\n /*\n * The gutter needs an opaque background – the content scrolls underneath\n * it – but it must follow the background of the editor, which changes with\n * its state (invalid, disabled, …). Inheriting it down from the editor\n * beats the background the CodeMirror theme applies, which only serves as\n * a fallback.\n */\n & :global(.cm-editor),\n & :global(.cm-scroller),\n & :global(.cm-gutters) {\n background-color: inherit;\n }\n\n /* The same goes for the text color of the code and the line numbers. */\n & :global(.cm-editor),\n & :global(.cm-gutters) {\n color: inherit;\n }\n\n /* Syntax highlighting would make disabled code look editable. */\n &[data-disabled] :global(.cm-content *) {\n color: inherit;\n }\n\n & :global(.cm-editor) {\n outline: none;\n\n & :global(.cm-scroller) {\n @include scrollbar.scrollbar;\n }\n\n & :global(.cm-lineNumbers .cm-gutterElement) {\n min-width: var(--code-editor--gutter-element-min-width);\n }\n\n & :global(.cm-foldGutter) {\n min-width: var(--code-editor--gutter-element-min-width);\n text-align: center;\n }\n\n & :global(.cm-panels) {\n display: none;\n }\n\n /* the block padding is applied by the editor itself */\n & :global(.cm-content) {\n padding-block: unset;\n }\n\n & :global(.cm-line) {\n padding-inline: var(--form-control--padding-x);\n }\n\n /*\n * The elements of the first gutter carry the inline start padding, so\n * that the highlight of the active line reaches the editor border.\n */\n & :global(.cm-gutters > .cm-gutter:first-child .cm-gutterElement) {\n padding-inline-start: var(--form-control--padding-x);\n }\n\n & :global(.cm-activeLineGutter),\n & :global(.cm-activeLine) {\n background-color: color-mix(\n in srgb,\n var(--form-control--background-color--hover) 65%,\n transparent\n );\n }\n }\n }\n}\n"],"mappings":""}
|