@alchemy.run/sigil 0.0.0-alpha.1 → 0.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/README.md +299 -299
  2. package/dist/ansi.d.ts +223 -0
  3. package/dist/ansi.js +2 -0
  4. package/dist/{devtools-QpCMm9JH.mjs → devtools-BhYGjb7h.js} +1 -1
  5. package/dist/index-DDVME65c.d.ts +919 -0
  6. package/dist/index.d.ts +1657 -0
  7. package/dist/index.js +4643 -0
  8. package/dist/sgr-CMfEpjSk.d.ts +91 -0
  9. package/dist/truncate-CBiyyZzw.js +2156 -0
  10. package/dist/yoga-5jKhYCJC.js +3465 -0
  11. package/dist/yoga.d.ts +2 -0
  12. package/dist/yoga.js +2 -0
  13. package/package.json +37 -17
  14. package/src/ansi/chalk.ts +179 -0
  15. package/src/ansi/cursor.ts +48 -0
  16. package/src/ansi/east-asian-width.ts +215 -0
  17. package/src/ansi/escapes.ts +128 -0
  18. package/src/ansi/index.ts +27 -0
  19. package/src/ansi/sgr.ts +237 -0
  20. package/src/ansi/slice.ts +43 -0
  21. package/src/ansi/string-width.ts +236 -0
  22. package/src/ansi/strip.ts +33 -0
  23. package/src/ansi/supports-color.ts +213 -0
  24. package/src/ansi/tokenize.ts +453 -0
  25. package/src/ansi/truncate.ts +194 -0
  26. package/src/ansi/widest-line.ts +12 -0
  27. package/src/ansi/wrap.ts +766 -0
  28. package/src/ansi-tokenizer.ts +510 -0
  29. package/src/auto-bind.ts +41 -0
  30. package/src/boxes.ts +100 -0
  31. package/src/code-excerpt.ts +39 -0
  32. package/src/colorize.ts +60 -0
  33. package/src/components/AccessibilityContext.ts +5 -0
  34. package/src/components/AnimationContext.ts +24 -0
  35. package/src/components/App.tsx +781 -0
  36. package/src/components/AppContext.ts +111 -0
  37. package/src/components/BackgroundContext.ts +8 -0
  38. package/src/components/Box.tsx +116 -0
  39. package/src/components/CursorContext.ts +19 -0
  40. package/src/components/ErrorBoundary.tsx +38 -0
  41. package/src/components/ErrorOverview.tsx +133 -0
  42. package/src/components/FocusContext.ts +30 -0
  43. package/src/components/Newline.tsx +15 -0
  44. package/src/components/Spacer.tsx +10 -0
  45. package/src/components/Static.tsx +59 -0
  46. package/src/components/StderrContext.ts +26 -0
  47. package/src/components/StdinContext.ts +49 -0
  48. package/src/components/StdoutContext.ts +28 -0
  49. package/src/components/Text.tsx +144 -0
  50. package/src/components/Transform.tsx +37 -0
  51. package/src/cursor-position.ts +103 -0
  52. package/src/devtools-window-polyfill.ts +73 -0
  53. package/src/devtools.ts +43 -0
  54. package/src/dom.ts +292 -0
  55. package/src/get-max-width.ts +11 -0
  56. package/src/global.d.ts +36 -0
  57. package/src/hooks/use-animation.ts +142 -0
  58. package/src/hooks/use-app.ts +8 -0
  59. package/src/hooks/use-box-metrics.ts +134 -0
  60. package/src/hooks/use-cursor.ts +33 -0
  61. package/src/hooks/use-focus-manager.ts +62 -0
  62. package/src/hooks/use-focus.ts +83 -0
  63. package/src/hooks/use-input.ts +267 -0
  64. package/src/hooks/use-is-screen-reader-enabled.ts +12 -0
  65. package/src/hooks/use-paste.ts +78 -0
  66. package/src/hooks/use-stderr.ts +8 -0
  67. package/src/hooks/use-stdin.ts +10 -0
  68. package/src/hooks/use-stdout.ts +8 -0
  69. package/src/hooks/use-window-size.ts +41 -0
  70. package/src/indent-string.ts +16 -0
  71. package/src/index.ts +44 -0
  72. package/src/ink.tsx +1506 -0
  73. package/src/input-parser.ts +283 -0
  74. package/src/instances.ts +9 -0
  75. package/src/is-in-ci.ts +7 -0
  76. package/src/kitty-keyboard.ts +57 -0
  77. package/src/log-update.ts +370 -0
  78. package/src/measure-element.ts +62 -0
  79. package/src/measure-text.ts +31 -0
  80. package/src/output.ts +308 -0
  81. package/src/parse-keypress.ts +516 -0
  82. package/src/parse-stack-line.ts +139 -0
  83. package/src/patch-console.ts +62 -0
  84. package/src/quick-lru.ts +85 -0
  85. package/src/reconciler.ts +451 -0
  86. package/src/render-background.ts +38 -0
  87. package/src/render-border.ts +134 -0
  88. package/src/render-node-to-output.ts +191 -0
  89. package/src/render-to-string.ts +131 -0
  90. package/src/render.ts +276 -0
  91. package/src/renderer.ts +73 -0
  92. package/src/sanitize-ansi.ts +33 -0
  93. package/src/signal-exit.ts +107 -0
  94. package/src/squash-text-nodes.ts +40 -0
  95. package/src/stream.ts +30 -0
  96. package/src/styles.ts +748 -0
  97. package/src/terminal-size.ts +57 -0
  98. package/src/throttle.ts +73 -0
  99. package/src/types.ts +15 -0
  100. package/src/utils.ts +40 -0
  101. package/src/wrap-text.ts +50 -0
  102. package/src/write-synchronized.ts +9 -0
  103. package/src/yoga/config.ts +57 -0
  104. package/src/yoga/core/absoluteLayout.ts +626 -0
  105. package/src/yoga/core/baseline.ts +66 -0
  106. package/src/yoga/core/cache.ts +136 -0
  107. package/src/yoga/core/calculateLayout.ts +2920 -0
  108. package/src/yoga/core/config.ts +104 -0
  109. package/src/yoga/core/flexLine.ts +177 -0
  110. package/src/yoga/core/helpers.ts +293 -0
  111. package/src/yoga/core/layoutResults.ts +167 -0
  112. package/src/yoga/core/node.ts +611 -0
  113. package/src/yoga/core/numeric.ts +44 -0
  114. package/src/yoga/core/pixelGrid.ts +151 -0
  115. package/src/yoga/core/style.ts +887 -0
  116. package/src/yoga/core/types.ts +224 -0
  117. package/src/yoga/generated/YGEnums.ts +263 -0
  118. package/src/yoga/index.ts +19 -0
  119. package/src/yoga/node.ts +1140 -0
  120. package/dist/index.d.mts +0 -2379
  121. package/dist/index.mjs +0 -10072
@@ -0,0 +1,104 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Derived from Yoga. See THIRD_PARTY_NOTICES.md.
3
+
4
+ // Port of yoga/config/Config.h and yoga/config/Config.cpp.
5
+
6
+ import { Errata, ExperimentalFeature } from "../generated/YGEnums.ts";
7
+
8
+ // Whether moving a node from an old to new config should dirty previously
9
+ // calculated layout results.
10
+ export function configUpdateInvalidatesLayout(oldConfig: Config, newConfig: Config): boolean {
11
+ return (
12
+ oldConfig.getErrata() !== newConfig.getErrata() ||
13
+ oldConfig.getEnabledExperiments() !== newConfig.getEnabledExperiments() ||
14
+ oldConfig.getPointScaleFactor() !== newConfig.getPointScaleFactor() ||
15
+ oldConfig.useWebDefaults() !== newConfig.useWebDefaults()
16
+ );
17
+ }
18
+
19
+ export class Config {
20
+ private useWebDefaults_ = false;
21
+ private version_ = 0;
22
+ private experimentalFeatures_ = 0;
23
+ private errata_: Errata = Errata.MinSizeUndefinedInsteadOfAuto;
24
+ private pointScaleFactor_ = 1.0;
25
+
26
+ setUseWebDefaults(useWebDefaults: boolean): void {
27
+ this.useWebDefaults_ = useWebDefaults;
28
+ }
29
+
30
+ useWebDefaults(): boolean {
31
+ return this.useWebDefaults_;
32
+ }
33
+
34
+ setExperimentalFeatureEnabled(feature: ExperimentalFeature, enabled: boolean): void {
35
+ if (this.isExperimentalFeatureEnabled(feature) !== enabled) {
36
+ this.experimentalFeatures_ = enabled
37
+ ? this.experimentalFeatures_ | (1 << feature)
38
+ : this.experimentalFeatures_ & ~(1 << feature);
39
+ this.version_++;
40
+ }
41
+ }
42
+
43
+ isExperimentalFeatureEnabled(feature: ExperimentalFeature): boolean {
44
+ return (this.experimentalFeatures_ & (1 << feature)) !== 0;
45
+ }
46
+
47
+ getEnabledExperiments(): number {
48
+ return this.experimentalFeatures_;
49
+ }
50
+
51
+ setErrata(errata: Errata): void {
52
+ if (this.errata_ !== errata) {
53
+ this.errata_ = errata;
54
+ this.version_++;
55
+ }
56
+ }
57
+
58
+ addErrata(errata: Errata): void {
59
+ if (!this.hasErrata(errata)) {
60
+ this.errata_ |= errata;
61
+ this.version_++;
62
+ }
63
+ }
64
+
65
+ removeErrata(errata: Errata): void {
66
+ if (this.hasErrata(errata)) {
67
+ this.errata_ &= ~errata;
68
+ this.version_++;
69
+ }
70
+ }
71
+
72
+ getErrata(): Errata {
73
+ return this.errata_;
74
+ }
75
+
76
+ hasErrata(errata: Errata): boolean {
77
+ return (this.errata_ & errata) !== Errata.None;
78
+ }
79
+
80
+ setPointScaleFactor(pointScaleFactor: number): void {
81
+ const value = pointScaleFactor;
82
+ if (this.pointScaleFactor_ !== value) {
83
+ this.pointScaleFactor_ = value;
84
+ this.version_++;
85
+ }
86
+ }
87
+
88
+ getPointScaleFactor(): number {
89
+ return this.pointScaleFactor_;
90
+ }
91
+
92
+ getVersion(): number {
93
+ return this.version_;
94
+ }
95
+ }
96
+
97
+ let defaultConfig: Config | null = null;
98
+
99
+ export function getDefaultConfig(): Config {
100
+ if (defaultConfig === null) {
101
+ defaultConfig = new Config();
102
+ }
103
+ return defaultConfig;
104
+ }
@@ -0,0 +1,177 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Derived from Yoga. See THIRD_PARTY_NOTICES.md.
3
+
4
+ // Port of yoga/algorithm/FlexLine.h and yoga/algorithm/FlexLine.cpp.
5
+ //
6
+ // The C++ version advances a shared LayoutableChildren iterator; here the
7
+ // caller materializes the layout children into an array once and this function
8
+ // receives the start index, returning the index of the first child of the next
9
+ // line alongside the line itself.
10
+
11
+ import { Direction, Display, PositionType, Wrap } from "../generated/YGEnums.ts";
12
+ import { boundAxisWithinMinAndMax, resolveDirection } from "./helpers.ts";
13
+ import type { Node } from "./node.ts";
14
+
15
+ export interface FlexLineRunningLayout {
16
+ // Total flex grow factors of flex items which are to be laid in the current
17
+ // line. This is decremented as free space is distributed.
18
+ totalFlexGrowFactors: number;
19
+
20
+ // Total flex shrink factors of flex items which are to be laid in the
21
+ // current line. This is decremented as free space is distributed.
22
+ totalFlexShrinkScaledFactors: number;
23
+
24
+ // The amount of available space within inner dimensions of the line which
25
+ // may still be distributed.
26
+ remainingFreeSpace: number;
27
+
28
+ // The size of the mainDim for the row after considering size, padding,
29
+ // margin and border of flex items. This is used to calculate maxLineDim
30
+ // after going through all the rows to decide on the main axis size of owner.
31
+ mainDim: number;
32
+
33
+ // The size of the crossDim for the row after considering size, padding,
34
+ // margin and border of flex items. Used for calculating containers
35
+ // crossSize.
36
+ crossDim: number;
37
+ }
38
+
39
+ export interface FlexLine {
40
+ // List of children which are part of the line flow. This means they are not
41
+ // positioned absolutely, or with `display: "none"`, and do not overflow the
42
+ // available dimensions.
43
+ itemsInFlow: Node[];
44
+
45
+ // Accumulation of the dimensions and margin of all the children on the
46
+ // current line. This will be used in order to either set the dimensions of
47
+ // the node if none already exist or to compute the remaining space left for
48
+ // the flexible children.
49
+ sizeConsumed: number;
50
+
51
+ // Number of edges along the line flow with an auto margin.
52
+ numberOfAutoMargins: number;
53
+
54
+ // Index into the layout-children array of the first child of the next line.
55
+ endIndex: number;
56
+
57
+ // Layout information about the line computed in steps after line-breaking
58
+ layout: FlexLineRunningLayout;
59
+ }
60
+
61
+ // Calculates where a line starting at a given index should break, returning
62
+ // information about the collective children on the line.
63
+ //
64
+ // This function assumes that all the children of node have their
65
+ // computedFlexBasis properly computed (to do this use the
66
+ // computeFlexBasisForChildren function).
67
+ export function calculateFlexLine(
68
+ node: Node,
69
+ ownerDirection: Direction,
70
+ ownerWidth: number,
71
+ mainAxisOwnerSize: number,
72
+ availableInnerWidth: number,
73
+ availableInnerMainDim: number,
74
+ layoutChildren: readonly Node[],
75
+ startIndex: number,
76
+ lineCount: number,
77
+ flexLine: FlexLine,
78
+ ): void {
79
+ const itemsInFlow = flexLine.itemsInFlow;
80
+ itemsInFlow.length = 0;
81
+
82
+ let sizeConsumed = 0;
83
+ let totalFlexGrowFactors = 0;
84
+ let totalFlexShrinkScaledFactors = 0;
85
+ let numberOfAutoMargins = 0;
86
+ let firstElementInLine: Node | null = null;
87
+
88
+ let sizeConsumedIncludingMinConstraint = 0;
89
+ const direction = node.resolveDirection(ownerDirection);
90
+ const mainAxis = resolveDirection(node.style.flexDirection(), direction);
91
+ const isNodeFlexWrap = node.style.flexWrap() !== Wrap.NoWrap;
92
+ const gap = node.style.computeGapForAxis(mainAxis, availableInnerMainDim);
93
+
94
+ let index = startIndex;
95
+ // Add items to the current line until it's full or we run out of items.
96
+ for (; index < layoutChildren.length; index++) {
97
+ const child = layoutChildren[index]!;
98
+ if (
99
+ child.style.display() === Display.None ||
100
+ child.style.positionType() === PositionType.Absolute
101
+ ) {
102
+ continue;
103
+ }
104
+
105
+ if (firstElementInLine === null) {
106
+ firstElementInLine = child;
107
+ }
108
+
109
+ if (child.style.flexStartMarginIsAuto(mainAxis, ownerDirection)) {
110
+ numberOfAutoMargins++;
111
+ }
112
+ if (child.style.flexEndMarginIsAuto(mainAxis, ownerDirection)) {
113
+ numberOfAutoMargins++;
114
+ }
115
+
116
+ child.lineIndex = lineCount;
117
+ const childMarginMainAxis = child.style.computeMarginForAxis(mainAxis, availableInnerWidth);
118
+ const childLeadingGapMainAxis = child === firstElementInLine ? 0 : gap;
119
+ const flexBasisWithMinAndMaxConstraints = boundAxisWithinMinAndMax(
120
+ child,
121
+ direction,
122
+ mainAxis,
123
+ child.layout.computedFlexBasis,
124
+ mainAxisOwnerSize,
125
+ ownerWidth,
126
+ );
127
+
128
+ // If this is a multi-line flow and this item pushes us over the available
129
+ // size, we've hit the end of the current line. Break out of the loop and
130
+ // lay out the current line.
131
+ if (
132
+ sizeConsumedIncludingMinConstraint +
133
+ flexBasisWithMinAndMaxConstraints +
134
+ childMarginMainAxis +
135
+ childLeadingGapMainAxis >
136
+ availableInnerMainDim &&
137
+ isNodeFlexWrap &&
138
+ itemsInFlow.length > 0
139
+ ) {
140
+ break;
141
+ }
142
+
143
+ sizeConsumedIncludingMinConstraint +=
144
+ flexBasisWithMinAndMaxConstraints + childMarginMainAxis + childLeadingGapMainAxis;
145
+ sizeConsumed +=
146
+ flexBasisWithMinAndMaxConstraints + childMarginMainAxis + childLeadingGapMainAxis;
147
+
148
+ if (child.isNodeFlexible()) {
149
+ totalFlexGrowFactors += child.resolveFlexGrow();
150
+
151
+ // Unlike the grow factor, the shrink factor is scaled relative to the
152
+ // child dimension.
153
+ totalFlexShrinkScaledFactors += -child.resolveFlexShrink() * child.layout.computedFlexBasis;
154
+ }
155
+
156
+ itemsInFlow.push(child);
157
+ }
158
+
159
+ // The total flex factor needs to be floored to 1.
160
+ if (totalFlexGrowFactors > 0 && totalFlexGrowFactors < 1) {
161
+ totalFlexGrowFactors = 1;
162
+ }
163
+
164
+ // The total flex shrink factor needs to be floored to 1.
165
+ if (totalFlexShrinkScaledFactors > 0 && totalFlexShrinkScaledFactors < 1) {
166
+ totalFlexShrinkScaledFactors = 1;
167
+ }
168
+
169
+ flexLine.sizeConsumed = sizeConsumed;
170
+ flexLine.numberOfAutoMargins = numberOfAutoMargins;
171
+ flexLine.endIndex = index;
172
+ flexLine.layout.totalFlexGrowFactors = totalFlexGrowFactors;
173
+ flexLine.layout.totalFlexShrinkScaledFactors = totalFlexShrinkScaledFactors;
174
+ flexLine.layout.remainingFreeSpace = 0;
175
+ flexLine.layout.mainDim = 0;
176
+ flexLine.layout.crossDim = 0;
177
+ }
@@ -0,0 +1,293 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Derived from Yoga. See THIRD_PARTY_NOTICES.md.
3
+
4
+ // Port of yoga/algorithm/FlexDirection.h, yoga/algorithm/Align.h,
5
+ // yoga/algorithm/SizingMode.h, yoga/algorithm/TrailingPosition.h and
6
+ // yoga/algorithm/BoundAxis.h, plus the internal PhysicalEdge enum.
7
+
8
+ import {
9
+ Align,
10
+ Dimension,
11
+ Direction,
12
+ Display,
13
+ FlexDirection,
14
+ Justify,
15
+ MeasureMode,
16
+ } from "../generated/YGEnums.ts";
17
+ import type { Node } from "./node.ts";
18
+ import { maxOrDefined } from "./numeric.ts";
19
+
20
+ export const PhysicalEdge = {
21
+ Left: 0,
22
+ Top: 1,
23
+ Right: 2,
24
+ Bottom: 3,
25
+ } as const;
26
+ export type PhysicalEdge = (typeof PhysicalEdge)[keyof typeof PhysicalEdge];
27
+
28
+ // Port of yoga/algorithm/SizingMode.h
29
+ export const SizingMode = {
30
+ StretchFit: 0,
31
+ MaxContent: 1,
32
+ FitContent: 2,
33
+ } as const;
34
+ export type SizingMode = (typeof SizingMode)[keyof typeof SizingMode];
35
+
36
+ export function measureMode(mode: SizingMode): MeasureMode {
37
+ switch (mode) {
38
+ case SizingMode.StretchFit:
39
+ return MeasureMode.Exactly;
40
+ case SizingMode.MaxContent:
41
+ return MeasureMode.Undefined;
42
+ case SizingMode.FitContent:
43
+ return MeasureMode.AtMost;
44
+ }
45
+ }
46
+
47
+ export function sizingMode(mode: MeasureMode): SizingMode {
48
+ switch (mode) {
49
+ case MeasureMode.Exactly:
50
+ return SizingMode.StretchFit;
51
+ case MeasureMode.Undefined:
52
+ return SizingMode.MaxContent;
53
+ case MeasureMode.AtMost:
54
+ return SizingMode.FitContent;
55
+ }
56
+ }
57
+
58
+ // Port of yoga/algorithm/FlexDirection.h
59
+
60
+ export function isRow(flexDirection: FlexDirection): boolean {
61
+ return (flexDirection & FlexDirection.Row) !== 0;
62
+ }
63
+
64
+ export function isColumn(flexDirection: FlexDirection): boolean {
65
+ return (flexDirection & FlexDirection.Row) === 0;
66
+ }
67
+
68
+ export function resolveDirection(
69
+ flexDirection: FlexDirection,
70
+ direction: Direction,
71
+ ): FlexDirection {
72
+ if (direction === Direction.RTL) {
73
+ if (flexDirection === FlexDirection.Row) {
74
+ return FlexDirection.RowReverse;
75
+ } else if (flexDirection === FlexDirection.RowReverse) {
76
+ return FlexDirection.Row;
77
+ }
78
+ }
79
+
80
+ return flexDirection;
81
+ }
82
+
83
+ export function resolveCrossDirection(
84
+ flexDirection: FlexDirection,
85
+ direction: Direction,
86
+ ): FlexDirection {
87
+ return isColumn(flexDirection)
88
+ ? resolveDirection(FlexDirection.Row, direction)
89
+ : FlexDirection.Column;
90
+ }
91
+
92
+ // Table-lookup forms of the per-axis switches, indexed by FlexDirection
93
+ // (Column, ColumnReverse, Row, RowReverse).
94
+ const FLEX_START_EDGE = [
95
+ PhysicalEdge.Top,
96
+ PhysicalEdge.Bottom,
97
+ PhysicalEdge.Left,
98
+ PhysicalEdge.Right,
99
+ ] as const;
100
+
101
+ const FLEX_END_EDGE = [
102
+ PhysicalEdge.Bottom,
103
+ PhysicalEdge.Top,
104
+ PhysicalEdge.Right,
105
+ PhysicalEdge.Left,
106
+ ] as const;
107
+
108
+ const DIMENSION_OF_AXIS = [
109
+ Dimension.Height,
110
+ Dimension.Height,
111
+ Dimension.Width,
112
+ Dimension.Width,
113
+ ] as const;
114
+
115
+ export function flexStartEdge(flexDirection: FlexDirection): PhysicalEdge {
116
+ return FLEX_START_EDGE[flexDirection];
117
+ }
118
+
119
+ export function flexEndEdge(flexDirection: FlexDirection): PhysicalEdge {
120
+ return FLEX_END_EDGE[flexDirection];
121
+ }
122
+
123
+ export function inlineStartEdge(flexDirection: FlexDirection, direction: Direction): PhysicalEdge {
124
+ if (isRow(flexDirection)) {
125
+ return direction === Direction.RTL ? PhysicalEdge.Right : PhysicalEdge.Left;
126
+ }
127
+
128
+ return PhysicalEdge.Top;
129
+ }
130
+
131
+ export function inlineEndEdge(flexDirection: FlexDirection, direction: Direction): PhysicalEdge {
132
+ if (isRow(flexDirection)) {
133
+ return direction === Direction.RTL ? PhysicalEdge.Left : PhysicalEdge.Right;
134
+ }
135
+
136
+ return PhysicalEdge.Bottom;
137
+ }
138
+
139
+ export function dimension(flexDirection: FlexDirection): Dimension {
140
+ return DIMENSION_OF_AXIS[flexDirection];
141
+ }
142
+
143
+ // Port of yoga/algorithm/Align.h
144
+
145
+ export function resolveChildAlignment(node: Node, child: Node): Align {
146
+ const align =
147
+ child.style.alignSelf() === Align.Auto ? node.style.alignItems() : child.style.alignSelf();
148
+
149
+ if (
150
+ node.style.display() === Display.Flex &&
151
+ align === Align.Baseline &&
152
+ isColumn(node.style.flexDirection())
153
+ ) {
154
+ return Align.FlexStart;
155
+ }
156
+
157
+ return align;
158
+ }
159
+
160
+ export function resolveChildJustification(node: Node, child: Node): Justify {
161
+ return child.style.justifySelf() === Justify.Auto
162
+ ? node.style.justifyItems()
163
+ : child.style.justifySelf();
164
+ }
165
+
166
+ /**
167
+ * Fallback alignment to use on overflow
168
+ * https://www.w3.org/TR/css-align-3/#distribution-values
169
+ */
170
+ export function fallbackAlignment(align: Align): Align {
171
+ switch (align) {
172
+ // Fallback to flex-start
173
+ case Align.SpaceBetween:
174
+ case Align.Stretch:
175
+ return Align.FlexStart;
176
+
177
+ // Fallback to safe center. TODO (T208209388): This should be aligned to
178
+ // Start instead of FlexStart (for row-reverse containers)
179
+ case Align.SpaceAround:
180
+ case Align.SpaceEvenly:
181
+ return Align.FlexStart;
182
+ default:
183
+ return align;
184
+ }
185
+ }
186
+
187
+ export function fallbackJustification(align: Justify): Justify {
188
+ switch (align) {
189
+ // Fallback to flex-start
190
+ case Justify.SpaceBetween:
191
+ return Justify.FlexStart;
192
+
193
+ // Fallback to safe center. TODO (T208209388): This should be aligned to
194
+ // Start instead of FlexStart (for row-reverse containers)
195
+ case Justify.SpaceAround:
196
+ case Justify.SpaceEvenly:
197
+ return Justify.FlexStart;
198
+ default:
199
+ return align;
200
+ }
201
+ }
202
+
203
+ // Port of yoga/algorithm/BoundAxis.h
204
+
205
+ export function paddingAndBorderForAxis(
206
+ node: Node,
207
+ axis: FlexDirection,
208
+ direction: Direction,
209
+ widthSize: number,
210
+ ): number {
211
+ if (!node.style.hasPaddingOrBorder()) {
212
+ return 0;
213
+ }
214
+ return (
215
+ node.style.computeInlineStartPaddingAndBorder(axis, direction, widthSize) +
216
+ node.style.computeInlineEndPaddingAndBorder(axis, direction, widthSize)
217
+ );
218
+ }
219
+
220
+ export function boundAxisWithinMinAndMax(
221
+ node: Node,
222
+ direction: Direction,
223
+ axis: FlexDirection,
224
+ value: number,
225
+ axisSize: number,
226
+ widthSize: number,
227
+ ): number {
228
+ let min = NaN;
229
+ let max = NaN;
230
+
231
+ if (isColumn(axis)) {
232
+ min = node.style.resolvedMinDimension(direction, Dimension.Height, axisSize, widthSize);
233
+ max = node.style.resolvedMaxDimension(direction, Dimension.Height, axisSize, widthSize);
234
+ } else if (isRow(axis)) {
235
+ min = node.style.resolvedMinDimension(direction, Dimension.Width, axisSize, widthSize);
236
+ max = node.style.resolvedMaxDimension(direction, Dimension.Width, axisSize, widthSize);
237
+ }
238
+
239
+ if (max >= 0 && value > max) {
240
+ return max;
241
+ }
242
+
243
+ if (min >= 0 && value < min) {
244
+ return min;
245
+ }
246
+
247
+ return value;
248
+ }
249
+
250
+ // Like boundAxisWithinMinAndMax but also ensures that the value doesn't
251
+ // go below the padding and border amount.
252
+ export function boundAxis(
253
+ node: Node,
254
+ axis: FlexDirection,
255
+ direction: Direction,
256
+ value: number,
257
+ axisSize: number,
258
+ widthSize: number,
259
+ ): number {
260
+ return maxOrDefined(
261
+ boundAxisWithinMinAndMax(node, direction, axis, value, axisSize, widthSize),
262
+ paddingAndBorderForAxis(node, axis, direction, widthSize),
263
+ );
264
+ }
265
+
266
+ // Port of yoga/algorithm/TrailingPosition.h
267
+
268
+ // Given an offset to an edge, returns the offset to the opposite edge on the
269
+ // same axis. This assumes that the width/height of both nodes is determined at
270
+ // this point.
271
+ export function getPositionOfOppositeEdge(
272
+ position: number,
273
+ axis: FlexDirection,
274
+ containingNode: Node,
275
+ node: Node,
276
+ ): number {
277
+ return (
278
+ containingNode.layout.measuredDimension(dimension(axis)) -
279
+ node.layout.measuredDimension(dimension(axis)) -
280
+ position
281
+ );
282
+ }
283
+
284
+ export function setChildTrailingPosition(node: Node, child: Node, axis: FlexDirection): void {
285
+ child.setLayoutPosition(
286
+ getPositionOfOppositeEdge(child.layout.position(flexStartEdge(axis)), axis, node, child),
287
+ flexEndEdge(axis),
288
+ );
289
+ }
290
+
291
+ export function needsTrailingPosition(axis: FlexDirection): boolean {
292
+ return axis === FlexDirection.RowReverse || axis === FlexDirection.ColumnReverse;
293
+ }