@salt-ds/core 1.65.1 → 1.67.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/CHANGELOG.md +43 -0
- package/css/salt-core.css +145 -3
- package/dist-cjs/aria-announcer/AriaAnnouncerProvider.js +28 -11
- package/dist-cjs/aria-announcer/AriaAnnouncerProvider.js.map +1 -1
- package/dist-cjs/border-layout/BorderLayout.js +28 -7
- package/dist-cjs/border-layout/BorderLayout.js.map +1 -1
- package/dist-cjs/dialog/Dialog.js +3 -2
- package/dist-cjs/dialog/Dialog.js.map +1 -1
- package/dist-cjs/drawer/Drawer.js +2 -1
- package/dist-cjs/drawer/Drawer.js.map +1 -1
- package/dist-cjs/file-drop-zone/FileDropZone.js +19 -4
- package/dist-cjs/file-drop-zone/FileDropZone.js.map +1 -1
- package/dist-cjs/file-drop-zone/FileDropZoneTrigger.js +3 -2
- package/dist-cjs/file-drop-zone/FileDropZoneTrigger.js.map +1 -1
- package/dist-cjs/grid-layout/GridLayout.css.js +1 -1
- package/dist-cjs/index.js +22 -0
- package/dist-cjs/index.js.map +1 -1
- package/dist-cjs/mega-menu/MegaMenu.js +81 -0
- package/dist-cjs/mega-menu/MegaMenu.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuActions.css.js +6 -0
- package/dist-cjs/mega-menu/MegaMenuActions.css.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuActions.js +37 -0
- package/dist-cjs/mega-menu/MegaMenuActions.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuAside.css.js +6 -0
- package/dist-cjs/mega-menu/MegaMenuAside.css.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuAside.js +37 -0
- package/dist-cjs/mega-menu/MegaMenuAside.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuContent.css.js +6 -0
- package/dist-cjs/mega-menu/MegaMenuContent.css.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuContent.js +29 -0
- package/dist-cjs/mega-menu/MegaMenuContent.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuContext.js +18 -0
- package/dist-cjs/mega-menu/MegaMenuContext.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuGroup.css.js +6 -0
- package/dist-cjs/mega-menu/MegaMenuGroup.css.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuGroup.js +44 -0
- package/dist-cjs/mega-menu/MegaMenuGroup.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuGroupContext.js +23 -0
- package/dist-cjs/mega-menu/MegaMenuGroupContext.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuGroupHeading.css.js +6 -0
- package/dist-cjs/mega-menu/MegaMenuGroupHeading.css.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuGroupHeading.js +44 -0
- package/dist-cjs/mega-menu/MegaMenuGroupHeading.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuGroups.css.js +6 -0
- package/dist-cjs/mega-menu/MegaMenuGroups.css.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuGroups.js +29 -0
- package/dist-cjs/mega-menu/MegaMenuGroups.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuList.css.js +6 -0
- package/dist-cjs/mega-menu/MegaMenuList.css.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuList.js +47 -0
- package/dist-cjs/mega-menu/MegaMenuList.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuListItem.css.js +6 -0
- package/dist-cjs/mega-menu/MegaMenuListItem.css.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuListItem.js +50 -0
- package/dist-cjs/mega-menu/MegaMenuListItem.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuPanel.css.js +6 -0
- package/dist-cjs/mega-menu/MegaMenuPanel.css.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuPanel.js +94 -0
- package/dist-cjs/mega-menu/MegaMenuPanel.js.map +1 -0
- package/dist-cjs/mega-menu/MegaMenuTrigger.js +97 -0
- package/dist-cjs/mega-menu/MegaMenuTrigger.js.map +1 -0
- package/dist-cjs/mega-menu/useMegaMenu.js +15 -0
- package/dist-cjs/mega-menu/useMegaMenu.js.map +1 -0
- package/dist-cjs/mega-menu/useMegaMenuNavigation.js +282 -0
- package/dist-cjs/mega-menu/useMegaMenuNavigation.js.map +1 -0
- package/dist-cjs/mega-menu/usePageMargin.js +28 -0
- package/dist-cjs/mega-menu/usePageMargin.js.map +1 -0
- package/dist-cjs/overlay/OverlayPanel.js +2 -1
- package/dist-cjs/overlay/OverlayPanel.js.map +1 -1
- package/dist-cjs/semantic-icon-provider/SemanticIconProvider.js +1 -0
- package/dist-cjs/semantic-icon-provider/SemanticIconProvider.js.map +1 -1
- package/dist-es/aria-announcer/AriaAnnouncerProvider.js +29 -12
- package/dist-es/aria-announcer/AriaAnnouncerProvider.js.map +1 -1
- package/dist-es/border-layout/BorderLayout.js +28 -7
- package/dist-es/border-layout/BorderLayout.js.map +1 -1
- package/dist-es/dialog/Dialog.js +3 -2
- package/dist-es/dialog/Dialog.js.map +1 -1
- package/dist-es/drawer/Drawer.js +2 -1
- package/dist-es/drawer/Drawer.js.map +1 -1
- package/dist-es/file-drop-zone/FileDropZone.js +20 -5
- package/dist-es/file-drop-zone/FileDropZone.js.map +1 -1
- package/dist-es/file-drop-zone/FileDropZoneTrigger.js +3 -2
- package/dist-es/file-drop-zone/FileDropZoneTrigger.js.map +1 -1
- package/dist-es/grid-layout/GridLayout.css.js +1 -1
- package/dist-es/index.js +11 -0
- package/dist-es/index.js.map +1 -1
- package/dist-es/mega-menu/MegaMenu.js +79 -0
- package/dist-es/mega-menu/MegaMenu.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuActions.css.js +4 -0
- package/dist-es/mega-menu/MegaMenuActions.css.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuActions.js +35 -0
- package/dist-es/mega-menu/MegaMenuActions.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuAside.css.js +4 -0
- package/dist-es/mega-menu/MegaMenuAside.css.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuAside.js +35 -0
- package/dist-es/mega-menu/MegaMenuAside.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuContent.css.js +4 -0
- package/dist-es/mega-menu/MegaMenuContent.css.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuContent.js +27 -0
- package/dist-es/mega-menu/MegaMenuContent.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuContext.js +16 -0
- package/dist-es/mega-menu/MegaMenuContext.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuGroup.css.js +4 -0
- package/dist-es/mega-menu/MegaMenuGroup.css.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuGroup.js +42 -0
- package/dist-es/mega-menu/MegaMenuGroup.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuGroupContext.js +20 -0
- package/dist-es/mega-menu/MegaMenuGroupContext.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuGroupHeading.css.js +4 -0
- package/dist-es/mega-menu/MegaMenuGroupHeading.css.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuGroupHeading.js +42 -0
- package/dist-es/mega-menu/MegaMenuGroupHeading.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuGroups.css.js +4 -0
- package/dist-es/mega-menu/MegaMenuGroups.css.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuGroups.js +27 -0
- package/dist-es/mega-menu/MegaMenuGroups.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuList.css.js +4 -0
- package/dist-es/mega-menu/MegaMenuList.css.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuList.js +45 -0
- package/dist-es/mega-menu/MegaMenuList.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuListItem.css.js +4 -0
- package/dist-es/mega-menu/MegaMenuListItem.css.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuListItem.js +48 -0
- package/dist-es/mega-menu/MegaMenuListItem.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuPanel.css.js +4 -0
- package/dist-es/mega-menu/MegaMenuPanel.css.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuPanel.js +92 -0
- package/dist-es/mega-menu/MegaMenuPanel.js.map +1 -0
- package/dist-es/mega-menu/MegaMenuTrigger.js +95 -0
- package/dist-es/mega-menu/MegaMenuTrigger.js.map +1 -0
- package/dist-es/mega-menu/useMegaMenu.js +13 -0
- package/dist-es/mega-menu/useMegaMenu.js.map +1 -0
- package/dist-es/mega-menu/useMegaMenuNavigation.js +278 -0
- package/dist-es/mega-menu/useMegaMenuNavigation.js.map +1 -0
- package/dist-es/mega-menu/usePageMargin.js +26 -0
- package/dist-es/mega-menu/usePageMargin.js.map +1 -0
- package/dist-es/overlay/OverlayPanel.js +2 -1
- package/dist-es/overlay/OverlayPanel.js.map +1 -1
- package/dist-es/semantic-icon-provider/SemanticIconProvider.js +1 -0
- package/dist-es/semantic-icon-provider/SemanticIconProvider.js.map +1 -1
- package/dist-types/index.d.ts +1 -0
- package/dist-types/mega-menu/MegaMenu.d.ts +36 -0
- package/dist-types/mega-menu/MegaMenuActions.d.ts +10 -0
- package/dist-types/mega-menu/MegaMenuAside.d.ts +9 -0
- package/dist-types/mega-menu/MegaMenuContent.d.ts +9 -0
- package/dist-types/mega-menu/MegaMenuContext.d.ts +28 -0
- package/dist-types/mega-menu/MegaMenuGroup.d.ts +9 -0
- package/dist-types/mega-menu/MegaMenuGroupContext.d.ts +12 -0
- package/dist-types/mega-menu/MegaMenuGroupHeading.d.ts +13 -0
- package/dist-types/mega-menu/MegaMenuGroups.d.ts +8 -0
- package/dist-types/mega-menu/MegaMenuList.d.ts +16 -0
- package/dist-types/mega-menu/MegaMenuListItem.d.ts +25 -0
- package/dist-types/mega-menu/MegaMenuPanel.d.ts +8 -0
- package/dist-types/mega-menu/MegaMenuTrigger.d.ts +9 -0
- package/dist-types/mega-menu/index.d.ts +11 -0
- package/dist-types/mega-menu/useMegaMenu.d.ts +6 -0
- package/dist-types/mega-menu/useMegaMenuNavigation.d.ts +16 -0
- package/dist-types/mega-menu/usePageMargin.d.ts +6 -0
- package/dist-types/semantic-icon-provider/SemanticIconProvider.d.ts +1 -0
- package/dist-types/tooltip/useTooltip.d.ts +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,48 @@
|
|
|
1
1
|
# @salt-ds/core
|
|
2
2
|
|
|
3
|
+
## 1.67.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 9c9b83e: Added `LevelSeparatorIcon` to `SemanticIconProvider`, defaulting to `ChevronRightIcon`.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 747cb08: Fixed `Dialog` not closing on `Escape` when `disableDismiss` was set. `disableDismiss` now only prevents dismissal via outside press, keeping `Escape` available so the dialog remains accessible.
|
|
12
|
+
- d84df88: Fixed `FileDropZone` drag-and-drop handling so disabled drop zones ignore dropped files while preventing browser file navigation, and non-file drops are cancelled without invoking the file `onDrop` callback. `FileDropZoneTrigger` now composes consumer `onClick` handlers and calls `onChange` before resetting the input value.
|
|
13
|
+
- 56855cb: Fixed `AriaAnnouncerProvider` leaking pending `setTimeout` handles used to drain announcements from the live region. The provider now tracks each scheduled removal and clears any outstanding timers on unmount, preventing `setState`-on-unmounted warnings and test-worker crashes (e.g. `ReferenceError: window is not defined`) when the provider unmounts within the announcement drain window.
|
|
14
|
+
- e226b17: Fixed `BorderLayout` leaving empty rows or columns when the `north`, `south`, `west`, or `east` regions were omitted. The grid template now only includes tracks for the regions that are present, so omitted regions no longer leave gaps.
|
|
15
|
+
- 747cb08: Fixed background content remaining interactive while a modal floating element (`Dialog`, `Drawer`, `Overlay`) was open. Outside elements are now marked inert for the duration the floating element is shown.
|
|
16
|
+
- d37a311: Updated Floating UI from `0.26.28` to `0.27.19`.
|
|
17
|
+
|
|
18
|
+
## 1.66.0
|
|
19
|
+
|
|
20
|
+
### Minor Changes
|
|
21
|
+
|
|
22
|
+
- f9f9b8e: `MegaMenu` is a large, expandable panel which opens from the main navigation. It displays and categorizes links to key application pages in a multi-column layout, allowing users to access a wide range of app features and content from a single menu.
|
|
23
|
+
|
|
24
|
+
Compose it with `MegaMenuTrigger`, `MegaMenuPanel`, `MegaMenuContent`, `MegaMenuAside`, `MegaMenuActions`, `MegaMenuGroups`, `MegaMenuGroup`, `MegaMenuGroupHeading`, `MegaMenuList`, and `MegaMenuListItem`.
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
<MegaMenu>
|
|
28
|
+
<MegaMenuTrigger>
|
|
29
|
+
<NavigationItem>Products</NavigationItem>
|
|
30
|
+
</MegaMenuTrigger>
|
|
31
|
+
<MegaMenuPanel>
|
|
32
|
+
<MegaMenuContent>
|
|
33
|
+
<MegaMenuGroups>
|
|
34
|
+
<MegaMenuGroup>
|
|
35
|
+
<MegaMenuGroupHeading>Group</MegaMenuGroupHeading>
|
|
36
|
+
<MegaMenuList>
|
|
37
|
+
<MegaMenuListItem href="#">Item</MegaMenuListItem>
|
|
38
|
+
</MegaMenuList>
|
|
39
|
+
</MegaMenuGroup>
|
|
40
|
+
</MegaMenuGroups>
|
|
41
|
+
</MegaMenuContent>
|
|
42
|
+
</MegaMenuPanel>
|
|
43
|
+
</MegaMenu>
|
|
44
|
+
```
|
|
45
|
+
|
|
3
46
|
## 1.65.1
|
|
4
47
|
|
|
5
48
|
### Patch Changes
|
package/css/salt-core.css
CHANGED
|
@@ -1699,8 +1699,8 @@ a:focus .saltCard-interactable.saltCard-disabled {
|
|
|
1699
1699
|
}
|
|
1700
1700
|
.saltGridLayout-area {
|
|
1701
1701
|
grid-template: var(--gridLayout-gridTemplate);
|
|
1702
|
-
grid-template-columns: min-content 1fr min-content;
|
|
1703
|
-
grid-template-rows: min-content 1fr min-content;
|
|
1702
|
+
grid-template-columns: var(--gridLayout-areaColumns, min-content 1fr min-content);
|
|
1703
|
+
grid-template-rows: var(--gridLayout-areaRows, min-content 1fr min-content);
|
|
1704
1704
|
}
|
|
1705
1705
|
|
|
1706
1706
|
/* src/input/Input.css */
|
|
@@ -2255,6 +2255,148 @@ a:focus .saltCard-interactable.saltCard-disabled {
|
|
|
2255
2255
|
outline: none;
|
|
2256
2256
|
}
|
|
2257
2257
|
|
|
2258
|
+
/* src/mega-menu/MegaMenuActions.css */
|
|
2259
|
+
.saltMegaMenuActions {
|
|
2260
|
+
display: flex;
|
|
2261
|
+
flex-wrap: wrap;
|
|
2262
|
+
margin-block-start: auto;
|
|
2263
|
+
}
|
|
2264
|
+
|
|
2265
|
+
/* src/mega-menu/MegaMenuAside.css */
|
|
2266
|
+
.saltMegaMenuAside {
|
|
2267
|
+
flex: 0 0 auto;
|
|
2268
|
+
display: flex;
|
|
2269
|
+
flex-direction: column;
|
|
2270
|
+
padding: var(--salt-spacing-300);
|
|
2271
|
+
}
|
|
2272
|
+
|
|
2273
|
+
/* src/mega-menu/MegaMenuContent.css */
|
|
2274
|
+
.saltMegaMenuContent {
|
|
2275
|
+
display: flex;
|
|
2276
|
+
flex-direction: column;
|
|
2277
|
+
gap: var(--salt-spacing-300);
|
|
2278
|
+
padding: var(--salt-spacing-300);
|
|
2279
|
+
min-width: 0;
|
|
2280
|
+
flex: 0 1 auto;
|
|
2281
|
+
max-inline-size: var(--saltMegaMenuPanel-availableWidth);
|
|
2282
|
+
box-sizing: border-box;
|
|
2283
|
+
}
|
|
2284
|
+
|
|
2285
|
+
/* src/mega-menu/MegaMenuGroup.css */
|
|
2286
|
+
.saltMegaMenuGroup {
|
|
2287
|
+
display: flex;
|
|
2288
|
+
flex-direction: column;
|
|
2289
|
+
}
|
|
2290
|
+
|
|
2291
|
+
/* src/mega-menu/MegaMenuGroupHeading.css */
|
|
2292
|
+
.saltMegaMenuGroupHeading {
|
|
2293
|
+
display: flex;
|
|
2294
|
+
align-items: center;
|
|
2295
|
+
margin: 0 0 var(--salt-spacing-50);
|
|
2296
|
+
padding: var(--salt-spacing-50) var(--salt-spacing-100);
|
|
2297
|
+
border-bottom: var(--salt-size-fixed-100) var(--salt-borderStyle-solid) var(--salt-separable-tertiary-borderColor);
|
|
2298
|
+
min-height: var(--salt-size-base);
|
|
2299
|
+
font-family: var(--salt-text-label-fontFamily);
|
|
2300
|
+
font-size: var(--salt-text-label-fontSize);
|
|
2301
|
+
font-weight: var(--salt-text-fontWeight-strong);
|
|
2302
|
+
line-height: var(--salt-text-label-lineHeight);
|
|
2303
|
+
color: var(--salt-content-secondary-foreground);
|
|
2304
|
+
}
|
|
2305
|
+
|
|
2306
|
+
/* src/mega-menu/MegaMenuGroups.css */
|
|
2307
|
+
.saltMegaMenuGroups {
|
|
2308
|
+
align-self: start;
|
|
2309
|
+
display: grid;
|
|
2310
|
+
grid-template-columns: repeat(auto-fit, minmax(0, var(--saltMegaMenuGroups-columnWidth, 12rem)));
|
|
2311
|
+
gap: var(--salt-spacing-300);
|
|
2312
|
+
min-width: 0;
|
|
2313
|
+
max-inline-size: var(--saltMegaMenuPanel-availableWidth);
|
|
2314
|
+
}
|
|
2315
|
+
|
|
2316
|
+
/* src/mega-menu/MegaMenuList.css */
|
|
2317
|
+
.saltMegaMenuList {
|
|
2318
|
+
list-style: none;
|
|
2319
|
+
margin: 0;
|
|
2320
|
+
padding: 0;
|
|
2321
|
+
display: flex;
|
|
2322
|
+
gap: var(--salt-spacing-fixed-100);
|
|
2323
|
+
flex-direction: column;
|
|
2324
|
+
}
|
|
2325
|
+
|
|
2326
|
+
/* src/mega-menu/MegaMenuListItem.css */
|
|
2327
|
+
.saltMegaMenuListItem {
|
|
2328
|
+
list-style: none;
|
|
2329
|
+
display: flex;
|
|
2330
|
+
flex-direction: column;
|
|
2331
|
+
}
|
|
2332
|
+
.saltMegaMenuListItem-wrapper {
|
|
2333
|
+
display: flex;
|
|
2334
|
+
padding: var(--salt-spacing-50) var(--salt-spacing-100);
|
|
2335
|
+
align-items: flex-start;
|
|
2336
|
+
color: var(--salt-content-primary-foreground);
|
|
2337
|
+
background: var(--salt-selectable-background);
|
|
2338
|
+
cursor: var(--salt-cursor-hover);
|
|
2339
|
+
min-height: calc(var(--salt-size-base) + var(--salt-spacing-100));
|
|
2340
|
+
box-sizing: border-box;
|
|
2341
|
+
gap: var(--salt-spacing-100);
|
|
2342
|
+
position: relative;
|
|
2343
|
+
border-radius: var(--salt-palette-corner-weak, 0);
|
|
2344
|
+
text-decoration: none;
|
|
2345
|
+
border: none;
|
|
2346
|
+
font: inherit;
|
|
2347
|
+
text-align: start;
|
|
2348
|
+
}
|
|
2349
|
+
.saltMegaMenuListItem-wrapper > .saltIcon {
|
|
2350
|
+
display: flex;
|
|
2351
|
+
height: var(--salt-size-base);
|
|
2352
|
+
align-items: center;
|
|
2353
|
+
}
|
|
2354
|
+
.saltMegaMenuListItem-content {
|
|
2355
|
+
flex: 1 0;
|
|
2356
|
+
margin: var(--salt-spacing-75) 0;
|
|
2357
|
+
font-family: var(--salt-text-fontFamily);
|
|
2358
|
+
font-size: var(--salt-text-fontSize);
|
|
2359
|
+
font-weight: var(--salt-text-fontWeight);
|
|
2360
|
+
line-height: var(--salt-text-lineHeight);
|
|
2361
|
+
}
|
|
2362
|
+
.saltMegaMenuListItem-wrapper:focus-visible {
|
|
2363
|
+
outline: var(--salt-focused-outline);
|
|
2364
|
+
outline-offset: calc(var(--salt-size-fixed-100) * -2);
|
|
2365
|
+
}
|
|
2366
|
+
.saltMegaMenuListItem-wrapper:hover:not(:focus-visible) {
|
|
2367
|
+
outline: none;
|
|
2368
|
+
background: var(--salt-overlayable-background-hover);
|
|
2369
|
+
}
|
|
2370
|
+
.saltMegaMenuListItem-wrapper:active {
|
|
2371
|
+
background: var(--salt-navigable-accent-background-active);
|
|
2372
|
+
}
|
|
2373
|
+
.saltMegaMenuListItem-wrapper:active::before {
|
|
2374
|
+
content: "";
|
|
2375
|
+
position: absolute;
|
|
2376
|
+
inset: 0;
|
|
2377
|
+
box-sizing: border-box;
|
|
2378
|
+
border-radius: inherit;
|
|
2379
|
+
border: var(--salt-size-fixed-100) var(--salt-borderStyle-solid) var(--salt-navigable-accent-borderColor-active);
|
|
2380
|
+
pointer-events: none;
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2383
|
+
/* src/mega-menu/MegaMenuPanel.css */
|
|
2384
|
+
.saltMegaMenuPanel {
|
|
2385
|
+
--saltMegaMenuPanel-availableWidth: calc(100vw - var(--salt-spacing-600));
|
|
2386
|
+
display: flex;
|
|
2387
|
+
align-items: stretch;
|
|
2388
|
+
inline-size: var(--saltMegaMenuPanel-inlineSize, fit-content);
|
|
2389
|
+
max-inline-size: var(--saltMegaMenuPanel-maxInlineSize, var(--saltMegaMenuPanel-availableWidth));
|
|
2390
|
+
max-block-size: 90vh;
|
|
2391
|
+
overflow-x: hidden;
|
|
2392
|
+
overflow-y: auto;
|
|
2393
|
+
box-sizing: border-box;
|
|
2394
|
+
border-radius: var(--salt-palette-corner, 0);
|
|
2395
|
+
border: var(--salt-size-fixed-100) var(--salt-borderStyle-solid) var(--salt-container-primary-borderColor);
|
|
2396
|
+
background: var(--salt-container-primary-background);
|
|
2397
|
+
box-shadow: var(--salt-overlayable-shadow-modal);
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2258
2400
|
/* src/menu/MenuGroup.css */
|
|
2259
2401
|
.saltMenuGroup-label {
|
|
2260
2402
|
background: var(--salt-container-primary-background);
|
|
@@ -6741,4 +6883,4 @@ label.saltText small,
|
|
|
6741
6883
|
box-shadow: 0 calc(var(--salt-size-fixed-100) * -1) 0 0 var(--salt-selectable-borderColor-selected), 0 var(--salt-size-fixed-100) 0 0 var(--salt-selectable-borderColor-selected);
|
|
6742
6884
|
}
|
|
6743
6885
|
|
|
6744
|
-
/* src/
|
|
6886
|
+
/* src/a8bb4014-b47b-4c2e-99dd-7c7ffe21f367.css */
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var window = require('@salt-ds/window');
|
|
4
5
|
var React = require('react');
|
|
5
6
|
var useIsomorphicLayoutEffect = require('../utils/useIsomorphicLayoutEffect.js');
|
|
6
7
|
var AriaAnnouncerContext = require('./AriaAnnouncerContext.js');
|
|
@@ -18,9 +19,25 @@ const AnnouncementRegion = React.forwardRef(function AnnouncementRegion2(props,
|
|
|
18
19
|
);
|
|
19
20
|
});
|
|
20
21
|
const AriaAnnouncerProvider = React.forwardRef(function AriaAnnouncerProvider2({ children, style, target, ...rest }, ref) {
|
|
22
|
+
const targetWindow = window.useWindow();
|
|
21
23
|
const [politeAnnouncements, setPoliteAnnouncements] = React.useState([]);
|
|
22
24
|
const [assertiveAnnouncements, setAssertiveAnnouncements] = React.useState([]);
|
|
23
25
|
const idCounterRef = React.useRef(0);
|
|
26
|
+
const timeoutsRef = React.useRef(/* @__PURE__ */ new Set());
|
|
27
|
+
const scheduleRemoval = React.useCallback(
|
|
28
|
+
(id, assertiveness, duration) => {
|
|
29
|
+
if (!targetWindow) return;
|
|
30
|
+
const setter = assertiveness === "polite" ? setPoliteAnnouncements : setAssertiveAnnouncements;
|
|
31
|
+
const handle = targetWindow.setTimeout(() => {
|
|
32
|
+
timeoutsRef.current.delete(handle);
|
|
33
|
+
setter(
|
|
34
|
+
(previous) => previous.filter((announcement) => announcement.id !== id)
|
|
35
|
+
);
|
|
36
|
+
}, duration);
|
|
37
|
+
timeoutsRef.current.add(handle);
|
|
38
|
+
},
|
|
39
|
+
[targetWindow]
|
|
40
|
+
);
|
|
24
41
|
const makeAnnouncement = React.useCallback(
|
|
25
42
|
(message, assertiveness = "polite", duration = ANNOUNCEMENT_TIME_IN_DOM) => {
|
|
26
43
|
idCounterRef.current += 1;
|
|
@@ -29,24 +46,24 @@ const AriaAnnouncerProvider = React.forwardRef(function AriaAnnouncerProvider2({
|
|
|
29
46
|
setPoliteAnnouncements((previous) => {
|
|
30
47
|
return previous.concat({ id, message });
|
|
31
48
|
});
|
|
32
|
-
setTimeout(() => {
|
|
33
|
-
setPoliteAnnouncements(
|
|
34
|
-
(previous) => previous.filter((announcement) => announcement.id !== id)
|
|
35
|
-
);
|
|
36
|
-
}, duration);
|
|
37
49
|
} else {
|
|
38
50
|
setAssertiveAnnouncements((previous) => {
|
|
39
51
|
return previous.concat({ id, message });
|
|
40
52
|
});
|
|
41
|
-
setTimeout(() => {
|
|
42
|
-
setAssertiveAnnouncements(
|
|
43
|
-
(previous) => previous.filter((announcement) => announcement.id !== id)
|
|
44
|
-
);
|
|
45
|
-
}, duration);
|
|
46
53
|
}
|
|
54
|
+
scheduleRemoval(id, assertiveness, duration);
|
|
47
55
|
},
|
|
48
|
-
[]
|
|
56
|
+
[scheduleRemoval]
|
|
49
57
|
);
|
|
58
|
+
React.useEffect(() => {
|
|
59
|
+
const timeouts = timeoutsRef.current;
|
|
60
|
+
return () => {
|
|
61
|
+
for (const handle of timeouts) {
|
|
62
|
+
targetWindow == null ? void 0 : targetWindow.clearTimeout(handle);
|
|
63
|
+
}
|
|
64
|
+
timeouts.clear();
|
|
65
|
+
};
|
|
66
|
+
}, [targetWindow]);
|
|
50
67
|
const announce = React.useCallback(
|
|
51
68
|
(announcement, legacyDelayOrOptions = {}) => {
|
|
52
69
|
const options = typeof legacyDelayOrOptions === "object" && legacyDelayOrOptions ? legacyDelayOrOptions : {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AriaAnnouncerProvider.js","sources":["../src/aria-announcer/AriaAnnouncerProvider.tsx"],"sourcesContent":["import {\n type ComponentPropsWithRef,\n forwardRef,\n useCallback,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useIsomorphicLayoutEffect } from \"../utils/useIsomorphicLayoutEffect\";\nimport {\n type AnnounceFnOptions,\n AriaAnnouncerContext,\n} from \"./AriaAnnouncerContext\";\nimport { registerAnnouncementTarget } from \"./announcementRegistry\";\n\nexport const ANNOUNCEMENT_TIME_IN_DOM = 300; // time between DOM updates\n\nexport interface AriaAnnouncerProviderProps\n extends ComponentPropsWithRef<\"div\"> {\n /**\n * Optional target key used to route announcements to this provider.\n */\n target?: string;\n}\n\nconst AnnouncementRegion = forwardRef<\n HTMLDivElement,\n ComponentPropsWithRef<\"div\">\n>(function AnnouncementRegion(props, ref) {\n return (\n <div\n // Keep the region simple for maximum assistive-tech compatibility.\n // aria-live is applied by the caller (polite/assertive).\n aria-atomic={false}\n ref={ref}\n {...props}\n />\n );\n});\n\ntype AnnouncementMessage = {\n id: string;\n message: string;\n};\n\nexport const AriaAnnouncerProvider = forwardRef<\n HTMLDivElement,\n AriaAnnouncerProviderProps\n>(function AriaAnnouncerProvider({ children, style, target, ...rest }, ref) {\n const [politeAnnouncements, setPoliteAnnouncements] = useState<\n AnnouncementMessage[]\n >([]);\n const [assertiveAnnouncements, setAssertiveAnnouncements] = useState<\n AnnouncementMessage[]\n >([]);\n\n const idCounterRef = useRef(0);\n\n const makeAnnouncement = useCallback(\n (\n message: string,\n assertiveness: \"polite\" | \"assertive\" = \"polite\",\n duration: number = ANNOUNCEMENT_TIME_IN_DOM,\n ) => {\n idCounterRef.current += 1;\n // Date.now() can collide when multiple announcements are created in the same millisecond\n // (e.g. tests with cy.clock, batching, or multiple announces during one tick).\n // Add a monotonic counter suffix to guarantee uniqueness.\n const id = `announce-${assertiveness}-${Date.now()}-${idCounterRef.current}`;\n if (assertiveness === \"polite\") {\n setPoliteAnnouncements((previous) => {\n return previous.concat({ id, message });\n });\n\n
|
|
1
|
+
{"version":3,"file":"AriaAnnouncerProvider.js","sources":["../src/aria-announcer/AriaAnnouncerProvider.tsx"],"sourcesContent":["import { useWindow } from \"@salt-ds/window\";\nimport {\n type ComponentPropsWithRef,\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useIsomorphicLayoutEffect } from \"../utils/useIsomorphicLayoutEffect\";\nimport {\n type AnnounceFnOptions,\n AriaAnnouncerContext,\n} from \"./AriaAnnouncerContext\";\nimport { registerAnnouncementTarget } from \"./announcementRegistry\";\n\nexport const ANNOUNCEMENT_TIME_IN_DOM = 300; // time between DOM updates\n\nexport interface AriaAnnouncerProviderProps\n extends ComponentPropsWithRef<\"div\"> {\n /**\n * Optional target key used to route announcements to this provider.\n */\n target?: string;\n}\n\nconst AnnouncementRegion = forwardRef<\n HTMLDivElement,\n ComponentPropsWithRef<\"div\">\n>(function AnnouncementRegion(props, ref) {\n return (\n <div\n // Keep the region simple for maximum assistive-tech compatibility.\n // aria-live is applied by the caller (polite/assertive).\n aria-atomic={false}\n ref={ref}\n {...props}\n />\n );\n});\n\ntype AnnouncementMessage = {\n id: string;\n message: string;\n};\n\nexport const AriaAnnouncerProvider = forwardRef<\n HTMLDivElement,\n AriaAnnouncerProviderProps\n>(function AriaAnnouncerProvider({ children, style, target, ...rest }, ref) {\n const targetWindow = useWindow();\n\n const [politeAnnouncements, setPoliteAnnouncements] = useState<\n AnnouncementMessage[]\n >([]);\n const [assertiveAnnouncements, setAssertiveAnnouncements] = useState<\n AnnouncementMessage[]\n >([]);\n\n const idCounterRef = useRef(0);\n const timeoutsRef = useRef<Set<number>>(new Set());\n\n const scheduleRemoval = useCallback(\n (id: string, assertiveness: \"polite\" | \"assertive\", duration: number) => {\n if (!targetWindow) return;\n\n const setter =\n assertiveness === \"polite\"\n ? setPoliteAnnouncements\n : setAssertiveAnnouncements;\n const handle = targetWindow.setTimeout(() => {\n timeoutsRef.current.delete(handle);\n setter((previous) =>\n previous.filter((announcement) => announcement.id !== id),\n );\n }, duration);\n timeoutsRef.current.add(handle);\n },\n [targetWindow],\n );\n\n const makeAnnouncement = useCallback(\n (\n message: string,\n assertiveness: \"polite\" | \"assertive\" = \"polite\",\n duration: number = ANNOUNCEMENT_TIME_IN_DOM,\n ) => {\n idCounterRef.current += 1;\n // Date.now() can collide when multiple announcements are created in the same millisecond\n // (e.g. tests with cy.clock, batching, or multiple announces during one tick).\n // Add a monotonic counter suffix to guarantee uniqueness.\n const id = `announce-${assertiveness}-${Date.now()}-${idCounterRef.current}`;\n if (assertiveness === \"polite\") {\n setPoliteAnnouncements((previous) => {\n return previous.concat({ id, message });\n });\n } else {\n setAssertiveAnnouncements((previous) => {\n return previous.concat({ id, message });\n });\n }\n scheduleRemoval(id, assertiveness, duration);\n },\n [scheduleRemoval],\n );\n\n useEffect(() => {\n const timeouts = timeoutsRef.current;\n return () => {\n for (const handle of timeouts) {\n targetWindow?.clearTimeout(handle);\n }\n timeouts.clear();\n };\n }, [targetWindow]);\n\n const announce = useCallback(\n (\n announcement: string,\n legacyDelayOrOptions: number | AnnounceFnOptions | undefined = {},\n ) => {\n // Legacy delay (number arg) is handled by useAriaAnnouncer; if we also delayed\n // here we'd apply it twice. Keep supporting the signature but ignore the delay.\n const options: AnnounceFnOptions =\n typeof legacyDelayOrOptions === \"object\" && legacyDelayOrOptions\n ? legacyDelayOrOptions\n : {};\n\n makeAnnouncement(\n announcement,\n options.ariaLive,\n options.duration ?? ANNOUNCEMENT_TIME_IN_DOM,\n );\n },\n [makeAnnouncement],\n );\n\n const value = useMemo(() => ({ announce }), [announce]);\n\n useIsomorphicLayoutEffect(() => {\n if (!target) {\n return;\n }\n return registerAnnouncementTarget(target, announce);\n }, [announce, target]);\n\n return (\n <AriaAnnouncerContext.Provider value={value}>\n {children}\n <div\n // hidden styling based on https://tailwindcss.com/docs/screen-readers\n style={{\n position: \"absolute\",\n height: 1,\n width: 1,\n padding: 0,\n margin: -1,\n overflow: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n whiteSpace: \"nowrap\",\n borderWidth: 0,\n ...style,\n }}\n {...rest}\n ref={ref}\n >\n <AnnouncementRegion aria-live=\"polite\">\n {politeAnnouncements.map((announcement) => (\n <div key={`polite-${announcement.id}`}>{announcement.message}</div>\n ))}\n </AnnouncementRegion>\n <AnnouncementRegion aria-live=\"assertive\">\n {assertiveAnnouncements.map((announcement) => (\n <div key={`assertive-${announcement.id}`}>\n {announcement.message}\n </div>\n ))}\n </AnnouncementRegion>\n </div>\n </AriaAnnouncerContext.Provider>\n );\n});\n"],"names":["forwardRef","AnnouncementRegion","jsx","AriaAnnouncerProvider","useWindow","useState","useRef","useCallback","useEffect","useMemo","useIsomorphicLayoutEffect","registerAnnouncementTarget","jsxs","AriaAnnouncerContext"],"mappings":"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"}
|
|
@@ -19,12 +19,31 @@ const BorderLayout = React.forwardRef(
|
|
|
19
19
|
children,
|
|
20
20
|
(child) => React.isValidElement(child) && child.props.position
|
|
21
21
|
);
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
|
|
22
|
+
const hasNorth = borderAreas.includes("north");
|
|
23
|
+
const hasWest = borderAreas.includes("west");
|
|
24
|
+
const hasEast = borderAreas.includes("east");
|
|
25
|
+
const hasSouth = borderAreas.includes("south");
|
|
26
|
+
const middleColumns = [
|
|
27
|
+
hasWest ? "west" : void 0,
|
|
28
|
+
"center",
|
|
29
|
+
hasEast ? "east" : void 0
|
|
30
|
+
].filter(Boolean);
|
|
31
|
+
const gridTemplateColumns = [
|
|
32
|
+
hasWest ? "min-content" : void 0,
|
|
33
|
+
"1fr",
|
|
34
|
+
hasEast ? "min-content" : void 0
|
|
35
|
+
].filter(Boolean).join(" ");
|
|
36
|
+
const gridTemplateRows = [
|
|
37
|
+
hasNorth ? "min-content" : void 0,
|
|
38
|
+
"1fr",
|
|
39
|
+
hasSouth ? "min-content" : void 0
|
|
40
|
+
].filter(Boolean).join(" ");
|
|
41
|
+
const gridTemplateSections = [
|
|
42
|
+
hasNorth ? `"${"north ".repeat(middleColumns.length).trimEnd()}"` : void 0,
|
|
43
|
+
`"${middleColumns.join(" ")}"`,
|
|
44
|
+
hasSouth ? `"${"south ".repeat(middleColumns.length).trimEnd()}"` : void 0
|
|
45
|
+
].filter(Boolean);
|
|
46
|
+
const gridTemplateAreas = gridTemplateSections.join(" ");
|
|
28
47
|
const hasMainSection = borderAreas.includes("center");
|
|
29
48
|
React.useEffect(() => {
|
|
30
49
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -37,7 +56,9 @@ const BorderLayout = React.forwardRef(
|
|
|
37
56
|
}, [hasMainSection]);
|
|
38
57
|
const borderLayoutStyles = {
|
|
39
58
|
...style,
|
|
40
|
-
"--gridLayout-gridTemplate": gridTemplateAreas
|
|
59
|
+
"--gridLayout-gridTemplate": gridTemplateAreas,
|
|
60
|
+
"--gridLayout-areaColumns": gridTemplateColumns,
|
|
61
|
+
"--gridLayout-areaRows": gridTemplateRows
|
|
41
62
|
};
|
|
42
63
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
43
64
|
GridLayout.GridLayout,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BorderLayout.js","sources":["../src/border-layout/BorderLayout.tsx"],"sourcesContent":["import { clsx } from \"clsx\";\nimport {\n Children,\n type ElementType,\n type ForwardedRef,\n type FunctionComponent,\n forwardRef,\n isValidElement,\n type ReactNode,\n useEffect,\n} from \"react\";\n\nimport type { BorderPosition } from \"../border-item\";\nimport { GridLayout, type GridLayoutProps } from \"../grid-layout\";\nimport {\n makePrefixer,\n type PolymorphicComponentPropWithRef,\n type ResponsiveProp,\n} from \"../utils\";\n\nexport type BorderLayoutProps<T extends ElementType> =\n PolymorphicComponentPropWithRef<\n T,\n {\n /**\n * Defines the size of the gutter between the columns and the rows by setting a density multiplier. Defaults to 0\n */\n gap?: GridLayoutProps<T>[\"gap\"];\n /**\n * Defines the size of the gutter between the columns by setting a density multiplier. Defaults to 0\n */\n columnGap?: GridLayoutProps<T>[\"columnGap\"];\n /**\n * Defines the size of the gutter between the rows by setting a density multiplier. Defaults to 0\n */\n rowGap?: GridLayoutProps<T>[\"rowGap\"];\n /**\n * Border item components to be rendered.\n */\n children: ReactNode;\n /**\n * Defines the margin around the component. It can be specified as a number (which acts as a multiplier) or a string representing the margin value. Default is `0`.\n */\n margin?: ResponsiveProp<number | string>;\n /**\n * Defines the padding within the component. It can be specified as a number (which acts as a multiplier) or a string representing the padding value. Default is `0`.\n */\n padding?: ResponsiveProp<number | string>;\n }\n >;\n\nconst withBaseName = makePrefixer(\"saltBorderLayout\");\n\nconst numberOfColumns = 3;\n\ntype BorderLayoutComponent = <T extends ElementType = \"div\">(\n props: BorderLayoutProps<T>,\n) => ReturnType<FunctionComponent>;\n\nexport const BorderLayout: BorderLayoutComponent = forwardRef(\n function BorderLayout<T extends ElementType>(\n props: unknown,\n ref?: ForwardedRef<unknown>,\n ) {\n // Props need to be typed this way due to polymorphic types not working with required props.\n const { as, children, className, gap, style, ...rest } =\n props as BorderLayoutProps<T>;\n\n const borderAreas = Children.map(\n children,\n (child) => isValidElement(child) && child.props.position,\n ) as BorderPosition[];\n\n const
|
|
1
|
+
{"version":3,"file":"BorderLayout.js","sources":["../src/border-layout/BorderLayout.tsx"],"sourcesContent":["import { clsx } from \"clsx\";\nimport {\n Children,\n type ElementType,\n type ForwardedRef,\n type FunctionComponent,\n forwardRef,\n isValidElement,\n type ReactNode,\n useEffect,\n} from \"react\";\n\nimport type { BorderPosition } from \"../border-item\";\nimport { GridLayout, type GridLayoutProps } from \"../grid-layout\";\nimport {\n makePrefixer,\n type PolymorphicComponentPropWithRef,\n type ResponsiveProp,\n} from \"../utils\";\n\nexport type BorderLayoutProps<T extends ElementType> =\n PolymorphicComponentPropWithRef<\n T,\n {\n /**\n * Defines the size of the gutter between the columns and the rows by setting a density multiplier. Defaults to 0\n */\n gap?: GridLayoutProps<T>[\"gap\"];\n /**\n * Defines the size of the gutter between the columns by setting a density multiplier. Defaults to 0\n */\n columnGap?: GridLayoutProps<T>[\"columnGap\"];\n /**\n * Defines the size of the gutter between the rows by setting a density multiplier. Defaults to 0\n */\n rowGap?: GridLayoutProps<T>[\"rowGap\"];\n /**\n * Border item components to be rendered.\n */\n children: ReactNode;\n /**\n * Defines the margin around the component. It can be specified as a number (which acts as a multiplier) or a string representing the margin value. Default is `0`.\n */\n margin?: ResponsiveProp<number | string>;\n /**\n * Defines the padding within the component. It can be specified as a number (which acts as a multiplier) or a string representing the padding value. Default is `0`.\n */\n padding?: ResponsiveProp<number | string>;\n }\n >;\n\nconst withBaseName = makePrefixer(\"saltBorderLayout\");\n\nconst numberOfColumns = 3;\n\ntype BorderLayoutComponent = <T extends ElementType = \"div\">(\n props: BorderLayoutProps<T>,\n) => ReturnType<FunctionComponent>;\n\nexport const BorderLayout: BorderLayoutComponent = forwardRef(\n function BorderLayout<T extends ElementType>(\n props: unknown,\n ref?: ForwardedRef<unknown>,\n ) {\n // Props need to be typed this way due to polymorphic types not working with required props.\n const { as, children, className, gap, style, ...rest } =\n props as BorderLayoutProps<T>;\n\n const borderAreas = Children.map(\n children,\n (child) => isValidElement(child) && child.props.position,\n ) as BorderPosition[];\n\n const hasNorth = borderAreas.includes(\"north\");\n const hasWest = borderAreas.includes(\"west\");\n const hasEast = borderAreas.includes(\"east\");\n const hasSouth = borderAreas.includes(\"south\");\n\n const middleColumns = [\n hasWest ? \"west\" : undefined,\n \"center\",\n hasEast ? \"east\" : undefined,\n ].filter(Boolean) as BorderPosition[];\n\n const gridTemplateColumns = [\n hasWest ? \"min-content\" : undefined,\n \"1fr\",\n hasEast ? \"min-content\" : undefined,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const gridTemplateRows = [\n hasNorth ? \"min-content\" : undefined,\n \"1fr\",\n hasSouth ? \"min-content\" : undefined,\n ]\n .filter(Boolean)\n .join(\" \");\n\n const gridTemplateSections = [\n hasNorth\n ? `\"${\"north \".repeat(middleColumns.length).trimEnd()}\"`\n : undefined,\n `\"${middleColumns.join(\" \")}\"`,\n hasSouth\n ? `\"${\"south \".repeat(middleColumns.length).trimEnd()}\"`\n : undefined,\n ].filter(Boolean);\n\n const gridTemplateAreas = gridTemplateSections.join(\" \");\n\n const hasMainSection = borderAreas.includes(\"center\");\n\n useEffect(() => {\n if (process.env.NODE_ENV !== \"production\") {\n if (!hasMainSection) {\n console.warn(\n \"No main section has been found. A main section should be provided.\",\n );\n }\n }\n }, [hasMainSection]);\n\n const borderLayoutStyles = {\n ...style,\n \"--gridLayout-gridTemplate\": gridTemplateAreas,\n \"--gridLayout-areaColumns\": gridTemplateColumns,\n \"--gridLayout-areaRows\": gridTemplateRows,\n };\n\n return (\n <GridLayout\n as={as as ElementType}\n className={clsx(withBaseName(), className, \"saltGridLayout-area\")}\n columns={numberOfColumns}\n gap={gap || 0}\n style={borderLayoutStyles}\n ref={ref}\n {...rest}\n >\n {children}\n </GridLayout>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","BorderLayout","Children","isValidElement","useEffect","jsx","GridLayout","clsx"],"mappings":"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"}
|
|
@@ -59,7 +59,7 @@ const Dialog = React.forwardRef(
|
|
|
59
59
|
});
|
|
60
60
|
const { getFloatingProps } = react.useInteractions([
|
|
61
61
|
react.useClick(context),
|
|
62
|
-
react.useDismiss(context, {
|
|
62
|
+
react.useDismiss(context, { outsidePress: !disableDismiss })
|
|
63
63
|
]);
|
|
64
64
|
const { Component: FloatingComponent } = useFloatingUI.useFloatingComponent();
|
|
65
65
|
const floatingRef = useForkRef.useForkRef(floating, ref);
|
|
@@ -92,7 +92,8 @@ const Dialog = React.forwardRef(
|
|
|
92
92
|
lockScroll: true,
|
|
93
93
|
focusManagerProps: {
|
|
94
94
|
context,
|
|
95
|
-
initialFocus
|
|
95
|
+
initialFocus,
|
|
96
|
+
outsideElementsInert: true
|
|
96
97
|
},
|
|
97
98
|
className: clsx.clsx(
|
|
98
99
|
withBaseName(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.js","sources":["../src/dialog/Dialog.tsx"],"sourcesContent":["import {\n type FloatingFocusManager,\n useClick,\n useDismiss,\n useInteractions,\n} from \"@floating-ui/react\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentProps,\n forwardRef,\n type HTMLAttributes,\n type ReactNode,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport { Scrim } from \"../scrim\";\nimport type { ValidationStatus } from \"../status-indicator\";\nimport {\n makePrefixer,\n useCurrentBreakpoint,\n useFloatingComponent,\n useFloatingUI,\n useForkRef,\n useId,\n} from \"../utils\";\nimport dialogCss from \"./Dialog.css\";\nimport { DialogContext } from \"./DialogContext\";\n\ninterface ConditionalScrimWrapperProps {\n children?: ReactNode;\n condition: boolean;\n}\n\nexport const ConditionalScrimWrapper = ({\n condition,\n children,\n}: ConditionalScrimWrapperProps) => {\n return condition ? <Scrim fixed>{children}</Scrim> : <>{children} </>;\n};\n\nexport interface DialogProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * Display or hide the component.\n */\n open?: boolean;\n /**\n * Callback function triggered when open state changes.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * The status of the Dialog\n * */\n status?: ValidationStatus;\n /**\n * Which element to initially focus. Can be either a number (tabbable index as specified by the order) or a ref.\n * Default value is 0 (first tabbable element).\n * */\n initialFocus?: ComponentProps<typeof FloatingFocusManager>[\"initialFocus\"];\n /**\n * Size of the Dialog\n * */\n size?: \"small\" | \"medium\" | \"large\";\n /**\n * Prevent the dialog closing on click away\n * */\n disableDismiss?: boolean;\n /**\n * Prevent Scrim from rendering\n * */\n disableScrim?: boolean;\n /**\n * @deprecated IDs are now auto-generated internally for proper ARIA labeling.\n *\n * Optional id prop\n * Used for accessibility purposes to announce the title and subtitle when using a screen reader\n * */\n idProp?: string;\n}\n\nconst withBaseName = makePrefixer(\"saltDialog\");\n\nexport const Dialog = forwardRef<HTMLDivElement, DialogProps>(\n function Dialog(props, ref) {\n const {\n children,\n className,\n open = false,\n onOpenChange,\n status,\n disableDismiss,\n size = \"medium\",\n disableScrim,\n idProp,\n initialFocus,\n id,\n \"aria-labelledby\": ariaLabelledBy,\n ...rest\n } = props;\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-dialog\",\n css: dialogCss,\n window: targetWindow,\n });\n\n const dialogId = useId(id);\n const currentBreakpoint = useCurrentBreakpoint();\n\n const [showComponent, setShowComponent] = useState(false);\n const [headerId, setHeaderId] = useState(idProp);\n\n const { context, floating, elements } = useFloatingUI({\n open: showComponent,\n onOpenChange,\n });\n\n const { getFloatingProps } = useInteractions([\n useClick(context),\n useDismiss(context, {
|
|
1
|
+
{"version":3,"file":"Dialog.js","sources":["../src/dialog/Dialog.tsx"],"sourcesContent":["import {\n type FloatingFocusManager,\n useClick,\n useDismiss,\n useInteractions,\n} from \"@floating-ui/react\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentProps,\n forwardRef,\n type HTMLAttributes,\n type ReactNode,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport { Scrim } from \"../scrim\";\nimport type { ValidationStatus } from \"../status-indicator\";\nimport {\n makePrefixer,\n useCurrentBreakpoint,\n useFloatingComponent,\n useFloatingUI,\n useForkRef,\n useId,\n} from \"../utils\";\nimport dialogCss from \"./Dialog.css\";\nimport { DialogContext } from \"./DialogContext\";\n\ninterface ConditionalScrimWrapperProps {\n children?: ReactNode;\n condition: boolean;\n}\n\nexport const ConditionalScrimWrapper = ({\n condition,\n children,\n}: ConditionalScrimWrapperProps) => {\n return condition ? <Scrim fixed>{children}</Scrim> : <>{children} </>;\n};\n\nexport interface DialogProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * Display or hide the component.\n */\n open?: boolean;\n /**\n * Callback function triggered when open state changes.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * The status of the Dialog\n * */\n status?: ValidationStatus;\n /**\n * Which element to initially focus. Can be either a number (tabbable index as specified by the order) or a ref.\n * Default value is 0 (first tabbable element).\n * */\n initialFocus?: ComponentProps<typeof FloatingFocusManager>[\"initialFocus\"];\n /**\n * Size of the Dialog\n * */\n size?: \"small\" | \"medium\" | \"large\";\n /**\n * Prevent the dialog closing on click away\n * */\n disableDismiss?: boolean;\n /**\n * Prevent Scrim from rendering\n * */\n disableScrim?: boolean;\n /**\n * @deprecated IDs are now auto-generated internally for proper ARIA labeling.\n *\n * Optional id prop\n * Used for accessibility purposes to announce the title and subtitle when using a screen reader\n * */\n idProp?: string;\n}\n\nconst withBaseName = makePrefixer(\"saltDialog\");\n\nexport const Dialog = forwardRef<HTMLDivElement, DialogProps>(\n function Dialog(props, ref) {\n const {\n children,\n className,\n open = false,\n onOpenChange,\n status,\n disableDismiss,\n size = \"medium\",\n disableScrim,\n idProp,\n initialFocus,\n id,\n \"aria-labelledby\": ariaLabelledBy,\n ...rest\n } = props;\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-dialog\",\n css: dialogCss,\n window: targetWindow,\n });\n\n const dialogId = useId(id);\n const currentBreakpoint = useCurrentBreakpoint();\n\n const [showComponent, setShowComponent] = useState(false);\n const [headerId, setHeaderId] = useState(idProp);\n\n const { context, floating, elements } = useFloatingUI({\n open: showComponent,\n onOpenChange,\n });\n\n const { getFloatingProps } = useInteractions([\n useClick(context),\n useDismiss(context, { outsidePress: !disableDismiss }),\n ]);\n\n const { Component: FloatingComponent } = useFloatingComponent();\n\n const floatingRef = useForkRef<HTMLDivElement>(floating, ref);\n\n useEffect(() => {\n if (open && !showComponent) {\n setShowComponent(true);\n }\n\n if (!open && showComponent) {\n const animate = setTimeout(() => {\n setShowComponent(false);\n }, 300); // var(--salt-duration-perceptible)\n return () => clearTimeout(animate);\n }\n }, [open, showComponent]);\n\n const contextValue = useMemo(\n () => ({ status, id: headerId, setId: setHeaderId, dialogId }),\n [status, headerId, dialogId],\n );\n\n return (\n <DialogContext.Provider value={contextValue}>\n <ConditionalScrimWrapper condition={showComponent && !disableScrim}>\n <FloatingComponent\n id={dialogId}\n open={showComponent}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={clsx(ariaLabelledBy, headerId) || undefined}\n ref={floatingRef}\n width={elements.floating?.offsetWidth}\n height={elements.floating?.offsetHeight}\n lockScroll\n focusManagerProps={{\n context: context,\n initialFocus,\n outsideElementsInert: true,\n }}\n className={clsx(\n withBaseName(),\n withBaseName(size, currentBreakpoint),\n {\n [withBaseName(\"enterAnimation\")]: open,\n [withBaseName(\"exitAnimation\")]: !open,\n [withBaseName(status as string)]: status,\n },\n className,\n )}\n onAnimationEnd={() => {\n if (!open && showComponent) {\n setShowComponent(false);\n }\n }}\n {...getFloatingProps()}\n {...rest}\n >\n {children}\n </FloatingComponent>\n </ConditionalScrimWrapper>\n </DialogContext.Provider>\n );\n },\n);\n"],"names":["jsx","Scrim","jsxs","Fragment","makePrefixer","forwardRef","Dialog","useWindow","useComponentCssInjection","dialogCss","useId","useCurrentBreakpoint","useState","useFloatingUI","useInteractions","useClick","useDismiss","useFloatingComponent","useForkRef","useEffect","useMemo","DialogContext","clsx"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Drawer.js","sources":["../src/drawer/Drawer.tsx"],"sourcesContent":["import {\n type FloatingFocusManager,\n useClick,\n useDismiss,\n useInteractions,\n} from \"@floating-ui/react\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type PropsWithChildren,\n useEffect,\n useState,\n} from \"react\";\nimport { Scrim } from \"../scrim\";\nimport {\n makePrefixer,\n useFloatingComponent,\n useFloatingUI,\n useForkRef,\n} from \"../utils\";\nimport drawerCss from \"./Drawer.css\";\n\ninterface ConditionalScrimWrapperProps extends PropsWithChildren {\n condition: boolean;\n}\n\nconst ConditionalScrimWrapper = ({\n condition,\n children,\n}: ConditionalScrimWrapperProps) => {\n return condition ? <Scrim fixed> {children} </Scrim> : <>{children} </>;\n};\n\nexport interface DrawerProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * Defines the drawer position within the screen. Defaults to `left`.\n */\n position?: \"left\" | \"top\" | \"right\" | \"bottom\";\n /**\n * Display or hide the component.\n */\n open?: boolean;\n /**\n * Callback function triggered when open state changes.\n */\n onOpenChange?: (newOpen: boolean) => void;\n /**\n * Change background color palette\n */\n variant?: \"primary\" | \"secondary\" | \"tertiary\";\n /**\n * Prevent the dialog closing on click away\n * */\n disableDismiss?: boolean;\n /**\n * Prevent Scrim from rendering\n * */\n disableScrim?: boolean;\n /**\n * Which element to initially focus. Can be either a number (tabbable index as specified by the order) or a ref.\n * Default value is 0 (first tabbable element).\n * */\n initialFocus?: ComponentPropsWithoutRef<\n typeof FloatingFocusManager\n >[\"initialFocus\"];\n}\n\nconst withBaseName = makePrefixer(\"saltDrawer\");\n\nexport const Drawer = forwardRef<HTMLDivElement, DrawerProps>(\n function Drawer(props, ref) {\n const {\n children,\n className,\n position = \"left\",\n open = false,\n onOpenChange,\n variant = \"primary\",\n disableDismiss,\n disableScrim,\n initialFocus,\n ...rest\n } = props;\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-drawer\",\n css: drawerCss,\n window: targetWindow,\n });\n\n const [showComponent, setShowComponent] = useState(false);\n const { Component: FloatingComponent } = useFloatingComponent();\n\n const { context, floating, elements } = useFloatingUI({\n open: showComponent,\n onOpenChange,\n });\n\n const { getFloatingProps } = useInteractions([\n useClick(context),\n useDismiss(context, { enabled: !disableDismiss }),\n ]);\n\n const handleRef = useForkRef<HTMLDivElement>(floating, ref);\n\n useEffect(() => {\n if (open && !showComponent) {\n setShowComponent(true);\n }\n\n if (!open && showComponent) {\n const animate = setTimeout(() => {\n setShowComponent(false);\n }, 300); // var(--salt-duration-perceptible)\n return () => clearTimeout(animate);\n }\n }, [open, showComponent]);\n\n return (\n <ConditionalScrimWrapper condition={showComponent && !disableScrim}>\n <FloatingComponent\n open={showComponent}\n ref={handleRef}\n role={\"dialog\"}\n width={elements.floating?.offsetWidth}\n height={elements.floating?.offsetHeight}\n aria-modal=\"true\"\n focusManagerProps={{\n context: context,\n initialFocus,\n }}\n className={clsx(\n withBaseName(),\n withBaseName(position),\n {\n [withBaseName(\"enterAnimation\")]: open,\n [withBaseName(\"exitAnimation\")]: !open,\n [withBaseName(variant)]: variant,\n },\n className,\n )}\n {...getFloatingProps()}\n {...rest}\n >\n {children}\n </FloatingComponent>\n </ConditionalScrimWrapper>\n );\n },\n);\n"],"names":["jsxs","Scrim","Fragment","makePrefixer","forwardRef","Drawer","useWindow","useComponentCssInjection","drawerCss","useState","useFloatingComponent","useFloatingUI","useInteractions","useClick","useDismiss","useForkRef","useEffect","jsx","clsx"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"Drawer.js","sources":["../src/drawer/Drawer.tsx"],"sourcesContent":["import {\n type FloatingFocusManager,\n useClick,\n useDismiss,\n useInteractions,\n} from \"@floating-ui/react\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type PropsWithChildren,\n useEffect,\n useState,\n} from \"react\";\nimport { Scrim } from \"../scrim\";\nimport {\n makePrefixer,\n useFloatingComponent,\n useFloatingUI,\n useForkRef,\n} from \"../utils\";\nimport drawerCss from \"./Drawer.css\";\n\ninterface ConditionalScrimWrapperProps extends PropsWithChildren {\n condition: boolean;\n}\n\nconst ConditionalScrimWrapper = ({\n condition,\n children,\n}: ConditionalScrimWrapperProps) => {\n return condition ? <Scrim fixed> {children} </Scrim> : <>{children} </>;\n};\n\nexport interface DrawerProps extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * Defines the drawer position within the screen. Defaults to `left`.\n */\n position?: \"left\" | \"top\" | \"right\" | \"bottom\";\n /**\n * Display or hide the component.\n */\n open?: boolean;\n /**\n * Callback function triggered when open state changes.\n */\n onOpenChange?: (newOpen: boolean) => void;\n /**\n * Change background color palette\n */\n variant?: \"primary\" | \"secondary\" | \"tertiary\";\n /**\n * Prevent the dialog closing on click away\n * */\n disableDismiss?: boolean;\n /**\n * Prevent Scrim from rendering\n * */\n disableScrim?: boolean;\n /**\n * Which element to initially focus. Can be either a number (tabbable index as specified by the order) or a ref.\n * Default value is 0 (first tabbable element).\n * */\n initialFocus?: ComponentPropsWithoutRef<\n typeof FloatingFocusManager\n >[\"initialFocus\"];\n}\n\nconst withBaseName = makePrefixer(\"saltDrawer\");\n\nexport const Drawer = forwardRef<HTMLDivElement, DrawerProps>(\n function Drawer(props, ref) {\n const {\n children,\n className,\n position = \"left\",\n open = false,\n onOpenChange,\n variant = \"primary\",\n disableDismiss,\n disableScrim,\n initialFocus,\n ...rest\n } = props;\n\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-drawer\",\n css: drawerCss,\n window: targetWindow,\n });\n\n const [showComponent, setShowComponent] = useState(false);\n const { Component: FloatingComponent } = useFloatingComponent();\n\n const { context, floating, elements } = useFloatingUI({\n open: showComponent,\n onOpenChange,\n });\n\n const { getFloatingProps } = useInteractions([\n useClick(context),\n useDismiss(context, { enabled: !disableDismiss }),\n ]);\n\n const handleRef = useForkRef<HTMLDivElement>(floating, ref);\n\n useEffect(() => {\n if (open && !showComponent) {\n setShowComponent(true);\n }\n\n if (!open && showComponent) {\n const animate = setTimeout(() => {\n setShowComponent(false);\n }, 300); // var(--salt-duration-perceptible)\n return () => clearTimeout(animate);\n }\n }, [open, showComponent]);\n\n return (\n <ConditionalScrimWrapper condition={showComponent && !disableScrim}>\n <FloatingComponent\n open={showComponent}\n ref={handleRef}\n role={\"dialog\"}\n width={elements.floating?.offsetWidth}\n height={elements.floating?.offsetHeight}\n aria-modal=\"true\"\n focusManagerProps={{\n context: context,\n initialFocus,\n outsideElementsInert: true,\n }}\n className={clsx(\n withBaseName(),\n withBaseName(position),\n {\n [withBaseName(\"enterAnimation\")]: open,\n [withBaseName(\"exitAnimation\")]: !open,\n [withBaseName(variant)]: variant,\n },\n className,\n )}\n {...getFloatingProps()}\n {...rest}\n >\n {children}\n </FloatingComponent>\n </ConditionalScrimWrapper>\n );\n },\n);\n"],"names":["jsxs","Scrim","Fragment","makePrefixer","forwardRef","Drawer","useWindow","useComponentCssInjection","drawerCss","useState","useFloatingComponent","useFloatingUI","useInteractions","useClick","useDismiss","useForkRef","useEffect","jsx","clsx"],"mappings":"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"}
|
|
@@ -36,8 +36,19 @@ const FileDropZone = React.forwardRef(
|
|
|
36
36
|
const regionRef = React.useRef(null);
|
|
37
37
|
const handleRef = useForkRef.useForkRef(ref, regionRef);
|
|
38
38
|
const handleDragOver = (event) => {
|
|
39
|
+
onDragOver == null ? void 0 : onDragOver(event);
|
|
40
|
+
const hasFiles = utils.containsFiles(event);
|
|
39
41
|
event.preventDefault();
|
|
40
42
|
event.stopPropagation();
|
|
43
|
+
if (!hasFiles) {
|
|
44
|
+
if (event.dataTransfer) {
|
|
45
|
+
event.dataTransfer.dropEffect = "none";
|
|
46
|
+
}
|
|
47
|
+
if (isActive) {
|
|
48
|
+
setActive(false);
|
|
49
|
+
}
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
41
52
|
if (disabled) {
|
|
42
53
|
if (event.dataTransfer) {
|
|
43
54
|
event.dataTransfer.dropEffect = "none";
|
|
@@ -47,10 +58,9 @@ const FileDropZone = React.forwardRef(
|
|
|
47
58
|
if (event.dataTransfer) {
|
|
48
59
|
event.dataTransfer.dropEffect = "copy";
|
|
49
60
|
}
|
|
50
|
-
if (!isActive
|
|
61
|
+
if (!isActive) {
|
|
51
62
|
setActive(true);
|
|
52
63
|
}
|
|
53
|
-
onDragOver == null ? void 0 : onDragOver(event);
|
|
54
64
|
};
|
|
55
65
|
const handleDragLeave = (event) => {
|
|
56
66
|
if (disabled) {
|
|
@@ -58,16 +68,21 @@ const FileDropZone = React.forwardRef(
|
|
|
58
68
|
}
|
|
59
69
|
const region = regionRef == null ? void 0 : regionRef.current;
|
|
60
70
|
const eventTarget = event.relatedTarget;
|
|
61
|
-
if (eventTarget !== region && !(region == null ? void 0 : region.contains(eventTarget))) {
|
|
71
|
+
if (eventTarget !== region && (!(eventTarget instanceof Node) || !(region == null ? void 0 : region.contains(eventTarget)))) {
|
|
62
72
|
setActive(false);
|
|
63
73
|
}
|
|
64
74
|
onDragLeave == null ? void 0 : onDragLeave(event);
|
|
65
75
|
};
|
|
66
76
|
const handleDrop = (event) => {
|
|
77
|
+
event.preventDefault();
|
|
78
|
+
if (!utils.containsFiles(event)) {
|
|
79
|
+
setActive(false);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
67
82
|
if (disabled) {
|
|
83
|
+
setActive(false);
|
|
68
84
|
return;
|
|
69
85
|
}
|
|
70
|
-
event.preventDefault();
|
|
71
86
|
const files = utils.extractFiles(event);
|
|
72
87
|
setActive(false);
|
|
73
88
|
onDrop == null ? void 0 : onDrop(event, files);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileDropZone.js","sources":["../src/file-drop-zone/FileDropZone.tsx"],"sourcesContent":["import { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n type DragEvent,\n type DragEventHandler,\n forwardRef,\n useRef,\n useState,\n} from \"react\";\nimport type { ValidationStatus } from \"../status-indicator\";\nimport { makePrefixer, useForkRef } from \"../utils\";\nimport fileDropZoneCss from \"./FileDropZone.css\";\nimport { containsFiles, extractFiles } from \"./internal/utils\";\n\nexport interface FileDropZoneProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"onDrop\"> {\n /**\n * If `true`, the file drop zone will be disabled.\n */\n disabled?: boolean;\n /**\n * Status indicator to be displayed.\n */\n status?: Exclude<ValidationStatus, \"info\" | \"warning\">;\n /**\n * Callback for on drop event\n */\n onDrop?: (event: DragEvent<HTMLDivElement>, files: File[]) => void;\n}\n\nconst withBaseName = makePrefixer(\"saltFileDropZone\");\n\nexport const FileDropZone = forwardRef<HTMLDivElement, FileDropZoneProps>(\n function FileDropZone(\n {\n status,\n className,\n children,\n disabled,\n onDragOver,\n onDragLeave,\n onDrop,\n ...restProps\n },\n ref,\n ) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-file-drop-zone\",\n css: fileDropZoneCss,\n window: targetWindow,\n });\n const [isActive, setActive] = useState(false);\n\n const regionRef = useRef<HTMLDivElement>(null);\n const handleRef = useForkRef(ref, regionRef);\n\n const handleDragOver: DragEventHandler<HTMLDivElement> = (event) => {\n // Need to cancel the default events to allow drop\n // https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#droptargets\n
|
|
1
|
+
{"version":3,"file":"FileDropZone.js","sources":["../src/file-drop-zone/FileDropZone.tsx"],"sourcesContent":["import { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentPropsWithoutRef,\n type DragEvent,\n type DragEventHandler,\n forwardRef,\n useRef,\n useState,\n} from \"react\";\nimport type { ValidationStatus } from \"../status-indicator\";\nimport { makePrefixer, useForkRef } from \"../utils\";\nimport fileDropZoneCss from \"./FileDropZone.css\";\nimport { containsFiles, extractFiles } from \"./internal/utils\";\n\nexport interface FileDropZoneProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"onDrop\"> {\n /**\n * If `true`, the file drop zone will be disabled.\n */\n disabled?: boolean;\n /**\n * Status indicator to be displayed.\n */\n status?: Exclude<ValidationStatus, \"info\" | \"warning\">;\n /**\n * Callback for on drop event\n */\n onDrop?: (event: DragEvent<HTMLDivElement>, files: File[]) => void;\n}\n\nconst withBaseName = makePrefixer(\"saltFileDropZone\");\n\nexport const FileDropZone = forwardRef<HTMLDivElement, FileDropZoneProps>(\n function FileDropZone(\n {\n status,\n className,\n children,\n disabled,\n onDragOver,\n onDragLeave,\n onDrop,\n ...restProps\n },\n ref,\n ) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-file-drop-zone\",\n css: fileDropZoneCss,\n window: targetWindow,\n });\n const [isActive, setActive] = useState(false);\n\n const regionRef = useRef<HTMLDivElement>(null);\n const handleRef = useForkRef(ref, regionRef);\n\n const handleDragOver: DragEventHandler<HTMLDivElement> = (event) => {\n onDragOver?.(event);\n\n const hasFiles = containsFiles(event);\n // Need to cancel the default events to allow drop\n // https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#droptargets\n event.preventDefault();\n event.stopPropagation();\n\n if (!hasFiles) {\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = \"none\";\n }\n if (isActive) {\n setActive(false);\n }\n return;\n }\n\n if (disabled) {\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = \"none\";\n }\n return;\n }\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = \"copy\";\n }\n if (!isActive) {\n setActive(true);\n }\n };\n\n const handleDragLeave: DragEventHandler<HTMLDivElement> = (event) => {\n if (disabled) {\n return;\n }\n const region = regionRef?.current;\n const eventTarget = event.relatedTarget;\n if (\n eventTarget !== region &&\n (!(eventTarget instanceof Node) || !region?.contains(eventTarget))\n ) {\n setActive(false);\n }\n onDragLeave?.(event);\n };\n\n const handleDrop: DragEventHandler<HTMLDivElement> = (event) => {\n event.preventDefault();\n\n if (!containsFiles(event)) {\n setActive(false);\n return;\n }\n\n if (disabled) {\n setActive(false);\n return;\n }\n\n const files = extractFiles(event);\n setActive(false);\n onDrop?.(event, files);\n };\n\n return (\n <div\n className={clsx(\n withBaseName(),\n {\n [withBaseName(status as string)]: status,\n [withBaseName(\"active\")]: isActive,\n [withBaseName(\"disabled\")]: disabled,\n },\n className,\n )}\n aria-disabled={disabled}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n ref={handleRef}\n {...restProps}\n >\n {children}\n </div>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","FileDropZone","useWindow","useComponentCssInjection","fileDropZoneCss","useState","useRef","useForkRef","containsFiles","extractFiles","jsx","clsx"],"mappings":"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"}
|