@juspay/svelte-ui-components 4.50.0 → 4.52.0
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/Animations/tokenizedFly.js +9 -2
- package/dist/AreaChart/AreaChart.svelte +41 -13
- package/dist/AreaChart/properties.d.ts +12 -0
- package/dist/AttachmentChipRow/AttachmentChipRow.svelte +7 -6
- package/dist/BarChart/BarChart.svelte +54 -6
- package/dist/BarChart/properties.d.ts +12 -0
- package/dist/Calendar/Calendar.svelte +124 -51
- package/dist/Card/Card.svelte +5 -0
- package/dist/ChatSuggestions/ChatSuggestions.svelte +1 -0
- package/dist/CheckListItem/CheckListItem.svelte +27 -5
- package/dist/ColorPicker/ColorPicker.svelte +40 -9
- package/dist/ColorPicker/properties.d.ts +8 -0
- package/dist/Combobox/Combobox.svelte +34 -2
- package/dist/CommandMenu/CommandMenu.svelte +35 -8
- package/dist/CommandMenu/properties.d.ts +6 -0
- package/dist/DateRangePicker/DateRangePicker.svelte +5 -5
- package/dist/DualAxisBarChart/DualAxisBarChart.svelte +41 -7
- package/dist/DualAxisBarChart/properties.d.ts +4 -0
- package/dist/FileDropzoneTrigger/FileDropzoneTrigger.svelte +104 -10
- package/dist/FileDropzoneTrigger/properties.d.ts +14 -4
- package/dist/FileInput/FileInput.svelte +38 -9
- package/dist/FileInput/context.d.ts +20 -0
- package/dist/FileInput/context.js +8 -0
- package/dist/FileInput/properties.d.ts +25 -1
- package/dist/FunnelChart/FunnelChart.svelte +20 -1
- package/dist/FunnelChart/properties.d.ts +4 -0
- package/dist/Gallery/Gallery.svelte +72 -27
- package/dist/HITL/HITL.svelte +12 -3
- package/dist/LineChart/LineChart.svelte +105 -33
- package/dist/LineChart/properties.d.ts +12 -0
- package/dist/MediaPlayer/MediaPlayer.svelte +172 -2
- package/dist/MediaPlayer/MediaPlayer.svelte.d.ts +1 -1
- package/dist/MediaPlayer/properties.d.ts +31 -0
- package/dist/Menu/Menu.svelte +6 -4
- package/dist/Modal/Modal.svelte +15 -12
- package/dist/Modal/properties.d.ts +29 -1
- package/dist/Pagination/Pagination.svelte +1 -0
- package/dist/PieChart/PieChart.svelte +51 -29
- package/dist/PieChart/properties.d.ts +4 -0
- package/dist/Pill/Pill.svelte +5 -0
- package/dist/Radio/Radio.svelte +11 -2
- package/dist/Radio/properties.d.ts +7 -2
- package/dist/SankeyChart/SankeyChart.svelte +339 -211
- package/dist/SankeyChart/properties.d.ts +4 -0
- package/dist/Scroller/Scroller.svelte +247 -4
- package/dist/Scroller/properties.d.ts +8 -0
- package/dist/Select/Select.svelte +43 -5
- package/dist/Select/properties.d.ts +17 -1
- package/dist/Sheet/Sheet.svelte +31 -4
- package/dist/Sheet/properties.d.ts +6 -0
- package/dist/SplitInput/SplitInput.svelte +17 -0
- package/dist/SplitInput/field-name.d.ts +29 -0
- package/dist/SplitInput/field-name.js +50 -0
- package/dist/SplitInput/properties.d.ts +18 -4
- package/dist/Status/Status.svelte +24 -12
- package/dist/Status/properties.d.ts +11 -0
- package/dist/Table/BuiltinCell.svelte +13 -5
- package/dist/Table/BuiltinCell.svelte.d.ts +1 -0
- package/dist/Table/Table.svelte +78 -20
- package/dist/Table/a11y.d.ts +7 -0
- package/dist/Table/a11y.js +71 -0
- package/dist/Table/cellData.js +3 -0
- package/dist/Table/properties.d.ts +13 -5
- package/dist/ThemeSwitcher/ThemeSwitcher.svelte +4 -0
- package/dist/ThinkingIndicator/ThinkingIndicator.svelte +48 -9
- package/dist/Toast/Toast.svelte +40 -4
- package/dist/Toggle/Toggle.svelte +2 -0
- package/dist/Toggle/properties.d.ts +2 -0
- package/dist/_chart/Axis.svelte +10 -0
- package/dist/_chart/ChartContainer.svelte +32 -1
- package/dist/_chart/ChartTooltip.svelte +18 -3
- package/dist/_chart/LabelPlate.svelte +114 -0
- package/dist/_chart/LabelPlate.svelte.d.ts +7 -0
- package/dist/_chart/a11y.d.ts +29 -0
- package/dist/_chart/a11y.js +44 -0
- package/dist/_chart/measure.d.ts +2 -0
- package/dist/_chart/measure.js +4 -0
- package/dist/_chart/tooltipPosition.d.ts +6 -0
- package/dist/_chart/tooltipPosition.js +30 -2
- package/dist/_chart/types.d.ts +22 -0
- package/dist/_interaction/focusable.d.ts +47 -0
- package/dist/_interaction/focusable.js +139 -0
- package/dist/assets/captions-on.svg +3 -0
- package/dist/assets/captions.svg +5 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/styles/theme-dark.css +6 -1
- package/dist/types.d.ts +2 -0
- package/dist/utils.d.ts +18 -2
- package/dist/utils.js +73 -28
- package/dist-codemod/codemod/migrate-audit.js +9 -7
- package/dist-codemod/codemod/migration-assets/legacy-palette.css +9 -1
- package/dist-codemod/codemod/migration-assets-layout.js +61 -0
- package/dist-wc/index.js +5653 -4148
- package/package.json +4 -2
|
@@ -9,6 +9,34 @@ export function computeTooltipPosition(opts) {
|
|
|
9
9
|
const { tooltip, container } = opts;
|
|
10
10
|
const maxLeft = container.width - tooltip.width;
|
|
11
11
|
const maxTop = container.height - tooltip.height;
|
|
12
|
+
const finish = (left, top) => {
|
|
13
|
+
const preferred = { left: clamp(left, maxLeft), top: clamp(top, maxTop) };
|
|
14
|
+
const labels = opts.avoidRects ?? [];
|
|
15
|
+
const clear = (p) => labels.every((r) => p.left + tooltip.width <= r.left ||
|
|
16
|
+
p.left >= r.left + r.width ||
|
|
17
|
+
p.top + tooltip.height <= r.top ||
|
|
18
|
+
p.top >= r.top + r.height);
|
|
19
|
+
if (clear(preferred)) {
|
|
20
|
+
return preferred;
|
|
21
|
+
}
|
|
22
|
+
// Keep labels visible when the usual point/cursor offset intersects them.
|
|
23
|
+
// Try the nearby edges first, including combinations for crowded plots.
|
|
24
|
+
const candidates = [];
|
|
25
|
+
for (const r of labels) {
|
|
26
|
+
const xs = [preferred.left, r.left - tooltip.width - offset, r.left + r.width + offset];
|
|
27
|
+
const ys = [preferred.top, r.top - tooltip.height - offset, r.top + r.height + offset];
|
|
28
|
+
for (const x of xs) {
|
|
29
|
+
for (const y of ys) {
|
|
30
|
+
if (x >= 0 && y >= 0 && x <= maxLeft && y <= maxTop) {
|
|
31
|
+
candidates.push({ left: x, top: y });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const distance = (p) => (p.left - preferred.left) ** 2 + (p.top - preferred.top) ** 2;
|
|
37
|
+
candidates.sort((a, b) => distance(a) - distance(b));
|
|
38
|
+
return candidates.find(clear) ?? preferred;
|
|
39
|
+
};
|
|
12
40
|
const a = opts.anchor ?? null;
|
|
13
41
|
if (a !== null) {
|
|
14
42
|
let left;
|
|
@@ -33,7 +61,7 @@ export function computeTooltipPosition(opts) {
|
|
|
33
61
|
left = a.x + offset;
|
|
34
62
|
}
|
|
35
63
|
}
|
|
36
|
-
return
|
|
64
|
+
return finish(left, top);
|
|
37
65
|
}
|
|
38
66
|
const mouseX = opts.mouseX ?? 0;
|
|
39
67
|
const mouseY = opts.mouseY ?? 0;
|
|
@@ -45,5 +73,5 @@ export function computeTooltipPosition(opts) {
|
|
|
45
73
|
if (top + tooltip.height > container.height) {
|
|
46
74
|
top = mouseY - tooltip.height - offset;
|
|
47
75
|
}
|
|
48
|
-
return
|
|
76
|
+
return finish(left, top);
|
|
49
77
|
}
|
package/dist/_chart/types.d.ts
CHANGED
|
@@ -149,6 +149,28 @@ export type ChartContainerProperties = {
|
|
|
149
149
|
maxHeight?: number;
|
|
150
150
|
testId?: string;
|
|
151
151
|
classes?: string;
|
|
152
|
+
/**
|
|
153
|
+
* Accessible name of the chart drawing (`aria-label` on the `<svg>`). Without
|
|
154
|
+
* one the drawing is exposed with no name at all, which axe reports as
|
|
155
|
+
* `svg-img-alt` and which leaves a screen-reader user unable to tell which
|
|
156
|
+
* chart a data point belongs to.
|
|
157
|
+
*/
|
|
158
|
+
ariaLabel?: string;
|
|
159
|
+
/**
|
|
160
|
+
* Optional longer description of the chart. Rendered as an SVG `<desc>` whose
|
|
161
|
+
* instance-scoped id is referenced by `aria-describedby`, so it is announced
|
|
162
|
+
* after the name wherever `aria-describedby` is honoured.
|
|
163
|
+
*/
|
|
164
|
+
ariaDescription?: string;
|
|
165
|
+
/**
|
|
166
|
+
* True when the drawing contains focusable or clickable marks (bars, points,
|
|
167
|
+
* slices). An interactive drawing is exposed as `role="group"`, not
|
|
168
|
+
* `role="img"`: ARIA makes an image's children presentational, so marks left
|
|
169
|
+
* under an image either vanish from assistive technology or are announced
|
|
170
|
+
* inconsistently between browsers. A static drawing stays a named image.
|
|
171
|
+
* Defaults to false, which keeps every existing caller's `role="img"`.
|
|
172
|
+
*/
|
|
173
|
+
interactive?: boolean;
|
|
152
174
|
children: Snippet;
|
|
153
175
|
};
|
|
154
176
|
export type AxisProperties = {
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finds interactive elements the way a keyboard user meets them: through `<slot>`
|
|
3
|
+
* projection and into open shadow roots.
|
|
4
|
+
*
|
|
5
|
+
* `querySelector` cannot do either. Inside a `sui-*` element the content a consumer
|
|
6
|
+
* slotted in lives in the light DOM, so a query rooted in the shadow tree never sees
|
|
7
|
+
* it; and a control rendered by a nested `sui-*` element sits one shadow root further
|
|
8
|
+
* down. Menu needs this to return focus to a slotted trigger, and Scroller needs it to
|
|
9
|
+
* decide whether its content already offers a Tab stop. Both answered "none" through the
|
|
10
|
+
* custom-element build while answering correctly in the Svelte one.
|
|
11
|
+
*
|
|
12
|
+
* Pure DOM reads with no Svelte dependency, so it stays unit-testable under jsdom --
|
|
13
|
+
* which is also why visibility uses `checkVisibility` only when the engine has it
|
|
14
|
+
* rather than layout measurements jsdom cannot provide.
|
|
15
|
+
*/
|
|
16
|
+
export type FindInteractiveOptions = {
|
|
17
|
+
/** Also test `root` itself, not only what it contains. */
|
|
18
|
+
readonly includeRoot?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Only elements a Tab press reaches. Off by default so a control carrying
|
|
21
|
+
* `tabindex="-1"` still counts as somewhere focus can be put programmatically.
|
|
22
|
+
*/
|
|
23
|
+
readonly tabbableOnly?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Also yield elements that are not rendered right now (`display: none`, `hidden`, inert).
|
|
26
|
+
* For a caller that wants to be told when one of them is shown or hidden again.
|
|
27
|
+
*/
|
|
28
|
+
readonly includeHidden?: boolean;
|
|
29
|
+
};
|
|
30
|
+
/** Inert applies through shadow hosts and slot projection, beyond `closest()`'s tree. */
|
|
31
|
+
export declare function composedParent(el: Element): Element | null;
|
|
32
|
+
/**
|
|
33
|
+
* Every interactive element at or below `root`, in tree order. When `root` is itself a
|
|
34
|
+
* host, that includes the controls its own shadow tree renders -- the case of a
|
|
35
|
+
* `<sui-button>` handed over as a trigger.
|
|
36
|
+
*/
|
|
37
|
+
export declare function interactiveElements(root: Element | ShadowRoot | DocumentFragment, options?: FindInteractiveOptions): Generator<HTMLElement>;
|
|
38
|
+
/** The first interactive element at or below `root` in tree order, or `null`. */
|
|
39
|
+
export declare function findInteractive(root: Element | ShadowRoot | DocumentFragment, options?: FindInteractiveOptions): HTMLElement | null;
|
|
40
|
+
/** Whether anything beneath `root` is reachable with Tab. */
|
|
41
|
+
export declare function hasTabbableContent(root: Element | ShadowRoot | DocumentFragment): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* The direct content of `root` as the layout sees it: a `<slot>` stands in for the
|
|
44
|
+
* elements assigned to it. These are the nodes whose size and attributes decide whether
|
|
45
|
+
* `root`'s scrollable area, or its Tab order, changes.
|
|
46
|
+
*/
|
|
47
|
+
export declare function contentElements(root: Element): Element[];
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finds interactive elements the way a keyboard user meets them: through `<slot>`
|
|
3
|
+
* projection and into open shadow roots.
|
|
4
|
+
*
|
|
5
|
+
* `querySelector` cannot do either. Inside a `sui-*` element the content a consumer
|
|
6
|
+
* slotted in lives in the light DOM, so a query rooted in the shadow tree never sees
|
|
7
|
+
* it; and a control rendered by a nested `sui-*` element sits one shadow root further
|
|
8
|
+
* down. Menu needs this to return focus to a slotted trigger, and Scroller needs it to
|
|
9
|
+
* decide whether its content already offers a Tab stop. Both answered "none" through the
|
|
10
|
+
* custom-element build while answering correctly in the Svelte one.
|
|
11
|
+
*
|
|
12
|
+
* Pure DOM reads with no Svelte dependency, so it stays unit-testable under jsdom --
|
|
13
|
+
* which is also why visibility uses `checkVisibility` only when the engine has it
|
|
14
|
+
* rather than layout measurements jsdom cannot provide.
|
|
15
|
+
*/
|
|
16
|
+
const NATIVE_CONTROL_SELECTOR = [
|
|
17
|
+
'a[href]',
|
|
18
|
+
'button:not([disabled])',
|
|
19
|
+
'input:not([disabled]):not([type="hidden"])',
|
|
20
|
+
'select:not([disabled])',
|
|
21
|
+
'textarea:not([disabled])',
|
|
22
|
+
'summary',
|
|
23
|
+
'audio[controls]',
|
|
24
|
+
'video[controls]',
|
|
25
|
+
'iframe',
|
|
26
|
+
'[contenteditable=""]',
|
|
27
|
+
'[contenteditable="true"]'
|
|
28
|
+
].join(', ');
|
|
29
|
+
/** Inert applies through shadow hosts and slot projection, beyond `closest()`'s tree. */
|
|
30
|
+
export function composedParent(el) {
|
|
31
|
+
const slot = el instanceof HTMLElement || el instanceof SVGElement ? el.assignedSlot : null;
|
|
32
|
+
if (slot !== null) {
|
|
33
|
+
return slot;
|
|
34
|
+
}
|
|
35
|
+
const root = el.getRootNode();
|
|
36
|
+
return el.parentElement ?? (root instanceof ShadowRoot ? root.host : null);
|
|
37
|
+
}
|
|
38
|
+
function isRendered(el) {
|
|
39
|
+
if (el.hasAttribute('hidden')) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
for (let ancestor = el; ancestor !== null; ancestor = composedParent(ancestor)) {
|
|
43
|
+
if (ancestor.hasAttribute('inert')) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return typeof el.checkVisibility === 'function'
|
|
48
|
+
? el.checkVisibility({ visibilityProperty: true })
|
|
49
|
+
: true;
|
|
50
|
+
}
|
|
51
|
+
function interactiveElement(el, tabbableOnly, includeHidden) {
|
|
52
|
+
if (!(el instanceof HTMLElement)) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
// Native disabledness includes a disabled fieldset, except its first legend.
|
|
56
|
+
// Neither the own `disabled` property nor authored tabindex describes that
|
|
57
|
+
// inherited state. The browser's predicate also handles the legend exception.
|
|
58
|
+
if (el.matches(':disabled')) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
const tabbable = el.tabIndex >= 0;
|
|
62
|
+
// A native control keeps `tabindex="-1"` focusable from script. A bare `[tabindex]`
|
|
63
|
+
// is only a control because of that attribute, so a negative value takes it out.
|
|
64
|
+
const interactive = el.matches(NATIVE_CONTROL_SELECTOR)
|
|
65
|
+
? !tabbableOnly || tabbable
|
|
66
|
+
: el.hasAttribute('tabindex') && tabbable;
|
|
67
|
+
return interactive && (includeHidden || isRendered(el)) ? el : null;
|
|
68
|
+
}
|
|
69
|
+
function* childrenOf(node) {
|
|
70
|
+
if (node instanceof HTMLSlotElement) {
|
|
71
|
+
const assigned = node.assignedElements({ flatten: true });
|
|
72
|
+
// An unassigned slot renders its fallback content, which is its own children.
|
|
73
|
+
yield* assigned.length > 0 ? assigned : Array.from(node.children);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
yield* Array.from(node.children);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* What an element renders inside itself: its shadow tree when it hosts one, otherwise
|
|
80
|
+
* its own children. A host's light children are not rendered directly -- they appear
|
|
81
|
+
* wherever the shadow tree's `<slot>`s place them, which `childrenOf` resolves -- so
|
|
82
|
+
* walking the shadow tree alone visits each of them once and in the order they render.
|
|
83
|
+
*/
|
|
84
|
+
function renderedTreeOf(node) {
|
|
85
|
+
return node instanceof Element && node.shadowRoot !== null ? node.shadowRoot : node;
|
|
86
|
+
}
|
|
87
|
+
function* walk(node) {
|
|
88
|
+
for (const child of childrenOf(node)) {
|
|
89
|
+
yield child;
|
|
90
|
+
yield* walk(renderedTreeOf(child));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Every interactive element at or below `root`, in tree order. When `root` is itself a
|
|
95
|
+
* host, that includes the controls its own shadow tree renders -- the case of a
|
|
96
|
+
* `<sui-button>` handed over as a trigger.
|
|
97
|
+
*/
|
|
98
|
+
export function* interactiveElements(root, options = {}) {
|
|
99
|
+
const tabbableOnly = options.tabbableOnly === true;
|
|
100
|
+
const includeHidden = options.includeHidden === true;
|
|
101
|
+
if (options.includeRoot === true && root instanceof Element) {
|
|
102
|
+
const self = interactiveElement(root, tabbableOnly, includeHidden);
|
|
103
|
+
if (self !== null) {
|
|
104
|
+
yield self;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
for (const el of walk(renderedTreeOf(root))) {
|
|
108
|
+
const found = interactiveElement(el, tabbableOnly, includeHidden);
|
|
109
|
+
if (found !== null) {
|
|
110
|
+
yield found;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/** The first interactive element at or below `root` in tree order, or `null`. */
|
|
115
|
+
export function findInteractive(root, options = {}) {
|
|
116
|
+
const first = interactiveElements(root, options).next();
|
|
117
|
+
return first.done === true ? null : first.value;
|
|
118
|
+
}
|
|
119
|
+
/** Whether anything beneath `root` is reachable with Tab. */
|
|
120
|
+
export function hasTabbableContent(root) {
|
|
121
|
+
return findInteractive(root, { tabbableOnly: true }) !== null;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* The direct content of `root` as the layout sees it: a `<slot>` stands in for the
|
|
125
|
+
* elements assigned to it. These are the nodes whose size and attributes decide whether
|
|
126
|
+
* `root`'s scrollable area, or its Tab order, changes.
|
|
127
|
+
*/
|
|
128
|
+
export function contentElements(root) {
|
|
129
|
+
const out = [];
|
|
130
|
+
for (const child of Array.from(root.children)) {
|
|
131
|
+
if (child instanceof HTMLSlotElement) {
|
|
132
|
+
out.push(...childrenOf(child));
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
out.push(child);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return out;
|
|
139
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path fill-rule="evenodd" d="M5 5h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2zM11.121 9.879A3 3 0 1 0 11.121 14.121L9.99 12.99A1.4 1.4 0 1 1 9.99 11.01zM17.121 9.879A3 3 0 1 0 17.121 14.121L15.99 12.99A1.4 1.4 0 1 1 15.99 11.01z" />
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect x="3" y="5" width="18" height="14" rx="2" />
|
|
3
|
+
<path d="M10.5 10.5a2 2 0 1 0 0 3" />
|
|
4
|
+
<path d="M16.5 10.5a2 2 0 1 0 0 3" />
|
|
5
|
+
</svg>
|
package/dist/index.d.ts
CHANGED
|
@@ -228,7 +228,7 @@ export type * from './MediaPlayer/properties';
|
|
|
228
228
|
export type * from './MediaUpload/properties';
|
|
229
229
|
export type * from './Gallery/properties';
|
|
230
230
|
export { createSoundKit } from './SoundKit/SoundKit';
|
|
231
|
-
export { validateInput, lockBodyScroll, unlockBodyScroll, prefersReducedMotion } from './utils';
|
|
231
|
+
export { validateInput, lockBodyScroll, unlockBodyScroll, acquireScrollLock, prefersReducedMotion } from './utils';
|
|
232
232
|
export { reducedMotion } from './reduced-motion.svelte';
|
|
233
233
|
export type { ReducedMotionPreference } from './reduced-motion.svelte';
|
|
234
234
|
export { TEL_PRESETS, TEL_PRESET_IN_MOBILE } from './utils';
|
package/dist/index.js
CHANGED
|
@@ -123,7 +123,7 @@ export { createSoundKit } from './SoundKit/SoundKit';
|
|
|
123
123
|
// applies just as much across the boundary. A consumer driving motion from JavaScript
|
|
124
124
|
// -- a canvas, a chart, an imperative animation -- cannot reach the preference through
|
|
125
125
|
// a stylesheet, so leaving this unexported made every such consumer write it again.
|
|
126
|
-
export { validateInput, lockBodyScroll, unlockBodyScroll, prefersReducedMotion } from './utils';
|
|
126
|
+
export { validateInput, lockBodyScroll, unlockBodyScroll, acquireScrollLock, prefersReducedMotion } from './utils';
|
|
127
127
|
// The reactive counterpart to `prefersReducedMotion()` above: a consumer
|
|
128
128
|
// building their own component with runes needs a value that stays current
|
|
129
129
|
// inside a `$derived`, which a plain function call cannot give them, for the
|
|
@@ -201,8 +201,11 @@
|
|
|
201
201
|
--hitl-halted-color: #fbbf24;
|
|
202
202
|
--hitl-countdown-filter: brightness(1.6);
|
|
203
203
|
|
|
204
|
-
/* ThinkingIndicator
|
|
204
|
+
/* ThinkingIndicator. The shimmer gradient is built from the label colour plus this
|
|
205
|
+
highlight, so both stops of the sweep stay readable on the dark grounds
|
|
206
|
+
(#9ca3af / #e5e7eb are 5.1-7.5:1 and 10.5-15.4:1 on #0f0f17..#2f2f45). */
|
|
205
207
|
--thinking-indicator-label-color: #9ca3af;
|
|
208
|
+
--thinking-indicator-shimmer-highlight: #e5e7eb;
|
|
206
209
|
--thinking-indicator-detail-color: #9ca3af;
|
|
207
210
|
--thinking-indicator-arrow-color: #9ca3af;
|
|
208
211
|
--thinking-indicator-border-bottom: 1px solid #2a2a3c;
|
|
@@ -212,6 +215,7 @@
|
|
|
212
215
|
--thinking-indicator-chip-background: #1e1e2e;
|
|
213
216
|
--thinking-indicator-chip-border: 1px solid #2a2a3c;
|
|
214
217
|
--thinking-indicator-chip-color: #9ca3af;
|
|
218
|
+
--thinking-indicator-chip-shimmer-highlight: #f3f4f6;
|
|
215
219
|
--thinking-indicator-chip-box-shadow: 0 6px 20px rgb(0 0 0 / 40%);
|
|
216
220
|
|
|
217
221
|
/* AttachmentChipRow */
|
|
@@ -710,6 +714,7 @@
|
|
|
710
714
|
--sankey-label-color: #d1d5db;
|
|
711
715
|
|
|
712
716
|
/* Scroller */
|
|
717
|
+
--scroller-focus-outline: 2px solid #818cf8;
|
|
713
718
|
--scroller-arrow-background: #1e1e2e;
|
|
714
719
|
--scroller-arrow-color: #d1d5db;
|
|
715
720
|
--scroller-arrow-hover-background: #252535;
|
package/dist/types.d.ts
CHANGED
|
@@ -19,6 +19,8 @@ import type { HTMLAttributes } from 'svelte/elements';
|
|
|
19
19
|
*/
|
|
20
20
|
export type InputDataType = 'text' | 'tel' | 'password' | 'email' | 'number' | 'time' | 'date' | 'search' | 'url';
|
|
21
21
|
export type ModalTransition = 'IN' | 'ALL';
|
|
22
|
+
/** An overlay's owned scroll element. A null value/getter result disables locking. */
|
|
23
|
+
export type ScrollContainer = HTMLElement | (() => HTMLElement | null) | null;
|
|
22
24
|
/**
|
|
23
25
|
* @name CustomValidator
|
|
24
26
|
* @description Function type for taking input parameter and returning a boolean denoting if the value is valid or not
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CustomValidator, Hsv, Hsl, InputDataType, Rgb, ValidationState } from './types';
|
|
1
|
+
import type { CustomValidator, Hsv, Hsl, InputDataType, Rgb, ValidationState, ScrollContainer } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* A phone-number shape a consumer opts into, as the pair of patterns the
|
|
4
4
|
* in-progress/committed distinction needs.
|
|
@@ -93,9 +93,25 @@ export declare function prefersReducedMotion(): boolean;
|
|
|
93
93
|
* dismissal must be acted on at once, and the repeats it guards against are the
|
|
94
94
|
* ones to discard.
|
|
95
95
|
*
|
|
96
|
+
* `delay` may be a function, read on every call, for a caller whose delay can
|
|
97
|
+
* change after the debouncer exists. The window is then measured against the
|
|
98
|
+
* delay in force now, while `lastCallTime` stays the one debouncer's own: a
|
|
99
|
+
* caller rebuilding the debouncer to pick up a new delay would also forget when
|
|
100
|
+
* it last fired, and let through the very repeat it exists to drop.
|
|
101
|
+
*
|
|
96
102
|
* Not exported from the package; renaming it is a free change whenever the
|
|
97
103
|
* mismatch stops being worth the note.
|
|
98
104
|
*/
|
|
99
|
-
export declare function createDebouncer(delay: number): <T extends unknown[]>(callback: (...args: T) => void, ...args: T) => void;
|
|
105
|
+
export declare function createDebouncer(delay: number | (() => number)): <T extends unknown[]>(callback: (...args: T) => void, ...args: T) => void;
|
|
106
|
+
/**
|
|
107
|
+
* Acquire one hold and return its idempotent release function. Only overflow
|
|
108
|
+
* declarations are touched; their original values, priorities and order are
|
|
109
|
+
* restored after the final hold. Scroll position and unrelated styles stay intact.
|
|
110
|
+
* A null container is a no-op, including during SSR.
|
|
111
|
+
*/
|
|
112
|
+
export declare function acquireScrollLock(container?: HTMLElement | null): () => void;
|
|
113
|
+
/** Explicit ownership never falls back to body, even if the getter returns null. */
|
|
114
|
+
export declare function resolveScrollContainer(node: HTMLElement | null, container?: ScrollContainer): HTMLElement | null;
|
|
115
|
+
/** Backwards-compatible body helpers; every acquired hold needs one unlock. */
|
|
100
116
|
export declare function lockBodyScroll(): void;
|
|
101
117
|
export declare function unlockBodyScroll(): void;
|
package/dist/utils.js
CHANGED
|
@@ -352,6 +352,12 @@ export function prefersReducedMotion() {
|
|
|
352
352
|
* dismissal must be acted on at once, and the repeats it guards against are the
|
|
353
353
|
* ones to discard.
|
|
354
354
|
*
|
|
355
|
+
* `delay` may be a function, read on every call, for a caller whose delay can
|
|
356
|
+
* change after the debouncer exists. The window is then measured against the
|
|
357
|
+
* delay in force now, while `lastCallTime` stays the one debouncer's own: a
|
|
358
|
+
* caller rebuilding the debouncer to pick up a new delay would also forget when
|
|
359
|
+
* it last fired, and let through the very repeat it exists to drop.
|
|
360
|
+
*
|
|
355
361
|
* Not exported from the package; renaming it is a free change whenever the
|
|
356
362
|
* mismatch stops being worth the note.
|
|
357
363
|
*/
|
|
@@ -359,44 +365,83 @@ export function createDebouncer(delay) {
|
|
|
359
365
|
let lastCallTime = 0;
|
|
360
366
|
return function (callback, ...args) {
|
|
361
367
|
const now = Date.now();
|
|
362
|
-
|
|
368
|
+
const currentDelay = typeof delay === 'function' ? delay() : delay;
|
|
369
|
+
if (now - lastCallTime > currentDelay) {
|
|
363
370
|
lastCallTime = now;
|
|
364
371
|
callback(...args);
|
|
365
372
|
}
|
|
366
373
|
};
|
|
367
374
|
}
|
|
375
|
+
/** Per-container locks shared by overlays and the legacy body helpers. */
|
|
376
|
+
const scrollLocks = new WeakMap();
|
|
377
|
+
const bodyScrollReleases = [];
|
|
368
378
|
/**
|
|
369
|
-
*
|
|
370
|
-
*
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
* scrolling for all of them, so closing a confirmation dialog inside a still-open
|
|
374
|
-
* modal silently lets the page behind it scroll again. Counting the holders keeps
|
|
375
|
-
* the lock until the last one releases it.
|
|
376
|
-
*
|
|
377
|
-
* Callers must pair every lock with exactly one unlock.
|
|
379
|
+
* Acquire one hold and return its idempotent release function. Only overflow
|
|
380
|
+
* declarations are touched; their original values, priorities and order are
|
|
381
|
+
* restored after the final hold. Scroll position and unrelated styles stay intact.
|
|
382
|
+
* A null container is a no-op, including during SSR.
|
|
378
383
|
*/
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
let bodyScrollPreviousOverflow = '';
|
|
383
|
-
export function lockBodyScroll() {
|
|
384
|
-
if (typeof document === 'undefined') {
|
|
385
|
-
return;
|
|
384
|
+
export function acquireScrollLock(container = typeof document === 'undefined' ? null : document.body) {
|
|
385
|
+
if (container === null) {
|
|
386
|
+
return () => { };
|
|
386
387
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
388
|
+
let lock = scrollLocks.get(container);
|
|
389
|
+
if (!lock) {
|
|
390
|
+
const overflow = [];
|
|
391
|
+
for (let index = 0; index < container.style.length; index += 1) {
|
|
392
|
+
const name = container.style.item(index);
|
|
393
|
+
if (name === 'overflow' || name === 'overflow-x' || name === 'overflow-y') {
|
|
394
|
+
overflow.push([
|
|
395
|
+
name,
|
|
396
|
+
container.style.getPropertyValue(name),
|
|
397
|
+
container.style.getPropertyPriority(name)
|
|
398
|
+
]);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
lock = { count: 0, overflow };
|
|
402
|
+
scrollLocks.set(container, lock);
|
|
403
|
+
container.style.setProperty('overflow', 'hidden', 'important');
|
|
390
404
|
}
|
|
391
|
-
|
|
405
|
+
lock.count += 1;
|
|
406
|
+
const heldLock = lock;
|
|
407
|
+
let released = false;
|
|
408
|
+
return () => {
|
|
409
|
+
if (released) {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
released = true;
|
|
413
|
+
heldLock.count -= 1;
|
|
414
|
+
if (heldLock.count === 0) {
|
|
415
|
+
container.style.removeProperty('overflow');
|
|
416
|
+
container.style.removeProperty('overflow-x');
|
|
417
|
+
container.style.removeProperty('overflow-y');
|
|
418
|
+
for (const [name, value, priority] of heldLock.overflow) {
|
|
419
|
+
container.style.setProperty(name, value, priority);
|
|
420
|
+
}
|
|
421
|
+
scrollLocks.delete(container);
|
|
422
|
+
}
|
|
423
|
+
};
|
|
392
424
|
}
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
425
|
+
/** Explicit ownership never falls back to body, even if the getter returns null. */
|
|
426
|
+
export function resolveScrollContainer(node, container) {
|
|
427
|
+
const resolved = typeof container === 'function' ? container() : container;
|
|
428
|
+
if (typeof resolved === 'object') {
|
|
429
|
+
return resolved !== null && resolved.nodeType === 1 && typeof resolved.style === 'object'
|
|
430
|
+
? resolved
|
|
431
|
+
: null;
|
|
396
432
|
}
|
|
397
|
-
|
|
398
|
-
if (
|
|
399
|
-
|
|
400
|
-
bodyScrollPreviousOverflow = '';
|
|
433
|
+
// Invalid JavaScript/custom-element values are never permission to lock body.
|
|
434
|
+
if (typeof container !== 'undefined') {
|
|
435
|
+
return null;
|
|
401
436
|
}
|
|
437
|
+
return node?.ownerDocument.body ?? (typeof document === 'undefined' ? null : document.body);
|
|
438
|
+
}
|
|
439
|
+
/** Backwards-compatible body helpers; every acquired hold needs one unlock. */
|
|
440
|
+
export function lockBodyScroll() {
|
|
441
|
+
if (typeof document !== 'undefined') {
|
|
442
|
+
bodyScrollReleases.push(acquireScrollLock(document.body));
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
export function unlockBodyScroll() {
|
|
446
|
+
bodyScrollReleases.pop()?.();
|
|
402
447
|
}
|
|
@@ -5,6 +5,8 @@ import { parseArgs } from 'node:util';
|
|
|
5
5
|
import { analyzeStylesheet, analyzeSvelte, LIBRARY } from "../migrate/analyze.js";
|
|
6
6
|
import { planSelectorRewrites } from "../migrate/chart-tooltip-selector.js";
|
|
7
7
|
import { SKIPPED_DIRECTORIES } from "./cli.js";
|
|
8
|
+
import { LEGACY_DISPLAY_CSS_FILENAME, LEGACY_PALETTE_CSS_FILENAME, WC_DISPLAY_FILENAME, migrationAssetsDirBeside } from "./migration-assets-layout.js";
|
|
9
|
+
export { LEGACY_DISPLAY_CSS_FILENAME, LEGACY_PALETTE_CSS_FILENAME };
|
|
8
10
|
/**
|
|
9
11
|
* Runs the 4.28.0 breaking-change audit `npm run migrate` runs, from the
|
|
10
12
|
* PUBLISHED `sui-codemod` binary against a consumer project that only has
|
|
@@ -28,15 +30,15 @@ import { SKIPPED_DIRECTORIES } from "./cli.js";
|
|
|
28
30
|
* never otherwise reach.
|
|
29
31
|
*/
|
|
30
32
|
// ------------------------------------------------------------- wc-display.json
|
|
31
|
-
const MIGRATION_ASSETS_DIRNAME = 'migration-assets';
|
|
32
|
-
const WC_DISPLAY_FILENAME = 'wc-display.json';
|
|
33
|
-
export const LEGACY_DISPLAY_CSS_FILENAME = 'legacy-display.css';
|
|
34
|
-
export const LEGACY_PALETTE_CSS_FILENAME = 'legacy-palette.css';
|
|
35
33
|
/**
|
|
36
34
|
* The directory `generate-migration-assets.ts` writes into, resolved off
|
|
37
35
|
* THIS module's own compiled location rather than `process.cwd()` -- so it
|
|
38
|
-
* still finds `dist-codemod/migration-assets` when this module has
|
|
39
|
-
* compiled to `dist-codemod/migrate-audit.js` and invoked from
|
|
36
|
+
* still finds `dist-codemod/codemod/migration-assets` when this module has
|
|
37
|
+
* been compiled to `dist-codemod/codemod/migrate-audit.js` and invoked from
|
|
38
|
+
* anywhere. The directory name and the "beside the compiled module" rule come
|
|
39
|
+
* from `migration-assets-layout.ts`, the one place the generator, this lookup
|
|
40
|
+
* and the real-artifact tests all read it from.
|
|
41
|
+
*
|
|
40
42
|
* Run against the uncompiled `.ts` source (as the tests below do without an
|
|
41
43
|
* explicit `assetsDir` override) it resolves to a sibling directory that
|
|
42
44
|
* does not exist -- which is the correct answer, not a bug: this module
|
|
@@ -45,7 +47,7 @@ export const LEGACY_PALETTE_CSS_FILENAME = 'legacy-palette.css';
|
|
|
45
47
|
* than a guess.
|
|
46
48
|
*/
|
|
47
49
|
function defaultAssetsDir() {
|
|
48
|
-
return
|
|
50
|
+
return migrationAssetsDirBeside(dirname(fileURLToPath(import.meta.url)));
|
|
49
51
|
}
|
|
50
52
|
/** Same no-assertion narrowing `analyze.ts`'s own `asRecord` uses: copies known-present keys onto a fresh object rather than casting. */
|
|
51
53
|
function asRecord(value) {
|
|
@@ -12,11 +12,12 @@
|
|
|
12
12
|
* one property at a time, not to be a permanent fixture in a consumer
|
|
13
13
|
* build.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
15
|
+
* 62 properties pinned below. 9 more could not be -- see the note at the end.
|
|
16
16
|
*
|
|
17
17
|
* Generated by scripts/migrate/legacy-palette.ts -- do not hand edit.
|
|
18
18
|
*/
|
|
19
19
|
:root { --banner-link-color: #0099ff; } /* was the 4.27.x default */
|
|
20
|
+
:root { --button-width: fit-content; } /* was the 4.27.x default */
|
|
20
21
|
:root { --calendar-day-name-color: #999999; } /* was the 4.27.x default */
|
|
21
22
|
:root { --calendar-disabled-color: #cccccc; } /* was the 4.27.x default */
|
|
22
23
|
:root { --calendar-outside-month-color: #cccccc; } /* was the 4.27.x default */
|
|
@@ -26,6 +27,7 @@
|
|
|
26
27
|
:root { --delta-indicator-negative-color: #e5484d; } /* was the 4.27.x default */
|
|
27
28
|
:root { --delta-indicator-neutral-color: #8a8a8a; } /* was the 4.27.x default */
|
|
28
29
|
:root { --delta-indicator-positive-color: #1a9d6f; } /* was the 4.27.x default */
|
|
30
|
+
:root { --drp-apply-background: currentColor; } /* was the 4.27.x default */
|
|
29
31
|
:root { --drp-panel-background: inherit; } /* was the 4.27.x default */
|
|
30
32
|
:root { --empty-state-description-opacity: 0.6; } /* was the 4.27.x default */
|
|
31
33
|
:root { --field-group-label-color: #9ca3af; } /* was the 4.27.x default */
|
|
@@ -45,6 +47,8 @@
|
|
|
45
47
|
:root { --pagination-button-color: #3a4550; } /* was the 4.27.x default */
|
|
46
48
|
:root { --pagination-load-more-color: #3a4550; } /* was the 4.27.x default */
|
|
47
49
|
:root { --pill-tone-muted-color: #6b7280; } /* was the 4.27.x default */
|
|
50
|
+
:root { --sankey-col-label-color: #666; } /* was the 4.27.x default */
|
|
51
|
+
:root { --sankey-label-color: #333; } /* was the 4.27.x default */
|
|
48
52
|
:root { --select-placeholder-color: #999999; } /* was the 4.27.x default */
|
|
49
53
|
:root { --separator-margin: 0px 12px 0px 12px; } /* was the 4.27.x default */
|
|
50
54
|
:root { --statcard-breakdown-label-color: #9ca3af; } /* was the 4.27.x default */
|
|
@@ -66,6 +70,10 @@
|
|
|
66
70
|
:root { --task-list-secondary-color: #9a9a9a; } /* was the 4.27.x default */
|
|
67
71
|
:root { --thinking-indicator-detail-color: #bebebe; } /* was the 4.27.x default */
|
|
68
72
|
:root { --thinking-indicator-elapsed-color: #9a9a9a; } /* was the 4.27.x default */
|
|
73
|
+
:root { --thinking-indicator-label-color: #858585; } /* was the 4.27.x default */
|
|
74
|
+
:root { --thinking-indicator-trace-added-color: #1f7a5f; } /* was the 4.27.x default */
|
|
75
|
+
:root { --thinking-indicator-trace-more-color: #9a9a9a; } /* was the 4.27.x default */
|
|
76
|
+
:root { --thinking-indicator-trace-removed-color: #c93f38; } /* was the 4.27.x default */
|
|
69
77
|
:root { --thinking-indicator-trace-secondary-color: #9a9a9a; } /* was the 4.27.x default */
|
|
70
78
|
:root { --tool-call-log-error-color: #c93f38; } /* was the 4.27.x default */
|
|
71
79
|
:root { --tool-call-log-meta-color: #9a9a9a; } /* was the 4.27.x default */
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
/**
|
|
3
|
+
* Where the migration assets live in the BUILT package, in one place.
|
|
4
|
+
*
|
|
5
|
+
* Three different pieces of code have to agree on this directory and, before
|
|
6
|
+
* this module, each spelled it out on its own: the generator that writes it
|
|
7
|
+
* (`generate-migration-assets.ts`), the compiled reader that finds it
|
|
8
|
+
* (`migrate-audit.ts`) and the unit tests that check the real artifact. When
|
|
9
|
+
* `tsconfig.build.json` gained a second source tree the compiled layout moved
|
|
10
|
+
* from `dist-codemod/migration-assets` to `dist-codemod/codemod/migration-assets`;
|
|
11
|
+
* the generator and the reader were updated and the test's hand-written copy of
|
|
12
|
+
* the old path was not, so its "run build:codemod first" skip kept firing after
|
|
13
|
+
* a complete build and the real-artifact checks silently stopped running.
|
|
14
|
+
*
|
|
15
|
+
* The assets sit BESIDE the compiled `migrate-audit.js` and are resolved off
|
|
16
|
+
* its own `import.meta.url`, so the layout is "a `migration-assets` directory
|
|
17
|
+
* next to the compiled module", not an absolute location:
|
|
18
|
+
*
|
|
19
|
+
* dist-codemod/ <- tsconfig.build.json `outDir`
|
|
20
|
+
* codemod/ <- `scripts/codemod`, relative to its `rootDir` (`scripts`)
|
|
21
|
+
* bin.js migrate-audit.js ...
|
|
22
|
+
* migration-assets/ <- written by generate-migration-assets.ts
|
|
23
|
+
* wc-display.json legacy-display.css legacy-palette.css
|
|
24
|
+
*
|
|
25
|
+
* `migration-assets-layout.test.ts` pins these constants to `tsconfig.build.json`
|
|
26
|
+
* (`outDir`, `rootDir`) and to package.json (`bin`, `files`) so a change to any
|
|
27
|
+
* of them fails there instead of being discovered as a skipped test.
|
|
28
|
+
*
|
|
29
|
+
* Compiled into `dist-codemod` (it is imported by `migrate-audit.ts`) and also
|
|
30
|
+
* imported by the build-only generator, which node runs with
|
|
31
|
+
* `--experimental-strip-types`: keep it to erasable TypeScript.
|
|
32
|
+
*/
|
|
33
|
+
/** Package-root directory `build:codemod` emits into; `tsconfig.build.json` `outDir`. */
|
|
34
|
+
export const DIST_CODEMOD_DIRNAME = 'dist-codemod';
|
|
35
|
+
/** `scripts/codemod` as it appears under `DIST_CODEMOD_DIRNAME`, because `rootDir` is `scripts`. */
|
|
36
|
+
export const COMPILED_CODEMOD_DIRNAME = 'codemod';
|
|
37
|
+
export const MIGRATION_ASSETS_DIRNAME = 'migration-assets';
|
|
38
|
+
export const WC_DISPLAY_FILENAME = 'wc-display.json';
|
|
39
|
+
export const LEGACY_DISPLAY_CSS_FILENAME = 'legacy-display.css';
|
|
40
|
+
export const LEGACY_PALETTE_CSS_FILENAME = 'legacy-palette.css';
|
|
41
|
+
/** Everything the generator writes into the assets directory. */
|
|
42
|
+
export const MIGRATION_ASSET_FILENAMES = [
|
|
43
|
+
WC_DISPLAY_FILENAME,
|
|
44
|
+
LEGACY_DISPLAY_CSS_FILENAME,
|
|
45
|
+
LEGACY_PALETTE_CSS_FILENAME
|
|
46
|
+
];
|
|
47
|
+
/**
|
|
48
|
+
* The assets directory that sits beside a compiled module. The runtime lookup:
|
|
49
|
+
* `migrate-audit.ts` passes its own directory.
|
|
50
|
+
*/
|
|
51
|
+
export function migrationAssetsDirBeside(compiledModuleDir) {
|
|
52
|
+
return join(compiledModuleDir, MIGRATION_ASSETS_DIRNAME);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The assets directory a build of the package rooted at `packageRoot` produces
|
|
56
|
+
* and the published tarball ships. The generator's default `--out`, and what
|
|
57
|
+
* the real-artifact tests read.
|
|
58
|
+
*/
|
|
59
|
+
export function builtMigrationAssetsDir(packageRoot) {
|
|
60
|
+
return migrationAssetsDirBeside(join(packageRoot, DIST_CODEMOD_DIRNAME, COMPILED_CODEMOD_DIRNAME));
|
|
61
|
+
}
|