@elliemae/ds-banner 3.80.0-next.4 → 3.80.0-next.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/cjs/DSBanner.js +31 -58
  2. package/dist/cjs/DSBanner.js.map +3 -3
  3. package/dist/cjs/DSBannerContent.js +25 -23
  4. package/dist/cjs/DSBannerContent.js.map +2 -2
  5. package/dist/cjs/LiveRegionCorrectlyImplemented.js +67 -0
  6. package/dist/cjs/LiveRegionCorrectlyImplemented.js.map +7 -0
  7. package/dist/cjs/{exported-related → constants}/index.js +8 -3
  8. package/dist/cjs/constants/index.js.map +7 -0
  9. package/dist/cjs/index.js +5 -5
  10. package/dist/cjs/index.js.map +2 -2
  11. package/dist/cjs/react-desc-prop-types.js +11 -6
  12. package/dist/cjs/react-desc-prop-types.js.map +2 -2
  13. package/dist/cjs/styles.js +79 -45
  14. package/dist/cjs/styles.js.map +2 -2
  15. package/dist/cjs/typescript-testing/slot-props.js +52 -0
  16. package/dist/cjs/typescript-testing/slot-props.js.map +7 -0
  17. package/dist/cjs/typescript-testing/typescript-banner-valid.js +2 -1
  18. package/dist/cjs/typescript-testing/typescript-banner-valid.js.map +2 -2
  19. package/dist/cjs/useBannerContainer.js +55 -0
  20. package/dist/cjs/useBannerContainer.js.map +7 -0
  21. package/dist/cjs/useBannerExitAnimation.js +66 -0
  22. package/dist/cjs/useBannerExitAnimation.js.map +7 -0
  23. package/dist/cjs/usePageNotice.js +53 -0
  24. package/dist/cjs/usePageNotice.js.map +7 -0
  25. package/dist/esm/DSBanner.js +26 -59
  26. package/dist/esm/DSBanner.js.map +2 -2
  27. package/dist/esm/DSBannerContent.js +25 -23
  28. package/dist/esm/DSBannerContent.js.map +2 -2
  29. package/dist/esm/LiveRegionCorrectlyImplemented.js +37 -0
  30. package/dist/esm/LiveRegionCorrectlyImplemented.js.map +7 -0
  31. package/dist/esm/{exported-related → constants}/index.js +5 -0
  32. package/dist/esm/constants/index.js.map +7 -0
  33. package/dist/esm/index.js +1 -1
  34. package/dist/esm/index.js.map +1 -1
  35. package/dist/esm/react-desc-prop-types.js +8 -3
  36. package/dist/esm/react-desc-prop-types.js.map +2 -2
  37. package/dist/esm/styles.js +59 -25
  38. package/dist/esm/styles.js.map +2 -2
  39. package/dist/esm/typescript-testing/slot-props.js +29 -0
  40. package/dist/esm/typescript-testing/slot-props.js.map +7 -0
  41. package/dist/esm/typescript-testing/typescript-banner-valid.js +2 -1
  42. package/dist/esm/typescript-testing/typescript-banner-valid.js.map +2 -2
  43. package/dist/esm/useBannerContainer.js +25 -0
  44. package/dist/esm/useBannerContainer.js.map +7 -0
  45. package/dist/esm/useBannerExitAnimation.js +36 -0
  46. package/dist/esm/useBannerExitAnimation.js.map +7 -0
  47. package/dist/esm/usePageNotice.js +23 -0
  48. package/dist/esm/usePageNotice.js.map +7 -0
  49. package/dist/types/DSBannerContent.d.ts +2 -0
  50. package/dist/types/LiveRegionCorrectlyImplemented.d.ts +11 -0
  51. package/dist/types/{exported-related → constants}/index.d.ts +9 -0
  52. package/dist/types/index.d.ts +1 -1
  53. package/dist/types/react-desc-prop-types.d.ts +15 -1
  54. package/dist/types/styles.d.ts +3 -1
  55. package/dist/types/useBannerContainer.d.ts +10 -0
  56. package/dist/types/useBannerExitAnimation.d.ts +15 -0
  57. package/dist/types/usePageNotice.d.ts +11 -0
  58. package/package.json +12 -10
  59. package/dist/cjs/exported-related/index.js.map +0 -7
  60. package/dist/esm/exported-related/index.js.map +0 -7
@@ -31,6 +31,7 @@ __export(styles_exports, {
31
31
  StyledActionLink: () => StyledActionLink,
32
32
  StyledBannerContainer: () => StyledBannerContainer,
33
33
  StyledBannerLayout: () => StyledBannerLayout,
34
+ StyledBody: () => StyledBody,
34
35
  StyledCloseButton: () => StyledCloseButton,
35
36
  StyledIconContainer: () => StyledIconContainer,
36
37
  StyledInnerContainer: () => StyledInnerContainer,
@@ -44,45 +45,59 @@ var import_ds_button_v2 = require("@elliemae/ds-button-v2");
44
45
  var import_ds_grid = require("@elliemae/ds-grid");
45
46
  var import_ds_system = require("@elliemae/ds-system");
46
47
  var import_ds_typography = require("@elliemae/ds-typography");
47
- var import_exported_related = require("./exported-related/index.js");
48
+ var import_constants = require("./constants/index.js");
48
49
  const StyledBannerContainer = (0, import_ds_system.styled)("div", {
49
- name: import_exported_related.DSBannerName,
50
- slot: import_exported_related.DSBannerSlots.CONTAINER
50
+ name: import_constants.DSBannerName,
51
+ slot: import_constants.DSBannerSlots.CONTAINER
51
52
  })`
52
- min-height: 41px;
53
+ display: grid;
54
+ grid-template-columns: minmax(0, 1fr);
55
+ height: fit-content;
56
+ grid-template-rows: ${({ $isExpanded = true }) => $isExpanded ? "minmax(0, 1fr)" : "minmax(0, 0fr)"};
57
+ min-height: ${({ $isExpanded = true }) => $isExpanded ? "59px" : "0px"};
53
58
  overflow: hidden;
54
- transition: all 0.5s ease-in;
59
+ transition:
60
+ grid-template-rows ${import_constants.BANNER_SLIDE_DURATION_MS}ms ease-in,
61
+ min-height ${import_constants.BANNER_SLIDE_DURATION_MS}ms ease-in;
55
62
  @starting-style {
56
- max-height: 0px;
63
+ grid-template-rows: minmax(0, 0fr);
64
+ min-height: 0px;
65
+ }
66
+ & > * {
67
+ align-self: start;
68
+ min-height: 0;
69
+ overflow: hidden;
70
+ }
71
+ @media (prefers-reduced-motion: reduce) {
72
+ transition: none;
57
73
  }
58
74
  ${import_ds_system.xStyledCommonProps}
59
75
  `;
60
76
  const StyledInnerContainer = (0, import_ds_system.styled)(import_ds_grid.Grid, {
61
- name: import_exported_related.DSBannerName,
62
- slot: import_exported_related.DSBannerSlots.INNER_CONTAINER
77
+ name: import_constants.DSBannerName,
78
+ slot: import_constants.DSBannerSlots.INNER_CONTAINER
63
79
  })`
64
80
  padding-right: 4px;
65
- padding-bottom: 6px;
66
81
  width: 100%;
67
82
  min-width: 0;
68
83
  `;
69
84
  const handleBorderColor = (type, { colors }) => {
70
85
  switch (type) {
71
- case import_exported_related.BANNER_TYPES.SUCCESS:
86
+ case import_constants.BANNER_TYPES.SUCCESS:
72
87
  return colors.success[900];
73
- case import_exported_related.BANNER_TYPES.INFO:
88
+ case import_constants.BANNER_TYPES.INFO:
74
89
  return colors.brand[600];
75
- case import_exported_related.BANNER_TYPES.WARNING:
90
+ case import_constants.BANNER_TYPES.WARNING:
76
91
  return colors.warning[900];
77
- case import_exported_related.BANNER_TYPES.DANGER:
92
+ case import_constants.BANNER_TYPES.DANGER:
78
93
  return colors.danger[900];
79
94
  default:
80
95
  return "should_not_happen";
81
96
  }
82
97
  };
83
98
  const StyledBannerLayout = (0, import_ds_system.styled)("div", {
84
- name: import_exported_related.DSBannerName,
85
- slot: import_exported_related.DSBannerSlots.LAYOUT
99
+ name: import_constants.DSBannerName,
100
+ slot: import_constants.DSBannerSlots.LAYOUT
86
101
  })`
87
102
  display: flex;
88
103
  width: 100%;
@@ -96,50 +111,68 @@ const StyledBannerLayout = (0, import_ds_system.styled)("div", {
96
111
  }
97
112
  `;
98
113
  const StyledIconContainer = (0, import_ds_system.styled)("div", {
99
- name: import_exported_related.DSBannerName,
100
- slot: import_exported_related.DSBannerSlots.ICON_CONTAINER
114
+ name: import_constants.DSBannerName,
115
+ slot: import_constants.DSBannerSlots.ICON_CONTAINER
101
116
  })`
102
117
  padding-top: 8px;
103
118
  margin-right: ${({ theme }) => theme.space.xxs};
104
119
  margin-left: ${({ theme }) => theme.space.xs};
105
120
  min-width: 0px;
106
121
  `;
107
- const StyledTitle = (0, import_ds_system.styled)(import_ds_typography.DSTypography, { name: import_exported_related.DSBannerName, slot: import_exported_related.DSBannerSlots.TITLE })`
108
- color: neutral-700;
109
- font-weight: ${({ theme }) => theme.fontWeights.semibold};
122
+ const isSmallLayout = ({ theme }) => ["s", "xs"].includes(theme.layoutMode);
123
+ const StyledBody = (0, import_ds_system.styled)("div", { name: import_constants.DSBannerName, slot: import_constants.DSBannerSlots.BODY })`
124
+ display: grid;
125
+ grid-template-columns: ${(props) => isSmallLayout(props) ? "minmax(0, 1fr)" : "minmax(0, max-content) auto"};
126
+ justify-content: start;
110
127
  padding-top: 9px;
128
+ & > :nth-child(-n + 2) {
129
+ grid-column: 1;
130
+ }
131
+ `;
132
+ const StyledTitle = (0, import_ds_system.styled)(import_ds_typography.DSTypography, { name: import_constants.DSBannerName, slot: import_constants.DSBannerSlots.TITLE })`
133
+ display: block;
134
+ color: neutral-700;
111
135
  overflow-wrap: break-word;
112
136
  white-space: pre-wrap;
113
137
  min-width: 0px;
114
138
  `;
115
- const StyledSubTitle = (0, import_ds_system.styled)(import_ds_typography.DSTypography, { name: import_exported_related.DSBannerName, slot: import_exported_related.DSBannerSlots.SUBTITLE })`
116
- margin-left: ${({ theme }) => theme.space.xs};
139
+ const StyledSubTitle = (0, import_ds_system.styled)(import_ds_typography.DSTypography, { name: import_constants.DSBannerName, slot: import_constants.DSBannerSlots.SUBTITLE })`
117
140
  font-weight: ${({ theme }) => theme.fontWeights.regular};
118
- padding-top: 9px;
119
141
  overflow-wrap: break-word;
120
142
  white-space: pre-wrap;
121
143
  min-width: 0px;
122
- ${({ theme }) => {
123
- if (["s", "xs"].includes(theme.layoutMode)) {
124
- return `
125
- grid-column: 1 / -1;
126
- `;
127
- }
128
- return "";
129
- }}
144
+ padding-bottom: 9px;
130
145
  `;
131
- const StyledActionLink = (0, import_ds_system.styled)("a", {
132
- name: import_exported_related.DSBannerName,
133
- slot: import_exported_related.DSBannerSlots.ACTION_LINK
146
+ const StyledActionLink = (0, import_ds_system.styled)(import_ds_typography.DSTypography, {
147
+ name: import_constants.DSBannerName,
148
+ slot: import_constants.DSBannerSlots.ACTION_LINK
134
149
  })`
135
- display: inline-block;
136
- text-decoration: none;
137
- line-height: inherit;
138
- + font-size: inherit;
139
- font-weight: ${({ theme }) => theme.fontWeights.regular};
140
- color: brand-600;
141
150
  min-width: 0px;
142
151
  position: relative;
152
+ margin-bottom: 9px;
153
+ ${(props) => isSmallLayout(props) ? `
154
+ justify-self: start;
155
+ ` : `
156
+ grid-column: 2;
157
+ grid-row: ${props.isBodyEmpty ? 1 : 2};
158
+ align-self: end;
159
+ align-self: last baseline;
160
+ margin-left: 16px;
161
+ `}
162
+ /* Typography and underline of the action link (PUI-19233).
163
+ Size comes from the link-sml-title variant (set in DSBannerContent). The rest is the Link "inline text" styling:
164
+ idle underline + brand-600, hover no underline + brand-800 (decided: the link is underlined at rest).
165
+ PENDING UX CONFIRMATION: only font-weight (400 vs the variant's weight; the spec names a variant that does not
166
+ exist) and line-height (the description's, the variant's 24px would make the banner taller and misalign the
167
+ baselines). Adjusting them once UX answers should only touch those two declarations. */
168
+ font-weight: ${({ theme }) => theme.fontWeights.regular};
169
+ line-height: 1.278;
170
+ text-decoration: underline;
171
+ color: brand-600;
172
+ &:hover {
173
+ text-decoration: none;
174
+ color: brand-800;
175
+ }
143
176
  &:focus {
144
177
  outline: none;
145
178
  &:after {
@@ -157,14 +190,15 @@ const StyledActionLink = (0, import_ds_system.styled)("a", {
157
190
  }
158
191
  `;
159
192
  const StyledCloseButton = (0, import_ds_system.styled)(import_ds_button_v2.DSButtonV2, {
160
- name: import_exported_related.DSBannerName,
161
- slot: import_exported_related.DSBannerSlots.CLOSE_BUTTON
193
+ name: import_constants.DSBannerName,
194
+ slot: import_constants.DSBannerSlots.CLOSE_BUTTON
162
195
  })`
163
- margin: 5px;
196
+ margin-top: 4px;
197
+ margin-left: 8px;
164
198
  `;
165
199
  const StyledLiveRegionPortal = (0, import_ds_system.styled)("div", {
166
- name: import_exported_related.DSBannerName,
167
- slot: import_exported_related.DSBannerSlots.LIVE_REGION_PORTAL
200
+ name: import_constants.DSBannerName,
201
+ slot: import_constants.DSBannerSlots.LIVE_REGION_PORTAL
168
202
  })`
169
203
  clip: rect(0 0 0 0);
170
204
  position: absolute;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/styles.tsx", "../../../../../scripts/build/transpile/react-shim.js"],
4
- "sourcesContent": ["import { DSButtonV2 } from '@elliemae/ds-button-v2';\nimport { Grid } from '@elliemae/ds-grid';\nimport type { ColorProps, LayoutProps, SizingProps, SpaceProps } from '@elliemae/ds-system';\nimport { styled, xStyledCommonProps } from '@elliemae/ds-system';\nimport { DSTypography } from '@elliemae/ds-typography';\nimport { BANNER_TYPES, DSBannerName, DSBannerSlots } from './exported-related/index.js';\nimport type { DSBannerT } from './react-desc-prop-types.js';\n\ninterface StyledBannerContainerT extends SizingProps, LayoutProps, SpaceProps, ColorProps {}\nexport const StyledBannerContainer = styled('div', {\n name: DSBannerName,\n slot: DSBannerSlots.CONTAINER,\n})<StyledBannerContainerT>`\n min-height: 41px;\n overflow: hidden;\n transition: all 0.5s ease-in;\n @starting-style {\n max-height: 0px;\n }\n ${xStyledCommonProps}\n`;\n\ninterface StyledInnerContainerT {}\nexport const StyledInnerContainer = styled(Grid, {\n name: DSBannerName,\n slot: DSBannerSlots.INNER_CONTAINER,\n})<StyledInnerContainerT>`\n padding-right: 4px;\n padding-bottom: 6px;\n width: 100%;\n min-width: 0;\n`;\n\nconst handleBorderColor = (\n type: DSBannerT.BannerTypesT,\n { colors }: { colors: Record<string, Record<string, string>> },\n): string => {\n switch (type) {\n case BANNER_TYPES.SUCCESS:\n return colors.success[900];\n case BANNER_TYPES.INFO:\n return colors.brand[600];\n case BANNER_TYPES.WARNING:\n return colors.warning[900];\n case BANNER_TYPES.DANGER:\n return colors.danger[900];\n default:\n return 'should_not_happen';\n }\n};\ninterface StyledBannerLayoutT {\n $type: DSBannerT.BannerTypesT;\n}\nexport const StyledBannerLayout = styled('div', {\n name: DSBannerName,\n slot: DSBannerSlots.LAYOUT,\n})<StyledBannerLayoutT>`\n display: flex;\n width: 100%;\n align-items: flex-start;\n justify-content: space-between;\n background-color: neutral-000;\n border-bottom: 5px solid ${({ $type, theme }) => handleBorderColor($type, theme)};\n & > :first-child {\n flex: 1;\n min-width: 0;\n }\n`;\n\nexport const StyledIconContainer = styled('div', {\n name: DSBannerName,\n slot: DSBannerSlots.ICON_CONTAINER,\n})`\n padding-top: 8px;\n margin-right: ${({ theme }) => theme.space.xxs};\n margin-left: ${({ theme }) => theme.space.xs};\n min-width: 0px;\n`;\n\nexport const StyledTitle = styled(DSTypography, { name: DSBannerName, slot: DSBannerSlots.TITLE })`\n color: neutral-700;\n font-weight: ${({ theme }) => theme.fontWeights.semibold};\n padding-top: 9px;\n overflow-wrap: break-word;\n white-space: pre-wrap;\n min-width: 0px;\n`;\n\nexport const StyledSubTitle = styled(DSTypography, { name: DSBannerName, slot: DSBannerSlots.SUBTITLE })`\n margin-left: ${({ theme }) => theme.space.xs};\n font-weight: ${({ theme }) => theme.fontWeights.regular};\n padding-top: 9px;\n overflow-wrap: break-word;\n white-space: pre-wrap;\n min-width: 0px;\n ${({ theme }) => {\n if (['s', 'xs'].includes(theme.layoutMode!)) {\n return `\n grid-column: 1 / -1;\n `;\n }\n return '';\n }}\n`;\n\ninterface StyledActionLinkT {\n isBodyEmpty: boolean;\n}\nexport const StyledActionLink = styled('a', {\n name: DSBannerName,\n slot: DSBannerSlots.ACTION_LINK,\n})<StyledActionLinkT>`\n display: inline-block;\n text-decoration: none;\n line-height: inherit;\n+ font-size: inherit;\n font-weight: ${({ theme }) => theme.fontWeights.regular};\n color: brand-600;\n min-width: 0px;\n position: relative;\n &:focus {\n outline: none;\n &:after {\n position: absolute;\n content: '';\n top: -2px;\n left: -2px;\n right: -2px;\n bottom: -2px;\n border-radius: 2px;\n border: 2px solid brand-700;\n box-shadow: 0 0 0 1px brand-700;\n pointer-events: none;\n }\n }\n`;\nexport const StyledCloseButton = styled(DSButtonV2, {\n name: DSBannerName,\n slot: DSBannerSlots.CLOSE_BUTTON,\n})`\n margin: 5px;\n`;\n\nexport const StyledLiveRegionPortal = styled('div', {\n name: DSBannerName,\n slot: DSBannerSlots.LIVE_REGION_PORTAL,\n})`\n clip: rect(0 0 0 0);\n position: absolute;\n`;\n", "import * as React from 'react';\nexport { React };\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,0BAA2B;AAC3B,qBAAqB;AAErB,uBAA2C;AAC3C,2BAA6B;AAC7B,8BAA0D;AAInD,MAAM,4BAAwB,yBAAO,OAAO;AAAA,EACjD,MAAM;AAAA,EACN,MAAM,sCAAc;AACtB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOG,mCAAkB;AAAA;AAIf,MAAM,2BAAuB,yBAAO,qBAAM;AAAA,EAC/C,MAAM;AAAA,EACN,MAAM,sCAAc;AACtB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAOD,MAAM,oBAAoB,CACxB,MACA,EAAE,OAAO,MACE;AACX,UAAQ,MAAM;AAAA,IACZ,KAAK,qCAAa;AAChB,aAAO,OAAO,QAAQ,GAAG;AAAA,IAC3B,KAAK,qCAAa;AAChB,aAAO,OAAO,MAAM,GAAG;AAAA,IACzB,KAAK,qCAAa;AAChB,aAAO,OAAO,QAAQ,GAAG;AAAA,IAC3B,KAAK,qCAAa;AAChB,aAAO,OAAO,OAAO,GAAG;AAAA,IAC1B;AACE,aAAO;AAAA,EACX;AACF;AAIO,MAAM,yBAAqB,yBAAO,OAAO;AAAA,EAC9C,MAAM;AAAA,EACN,MAAM,sCAAc;AACtB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,6BAM4B,CAAC,EAAE,OAAO,MAAM,MAAM,kBAAkB,OAAO,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAO3E,MAAM,0BAAsB,yBAAO,OAAO;AAAA,EAC/C,MAAM;AAAA,EACN,MAAM,sCAAc;AACtB,CAAC;AAAA;AAAA,kBAEiB,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,GAAG;AAAA,iBAC/B,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,EAAE;AAAA;AAAA;AAIvC,MAAM,kBAAc,yBAAO,mCAAc,EAAE,MAAM,sCAAc,MAAM,sCAAc,MAAM,CAAC;AAAA;AAAA,iBAEhF,CAAC,EAAE,MAAM,MAAM,MAAM,YAAY,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAOnD,MAAM,qBAAiB,yBAAO,mCAAc,EAAE,MAAM,sCAAc,MAAM,sCAAc,SAAS,CAAC;AAAA,iBACtF,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,EAAE;AAAA,iBAC7B,CAAC,EAAE,MAAM,MAAM,MAAM,YAAY,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,IAKrD,CAAC,EAAE,MAAM,MAAM;AACf,MAAI,CAAC,KAAK,IAAI,EAAE,SAAS,MAAM,UAAW,GAAG;AAC3C,WAAO;AAAA;AAAA;AAAA,EAGT;AACA,SAAO;AACT,CAAC;AAAA;AAMI,MAAM,uBAAmB,yBAAO,KAAK;AAAA,EAC1C,MAAM;AAAA,EACN,MAAM,sCAAc;AACtB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,iBAKgB,CAAC,EAAE,MAAM,MAAM,MAAM,YAAY,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBlD,MAAM,wBAAoB,yBAAO,gCAAY;AAAA,EAClD,MAAM;AAAA,EACN,MAAM,sCAAc;AACtB,CAAC;AAAA;AAAA;AAIM,MAAM,6BAAyB,yBAAO,OAAO;AAAA,EAClD,MAAM;AAAA,EACN,MAAM,sCAAc;AACtB,CAAC;AAAA;AAAA;AAAA;",
4
+ "sourcesContent": ["import { DSButtonV2 } from '@elliemae/ds-button-v2';\nimport { Grid } from '@elliemae/ds-grid';\nimport type { ColorProps, LayoutProps, SizingProps, SpaceProps } from '@elliemae/ds-system';\nimport { styled, xStyledCommonProps } from '@elliemae/ds-system';\nimport { DSTypography } from '@elliemae/ds-typography';\nimport { BANNER_SLIDE_DURATION_MS, BANNER_TYPES, DSBannerName, DSBannerSlots } from './constants/index.js';\nimport type { DSBannerT } from './react-desc-prop-types.js';\n\ninterface StyledBannerContainerT extends SizingProps, LayoutProps, SpaceProps, ColorProps {\n $isExpanded?: boolean;\n}\n// The slide animates the height of an intrinsically sized (auto height) element, which css can not interpolate with\n// \"height\" or \"max-height\" (auto/none are not interpolable, and min-height would clamp the collapsed state anyway).\n// Instead the single child (the layout, the live region lives in a portal) is the item of a one track grid whose row goes\n// from 0fr to 1fr: the row is always sized from the content so it follows wrapping, small layouts and text resize.\n// The tracks are minmax(0, Xfr) and not plain Xfr because the item has a border (the type color line): a plain 0fr track\n// can not be smaller than the item's border box, so it would collapse to 5px instead of 0.\n// The open slide is css only (@starting-style, the container mounts expanded), the close slide needs the container to\n// still be mounted when $isExpanded turns false, which is handled by useBannerExitAnimation.\nexport const StyledBannerContainer = styled('div', {\n name: DSBannerName,\n slot: DSBannerSlots.CONTAINER,\n})<StyledBannerContainerT>`\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n height: fit-content;\n grid-template-rows: ${({ $isExpanded = true }) => ($isExpanded ? 'minmax(0, 1fr)' : 'minmax(0, 0fr)')};\n min-height: ${({ $isExpanded = true }) => ($isExpanded ? '59px' : '0px')};\n overflow: hidden;\n transition:\n grid-template-rows ${BANNER_SLIDE_DURATION_MS}ms ease-in,\n min-height ${BANNER_SLIDE_DURATION_MS}ms ease-in;\n @starting-style {\n grid-template-rows: minmax(0, 0fr);\n min-height: 0px;\n }\n & > * {\n align-self: start;\n min-height: 0;\n overflow: hidden;\n }\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n ${xStyledCommonProps}\n`;\n\ninterface StyledInnerContainerT {}\nexport const StyledInnerContainer = styled(Grid, {\n name: DSBannerName,\n slot: DSBannerSlots.INNER_CONTAINER,\n})<StyledInnerContainerT>`\n padding-right: 4px;\n width: 100%;\n min-width: 0;\n`;\n\nconst handleBorderColor = (\n type: DSBannerT.BannerTypesT,\n { colors }: { colors: Record<string, Record<string, string>> },\n): string => {\n switch (type) {\n case BANNER_TYPES.SUCCESS:\n return colors.success[900];\n case BANNER_TYPES.INFO:\n return colors.brand[600];\n case BANNER_TYPES.WARNING:\n return colors.warning[900];\n case BANNER_TYPES.DANGER:\n return colors.danger[900];\n default:\n return 'should_not_happen';\n }\n};\ninterface StyledBannerLayoutT {\n $type: DSBannerT.BannerTypesT;\n}\nexport const StyledBannerLayout = styled('div', {\n name: DSBannerName,\n slot: DSBannerSlots.LAYOUT,\n})<StyledBannerLayoutT>`\n display: flex;\n width: 100%;\n align-items: flex-start;\n justify-content: space-between;\n background-color: neutral-000;\n border-bottom: 5px solid ${({ $type, theme }) => handleBorderColor($type, theme)};\n & > :first-child {\n flex: 1;\n min-width: 0;\n }\n`;\n\nexport const StyledIconContainer = styled('div', {\n name: DSBannerName,\n slot: DSBannerSlots.ICON_CONTAINER,\n})`\n padding-top: 8px;\n margin-right: ${({ theme }) => theme.space.xxs};\n margin-left: ${({ theme }) => theme.space.xs};\n min-width: 0px;\n`;\n\nconst isSmallLayout = ({ theme }: { theme: { layoutMode?: string } }) => ['s', 'xs'].includes(theme.layoutMode!);\n\n// title, description and action link are the 3 children (in this order). Default layouts: the title and the description\n// share the first column and the action link is its own cell right after the text (the first column grows with the\n// text up to the free space, the link keeps its own width). Small layouts: a single column, the link goes on its own\n// row below the description.\nexport const StyledBody = styled('div', { name: DSBannerName, slot: DSBannerSlots.BODY })`\n display: grid;\n grid-template-columns: ${(props) => (isSmallLayout(props) ? 'minmax(0, 1fr)' : 'minmax(0, max-content) auto')};\n justify-content: start;\n padding-top: 9px;\n & > :nth-child(-n + 2) {\n grid-column: 1;\n }\n`;\n\nexport const StyledTitle = styled(DSTypography, { name: DSBannerName, slot: DSBannerSlots.TITLE })`\n display: block;\n color: neutral-700;\n overflow-wrap: break-word;\n white-space: pre-wrap;\n min-width: 0px;\n`;\n\n// the description carries the bottom spacing of the content area (Spec v2)\nexport const StyledSubTitle = styled(DSTypography, { name: DSBannerName, slot: DSBannerSlots.SUBTITLE })`\n font-weight: ${({ theme }) => theme.fontWeights.regular};\n overflow-wrap: break-word;\n white-space: pre-wrap;\n min-width: 0px;\n padding-bottom: 9px;\n`;\n\ninterface StyledActionLinkT {\n isBodyEmpty: boolean;\n}\n// its own cell of the StyledBody grid (never inline in the description), nested in DSTypography (link-sml-title variant).\nexport const StyledActionLink = styled(DSTypography, {\n name: DSBannerName,\n slot: DSBannerSlots.ACTION_LINK,\n})<StyledActionLinkT>`\n min-width: 0px;\n position: relative;\n margin-bottom: 9px;\n ${(props) =>\n isSmallLayout(props)\n ? `\n justify-self: start;\n `\n : `\n grid-column: 2;\n grid-row: ${props.isBodyEmpty ? 1 : 2};\n align-self: end;\n align-self: last baseline;\n margin-left: 16px;\n `}\n /* Typography and underline of the action link (PUI-19233).\n Size comes from the link-sml-title variant (set in DSBannerContent). The rest is the Link \"inline text\" styling:\n idle underline + brand-600, hover no underline + brand-800 (decided: the link is underlined at rest).\n PENDING UX CONFIRMATION: only font-weight (400 vs the variant's weight; the spec names a variant that does not\n exist) and line-height (the description's, the variant's 24px would make the banner taller and misalign the\n baselines). Adjusting them once UX answers should only touch those two declarations. */\n font-weight: ${({ theme }) => theme.fontWeights.regular};\n line-height: 1.278;\n text-decoration: underline;\n color: brand-600;\n &:hover {\n text-decoration: none;\n color: brand-800;\n }\n &:focus {\n outline: none;\n &:after {\n position: absolute;\n content: '';\n top: -2px;\n left: -2px;\n right: -2px;\n bottom: -2px;\n border-radius: 2px;\n border: 2px solid brand-700;\n box-shadow: 0 0 0 1px brand-700;\n pointer-events: none;\n }\n }\n`;\nexport const StyledCloseButton = styled(DSButtonV2, {\n name: DSBannerName,\n slot: DSBannerSlots.CLOSE_BUTTON,\n})`\n margin-top: 4px;\n margin-left: 8px;\n`;\n\nexport const StyledLiveRegionPortal = styled('div', {\n name: DSBannerName,\n slot: DSBannerSlots.LIVE_REGION_PORTAL,\n})`\n clip: rect(0 0 0 0);\n position: absolute;\n`;\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,0BAA2B;AAC3B,qBAAqB;AAErB,uBAA2C;AAC3C,2BAA6B;AAC7B,uBAAoF;AAc7E,MAAM,4BAAwB,yBAAO,OAAO;AAAA,EACjD,MAAM;AAAA,EACN,MAAM,+BAAc;AACtB,CAAC;AAAA;AAAA;AAAA;AAAA,wBAIuB,CAAC,EAAE,cAAc,KAAK,MAAO,cAAc,mBAAmB,gBAAiB;AAAA,gBACvF,CAAC,EAAE,cAAc,KAAK,MAAO,cAAc,SAAS,KAAM;AAAA;AAAA;AAAA,yBAGjD,yCAAwB;AAAA,iBAChC,yCAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAarC,mCAAkB;AAAA;AAIf,MAAM,2BAAuB,yBAAO,qBAAM;AAAA,EAC/C,MAAM;AAAA,EACN,MAAM,+BAAc;AACtB,CAAC;AAAA;AAAA;AAAA;AAAA;AAMD,MAAM,oBAAoB,CACxB,MACA,EAAE,OAAO,MACE;AACX,UAAQ,MAAM;AAAA,IACZ,KAAK,8BAAa;AAChB,aAAO,OAAO,QAAQ,GAAG;AAAA,IAC3B,KAAK,8BAAa;AAChB,aAAO,OAAO,MAAM,GAAG;AAAA,IACzB,KAAK,8BAAa;AAChB,aAAO,OAAO,QAAQ,GAAG;AAAA,IAC3B,KAAK,8BAAa;AAChB,aAAO,OAAO,OAAO,GAAG;AAAA,IAC1B;AACE,aAAO;AAAA,EACX;AACF;AAIO,MAAM,yBAAqB,yBAAO,OAAO;AAAA,EAC9C,MAAM;AAAA,EACN,MAAM,+BAAc;AACtB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,6BAM4B,CAAC,EAAE,OAAO,MAAM,MAAM,kBAAkB,OAAO,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAO3E,MAAM,0BAAsB,yBAAO,OAAO;AAAA,EAC/C,MAAM;AAAA,EACN,MAAM,+BAAc;AACtB,CAAC;AAAA;AAAA,kBAEiB,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,GAAG;AAAA,iBAC/B,CAAC,EAAE,MAAM,MAAM,MAAM,MAAM,EAAE;AAAA;AAAA;AAI9C,MAAM,gBAAgB,CAAC,EAAE,MAAM,MAA0C,CAAC,KAAK,IAAI,EAAE,SAAS,MAAM,UAAW;AAMxG,MAAM,iBAAa,yBAAO,OAAO,EAAE,MAAM,+BAAc,MAAM,+BAAc,KAAK,CAAC;AAAA;AAAA,2BAE7D,CAAC,UAAW,cAAc,KAAK,IAAI,mBAAmB,6BAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQxG,MAAM,kBAAc,yBAAO,mCAAc,EAAE,MAAM,+BAAc,MAAM,+BAAc,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAS1F,MAAM,qBAAiB,yBAAO,mCAAc,EAAE,MAAM,+BAAc,MAAM,+BAAc,SAAS,CAAC;AAAA,iBACtF,CAAC,EAAE,MAAM,MAAM,MAAM,YAAY,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAWlD,MAAM,uBAAmB,yBAAO,mCAAc;AAAA,EACnD,MAAM;AAAA,EACN,MAAM,+BAAc;AACtB,CAAC;AAAA;AAAA;AAAA;AAAA,IAIG,CAAC,UACD,cAAc,KAAK,IACf;AAAA;AAAA,MAGA;AAAA;AAAA,gBAEQ,MAAM,cAAc,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,GAItC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAOc,CAAC,EAAE,MAAM,MAAM,MAAM,YAAY,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBlD,MAAM,wBAAoB,yBAAO,gCAAY;AAAA,EAClD,MAAM;AAAA,EACN,MAAM,+BAAc;AACtB,CAAC;AAAA;AAAA;AAAA;AAKM,MAAM,6BAAyB,yBAAO,OAAO;AAAA,EAClD,MAAM;AAAA,EACN,MAAM,+BAAc;AACtB,CAAC;AAAA;AAAA;AAAA;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (let key of __getOwnPropNames(from))
11
+ if (!__hasOwnProp.call(to, key) && key !== except)
12
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
+ }
14
+ return to;
15
+ };
16
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+ var React = __toESM(require("react"));
25
+ const SlotPropsAsObj = {
26
+ dsBannerContainer: { "aria-label": "just a typescript test" },
27
+ dsBannerInnerContainer: { "aria-label": "just a typescript test" },
28
+ dsBannerCustomContainer: { "aria-label": "just a typescript test" },
29
+ dsBannerBody: { "aria-label": "just a typescript test" },
30
+ dsBannerTitle: { "aria-label": "just a typescript test" },
31
+ dsBannerSubtitle: { "aria-label": "just a typescript test" },
32
+ dsBannerIconContainer: { "aria-label": "just a typescript test" },
33
+ dsBannerActionLink: { "aria-label": "just a typescript test" },
34
+ dsBannerCloseButton: { "aria-label": "just a typescript test" },
35
+ dsBannerLayout: { "aria-label": "just a typescript test" },
36
+ dsBannerLiveRegionPortal: { "aria-label": "just a typescript test" }
37
+ };
38
+ const SlotPropsAsFunctions = {
39
+ dsBannerContainer: () => ({ "aria-label": "just a typescript test" }),
40
+ dsBannerInnerContainer: () => ({ "aria-label": "just a typescript test" }),
41
+ dsBannerCustomContainer: () => ({ "aria-label": "just a typescript test" }),
42
+ dsBannerBody: () => ({ "aria-label": "just a typescript test" }),
43
+ dsBannerTitle: () => ({ "aria-label": "just a typescript test" }),
44
+ dsBannerSubtitle: () => ({ "aria-label": "just a typescript test" }),
45
+ dsBannerIconContainer: () => ({ "aria-label": "just a typescript test" }),
46
+ dsBannerActionLink: () => ({ "aria-label": "just a typescript test" }),
47
+ dsBannerCloseButton: () => ({ "aria-label": "just a typescript test" }),
48
+ dsBannerLayout: () => ({ "aria-label": "just a typescript test" }),
49
+ dsBannerLiveRegionPortal: () => ({ "aria-label": "just a typescript test" })
50
+ };
51
+ const EnsureAllSlotsExistInSlotFunctionArguments = SlotPropsAsFunctions;
52
+ //# sourceMappingURL=slot-props.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/typescript-testing/slot-props.ts"],
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */\n\nimport type { TypescriptHelpersT } from '@elliemae/ds-typescript-helpers';\nimport type { DSBannerName, DSBannerSlots } from '../constants/index.js';\nimport type { DSBannerT } from '../react-desc-prop-types.js';\n\nconst SlotPropsAsObj: Partial<DSBannerT.Props> = {\n dsBannerContainer: { 'aria-label': 'just a typescript test' },\n dsBannerInnerContainer: { 'aria-label': 'just a typescript test' },\n dsBannerCustomContainer: { 'aria-label': 'just a typescript test' },\n dsBannerBody: { 'aria-label': 'just a typescript test' },\n dsBannerTitle: { 'aria-label': 'just a typescript test' },\n dsBannerSubtitle: { 'aria-label': 'just a typescript test' },\n dsBannerIconContainer: { 'aria-label': 'just a typescript test' },\n dsBannerActionLink: { 'aria-label': 'just a typescript test' },\n dsBannerCloseButton: { 'aria-label': 'just a typescript test' },\n dsBannerLayout: { 'aria-label': 'just a typescript test' },\n dsBannerLiveRegionPortal: { 'aria-label': 'just a typescript test' },\n};\n\nconst SlotPropsAsFunctions: DSBannerT.SlotFunctionArguments = {\n dsBannerContainer: () => ({ 'aria-label': 'just a typescript test' }),\n dsBannerInnerContainer: () => ({ 'aria-label': 'just a typescript test' }),\n dsBannerCustomContainer: () => ({ 'aria-label': 'just a typescript test' }),\n dsBannerBody: () => ({ 'aria-label': 'just a typescript test' }),\n dsBannerTitle: () => ({ 'aria-label': 'just a typescript test' }),\n dsBannerSubtitle: () => ({ 'aria-label': 'just a typescript test' }),\n dsBannerIconContainer: () => ({ 'aria-label': 'just a typescript test' }),\n dsBannerActionLink: () => ({ 'aria-label': 'just a typescript test' }),\n dsBannerCloseButton: () => ({ 'aria-label': 'just a typescript test' }),\n dsBannerLayout: () => ({ 'aria-label': 'just a typescript test' }),\n dsBannerLiveRegionPortal: () => ({ 'aria-label': 'just a typescript test' }),\n};\n\n// Exhaustiveness check \u2014 fails compilation if a slot is missing from SlotFunctionArguments\nconst EnsureAllSlotsExistInSlotFunctionArguments: Required<\n TypescriptHelpersT.PropsForSlots<typeof DSBannerName, typeof DSBannerSlots>\n> = SlotPropsAsFunctions;\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA,YAAuB;ACMvB,MAAM,iBAA2C;AAAA,EAC/C,mBAAmB,EAAE,cAAc,yBAAyB;AAAA,EAC5D,wBAAwB,EAAE,cAAc,yBAAyB;AAAA,EACjE,yBAAyB,EAAE,cAAc,yBAAyB;AAAA,EAClE,cAAc,EAAE,cAAc,yBAAyB;AAAA,EACvD,eAAe,EAAE,cAAc,yBAAyB;AAAA,EACxD,kBAAkB,EAAE,cAAc,yBAAyB;AAAA,EAC3D,uBAAuB,EAAE,cAAc,yBAAyB;AAAA,EAChE,oBAAoB,EAAE,cAAc,yBAAyB;AAAA,EAC7D,qBAAqB,EAAE,cAAc,yBAAyB;AAAA,EAC9D,gBAAgB,EAAE,cAAc,yBAAyB;AAAA,EACzD,0BAA0B,EAAE,cAAc,yBAAyB;AACrE;AAEA,MAAM,uBAAwD;AAAA,EAC5D,mBAAmB,OAAO,EAAE,cAAc,yBAAyB;AAAA,EACnE,wBAAwB,OAAO,EAAE,cAAc,yBAAyB;AAAA,EACxE,yBAAyB,OAAO,EAAE,cAAc,yBAAyB;AAAA,EACzE,cAAc,OAAO,EAAE,cAAc,yBAAyB;AAAA,EAC9D,eAAe,OAAO,EAAE,cAAc,yBAAyB;AAAA,EAC/D,kBAAkB,OAAO,EAAE,cAAc,yBAAyB;AAAA,EAClE,uBAAuB,OAAO,EAAE,cAAc,yBAAyB;AAAA,EACvE,oBAAoB,OAAO,EAAE,cAAc,yBAAyB;AAAA,EACpE,qBAAqB,OAAO,EAAE,cAAc,yBAAyB;AAAA,EACrE,gBAAgB,OAAO,EAAE,cAAc,yBAAyB;AAAA,EAChE,0BAA0B,OAAO,EAAE,cAAc,yBAAyB;AAC5E;AAGA,MAAM,6CAEF;",
6
+ "names": []
7
+ }
@@ -34,7 +34,8 @@ const testOptionalProps = {
34
34
  },
35
35
  CustomBody: () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: "test" }),
36
36
  closeBtnRef: () => null,
37
- actionRef: { current: {} }
37
+ actionRef: { current: {} },
38
+ bannerId: "my-banner"
38
39
  };
39
40
  const testPartialDefaults = {
40
41
  label: "hello"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../scripts/build/transpile/react-shim.js", "../../../src/typescript-testing/typescript-banner-valid.tsx"],
4
- "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */\nimport { DSBanner } from '../index.js';\nimport type { DSBannerT } from '../index.js';\n\n// test we expose the namespace and the namespace follows our deliverable conventions\ntype ComponentPropsForApp = DSBannerT.Props;\ntype ComponentPropsInternals = DSBannerT.InternalProps;\ntype ComponentPropsDefaultProps = DSBannerT.DefaultProps;\ntype ComponentPropsOptionalProps = DSBannerT.OptionalProps;\ntype ComponentPropsRequiredProps = DSBannerT.RequiredProps;\n\nconst testRequiredProps: ComponentPropsRequiredProps = {};\nconst testOptionalProps: ComponentPropsOptionalProps = {\n actionLink: {\n label: 'test',\n onClick: () => {},\n href: 'test',\n },\n CustomBody: () => <div>test</div>,\n closeBtnRef: () => null,\n actionRef: { current: {} },\n};\n\n// difference Props and InternalProps is that InternalProps has all the default props filled in\n// Props allows for partial defaults\nconst testPartialDefaults: Partial<ComponentPropsDefaultProps> = {\n label: 'hello',\n};\nconst testProps: ComponentPropsForApp = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testPartialDefaults,\n};\nconst testPropsAsSyntax = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testPartialDefaults,\n} as ComponentPropsForApp;\n// InternalProps requires all defaults to be filled in\nconst testCompleteDefaults: Required<ComponentPropsDefaultProps> = {\n containerProps: {},\n label: '',\n body: '',\n type: 'info',\n isOpen: true,\n onClose: () => null,\n showCloseButton: true,\n withLiveRegionAnnouncement: 'alert',\n isPageNotice: false,\n};\nconst testInternalProps: ComponentPropsInternals = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testCompleteDefaults,\n};\nconst testInternalPropsAsSyntax = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testCompleteDefaults,\n} as ComponentPropsInternals;\n\n// using the explicit type definition, if there is an error, it will be marked on the key that is wrong\nconst testExplicitDefinition: ComponentPropsForApp = {\n label: '',\n body: '',\n type: 'info',\n isOpen: true,\n withLiveRegionAnnouncement: 'alert',\n isPageNotice: false,\n};\n\n// using the \"as\" syntax, if there is an error, it will be marking the whole object as wrong because it is not compatible with the type\nconst testInferedTypeCompatibility = {\n label: '',\n body: '',\n type: 'info',\n isOpen: true,\n withLiveRegionAnnouncement: 'alert',\n isPageNotice: false,\n} as ComponentPropsForApp;\n\nconst testDefinitionAsConst = {\n label: '',\n body: '',\n type: 'info',\n isOpen: true,\n withLiveRegionAnnouncement: 'alert',\n isPageNotice: false,\n} as const;\n\nconst ExampleUsageComponent = () => (\n <>\n {/* works with explicitly casted props, all syntaxes */}\n <DSBanner {...testExplicitDefinition} />\n <DSBanner {...testInferedTypeCompatibility} />\n <DSBanner {...testDefinitionAsConst} />\n {/* works with inline values */}\n <DSBanner label=\"hello\" body=\"body\" type=\"danger\" isOpen />\n </>\n);\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA,YAAuB;ACkBH;AAjBpB,eAAyB;AAUzB,MAAM,oBAAiD,CAAC;AACxD,MAAM,oBAAiD;AAAA,EACrD,YAAY;AAAA,IACV,OAAO;AAAA,IACP,SAAS,MAAM;AAAA,IAAC;AAAA,IAChB,MAAM;AAAA,EACR;AAAA,EACA,YAAY,MAAM,4CAAC,SAAI,kBAAI;AAAA,EAC3B,aAAa,MAAM;AAAA,EACnB,WAAW,EAAE,SAAS,CAAC,EAAE;AAC3B;AAIA,MAAM,sBAA2D;AAAA,EAC/D,OAAO;AACT;AACA,MAAM,YAAkC;AAAA,EACtC,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AACA,MAAM,oBAAoB;AAAA,EACxB,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAEA,MAAM,uBAA6D;AAAA,EACjE,gBAAgB,CAAC;AAAA,EACjB,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS,MAAM;AAAA,EACf,iBAAiB;AAAA,EACjB,4BAA4B;AAAA,EAC5B,cAAc;AAChB;AACA,MAAM,oBAA6C;AAAA,EACjD,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AACA,MAAM,4BAA4B;AAAA,EAChC,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAGA,MAAM,yBAA+C;AAAA,EACnD,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,4BAA4B;AAAA,EAC5B,cAAc;AAChB;AAGA,MAAM,+BAA+B;AAAA,EACnC,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,4BAA4B;AAAA,EAC5B,cAAc;AAChB;AAEA,MAAM,wBAAwB;AAAA,EAC5B,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,4BAA4B;AAAA,EAC5B,cAAc;AAChB;AAEA,MAAM,wBAAwB,MAC5B,4EAEE;AAAA,8CAAC,qBAAU,GAAG,wBAAwB;AAAA,EACtC,4CAAC,qBAAU,GAAG,8BAA8B;AAAA,EAC5C,4CAAC,qBAAU,GAAG,uBAAuB;AAAA,EAErC,4CAAC,qBAAS,OAAM,SAAQ,MAAK,QAAO,MAAK,UAAS,QAAM,MAAC;AAAA,GAC3D;",
4
+ "sourcesContent": ["import * as React from 'react';\nexport { React };\n", "/* eslint-disable @typescript-eslint/no-unused-vars, no-unused-vars */\nimport { DSBanner } from '../index.js';\nimport type { DSBannerT } from '../index.js';\n\n// test we expose the namespace and the namespace follows our deliverable conventions\ntype ComponentPropsForApp = DSBannerT.Props;\ntype ComponentPropsInternals = DSBannerT.InternalProps;\ntype ComponentPropsDefaultProps = DSBannerT.DefaultProps;\ntype ComponentPropsOptionalProps = DSBannerT.OptionalProps;\ntype ComponentPropsRequiredProps = DSBannerT.RequiredProps;\n\nconst testRequiredProps: ComponentPropsRequiredProps = {};\nconst testOptionalProps: ComponentPropsOptionalProps = {\n actionLink: {\n label: 'test',\n onClick: () => {},\n href: 'test',\n },\n CustomBody: () => <div>test</div>,\n closeBtnRef: () => null,\n actionRef: { current: {} },\n bannerId: 'my-banner',\n};\n\n// difference Props and InternalProps is that InternalProps has all the default props filled in\n// Props allows for partial defaults\nconst testPartialDefaults: Partial<ComponentPropsDefaultProps> = {\n label: 'hello',\n};\nconst testProps: ComponentPropsForApp = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testPartialDefaults,\n};\nconst testPropsAsSyntax = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testPartialDefaults,\n} as ComponentPropsForApp;\n// InternalProps requires all defaults to be filled in\nconst testCompleteDefaults: Required<ComponentPropsDefaultProps> = {\n containerProps: {},\n label: '',\n body: '',\n type: 'info',\n isOpen: true,\n onClose: () => null,\n showCloseButton: true,\n withLiveRegionAnnouncement: 'alert',\n isPageNotice: false,\n};\nconst testInternalProps: ComponentPropsInternals = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testCompleteDefaults,\n};\nconst testInternalPropsAsSyntax = {\n ...testRequiredProps,\n ...testOptionalProps,\n ...testCompleteDefaults,\n} as ComponentPropsInternals;\n\n// using the explicit type definition, if there is an error, it will be marked on the key that is wrong\nconst testExplicitDefinition: ComponentPropsForApp = {\n label: '',\n body: '',\n type: 'info',\n isOpen: true,\n withLiveRegionAnnouncement: 'alert',\n isPageNotice: false,\n};\n\n// using the \"as\" syntax, if there is an error, it will be marking the whole object as wrong because it is not compatible with the type\nconst testInferedTypeCompatibility = {\n label: '',\n body: '',\n type: 'info',\n isOpen: true,\n withLiveRegionAnnouncement: 'alert',\n isPageNotice: false,\n} as ComponentPropsForApp;\n\nconst testDefinitionAsConst = {\n label: '',\n body: '',\n type: 'info',\n isOpen: true,\n withLiveRegionAnnouncement: 'alert',\n isPageNotice: false,\n} as const;\n\nconst ExampleUsageComponent = () => (\n <>\n {/* works with explicitly casted props, all syntaxes */}\n <DSBanner {...testExplicitDefinition} />\n <DSBanner {...testInferedTypeCompatibility} />\n <DSBanner {...testDefinitionAsConst} />\n {/* works with inline values */}\n <DSBanner label=\"hello\" body=\"body\" type=\"danger\" isOpen />\n </>\n);\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA,YAAuB;ACkBH;AAjBpB,eAAyB;AAUzB,MAAM,oBAAiD,CAAC;AACxD,MAAM,oBAAiD;AAAA,EACrD,YAAY;AAAA,IACV,OAAO;AAAA,IACP,SAAS,MAAM;AAAA,IAAC;AAAA,IAChB,MAAM;AAAA,EACR;AAAA,EACA,YAAY,MAAM,4CAAC,SAAI,kBAAI;AAAA,EAC3B,aAAa,MAAM;AAAA,EACnB,WAAW,EAAE,SAAS,CAAC,EAAE;AAAA,EACzB,UAAU;AACZ;AAIA,MAAM,sBAA2D;AAAA,EAC/D,OAAO;AACT;AACA,MAAM,YAAkC;AAAA,EACtC,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AACA,MAAM,oBAAoB;AAAA,EACxB,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAEA,MAAM,uBAA6D;AAAA,EACjE,gBAAgB,CAAC;AAAA,EACjB,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS,MAAM;AAAA,EACf,iBAAiB;AAAA,EACjB,4BAA4B;AAAA,EAC5B,cAAc;AAChB;AACA,MAAM,oBAA6C;AAAA,EACjD,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AACA,MAAM,4BAA4B;AAAA,EAChC,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAGA,MAAM,yBAA+C;AAAA,EACnD,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,4BAA4B;AAAA,EAC5B,cAAc;AAChB;AAGA,MAAM,+BAA+B;AAAA,EACnC,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,4BAA4B;AAAA,EAC5B,cAAc;AAChB;AAEA,MAAM,wBAAwB;AAAA,EAC5B,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,4BAA4B;AAAA,EAC5B,cAAc;AAChB;AAEA,MAAM,wBAAwB,MAC5B,4EAEE;AAAA,8CAAC,qBAAU,GAAG,wBAAwB;AAAA,EACtC,4CAAC,qBAAU,GAAG,8BAA8B;AAAA,EAC5C,4CAAC,qBAAU,GAAG,uBAAuB;AAAA,EAErC,4CAAC,qBAAS,OAAM,SAAQ,MAAK,QAAO,MAAK,UAAS,QAAM,MAAC;AAAA,GAC3D;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var useBannerContainer_exports = {};
30
+ __export(useBannerContainer_exports, {
31
+ useBannerContainer: () => useBannerContainer
32
+ });
33
+ module.exports = __toCommonJS(useBannerContainer_exports);
34
+ var React = __toESM(require("react"));
35
+ var import_react = require("react");
36
+ var import_useBannerExitAnimation = require("./useBannerExitAnimation.js");
37
+ const useBannerContainer = (isOpen, actionRef) => {
38
+ const exitAnimation = (0, import_useBannerExitAnimation.useBannerExitAnimation)(isOpen);
39
+ const handleActionRefForContainer = (0, import_react.useCallback)(
40
+ (containerNode) => {
41
+ if (containerNode && actionRef && actionRef.current) {
42
+ actionRef.current.focusOnWrapper = () => {
43
+ if (containerNode) {
44
+ setTimeout(() => {
45
+ containerNode?.focus();
46
+ }, 300);
47
+ }
48
+ };
49
+ }
50
+ },
51
+ [actionRef]
52
+ );
53
+ return { handleActionRefForContainer, ...exitAnimation };
54
+ };
55
+ //# sourceMappingURL=useBannerContainer.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/useBannerContainer.ts", "../../../../../scripts/build/transpile/react-shim.js"],
4
+ "sourcesContent": ["import type React from 'react';\nimport { useCallback } from 'react';\nimport type { DSBannerT } from './react-desc-prop-types.js';\nimport { useBannerExitAnimation } from './useBannerExitAnimation.js';\n\n// everything the container needs from its lifecycle: the actionRef.focusOnWrapper hookup and the exit animation\nexport const useBannerContainer = (isOpen: boolean, actionRef: DSBannerT.InternalProps['actionRef']) => {\n const exitAnimation = useBannerExitAnimation(isOpen);\n\n const handleActionRefForContainer = useCallback<React.RefCallback<HTMLDivElement>>(\n (containerNode) => {\n if (containerNode && actionRef && actionRef.current) {\n actionRef.current.focusOnWrapper = () => {\n if (containerNode) {\n setTimeout(() => {\n containerNode?.focus();\n }, 300);\n }\n };\n }\n },\n [actionRef],\n );\n\n return { handleActionRefForContainer, ...exitAnimation };\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADCvB,mBAA4B;AAE5B,oCAAuC;AAGhC,MAAM,qBAAqB,CAAC,QAAiB,cAAoD;AACtG,QAAM,oBAAgB,sDAAuB,MAAM;AAEnD,QAAM,kCAA8B;AAAA,IAClC,CAAC,kBAAkB;AACjB,UAAI,iBAAiB,aAAa,UAAU,SAAS;AACnD,kBAAU,QAAQ,iBAAiB,MAAM;AACvC,cAAI,eAAe;AACjB,uBAAW,MAAM;AACf,6BAAe,MAAM;AAAA,YACvB,GAAG,GAAG;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,SAAO,EAAE,6BAA6B,GAAG,cAAc;AACzD;",
6
+ "names": []
7
+ }
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var useBannerExitAnimation_exports = {};
30
+ __export(useBannerExitAnimation_exports, {
31
+ useBannerExitAnimation: () => useBannerExitAnimation
32
+ });
33
+ module.exports = __toCommonJS(useBannerExitAnimation_exports);
34
+ var React = __toESM(require("react"));
35
+ var import_react = require("react");
36
+ var import_constants = require("./constants/index.js");
37
+ const EXIT_FALLBACK_MS = import_constants.BANNER_SLIDE_DURATION_MS + 100;
38
+ const SLIDE_PROPERTY = "grid-template-rows";
39
+ const prefersReducedMotion = () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
40
+ const useBannerExitAnimation = (isOpen) => {
41
+ const [wasOpen, setWasOpen] = (0, import_react.useState)(isOpen);
42
+ const [isExiting, setIsExiting] = (0, import_react.useState)(false);
43
+ if (wasOpen !== isOpen) {
44
+ setWasOpen(isOpen);
45
+ setIsExiting(wasOpen && !isOpen && !prefersReducedMotion());
46
+ }
47
+ (0, import_react.useEffect)(() => {
48
+ if (!isExiting) return void 0;
49
+ const timeoutId = setTimeout(() => setIsExiting(false), EXIT_FALLBACK_MS);
50
+ return () => clearTimeout(timeoutId);
51
+ }, [isExiting]);
52
+ const handleTransitionEnd = (0, import_react.useCallback)((e) => {
53
+ if (e.target === e.currentTarget && e.propertyName === SLIDE_PROPERTY) setIsExiting(false);
54
+ }, []);
55
+ const containerExitProps = (0, import_react.useMemo)(
56
+ () => isExiting ? { inert: "", "aria-hidden": true, onTransitionEnd: handleTransitionEnd } : {},
57
+ [isExiting, handleTransitionEnd]
58
+ );
59
+ return {
60
+ isContainerRendered: isOpen || isExiting,
61
+ containerExitProps,
62
+ // the live region does not wait for the slide: it remounts (empty) in the same commit that closes the banner
63
+ liveRegionKey: isOpen ? "open" : "closing"
64
+ };
65
+ };
66
+ //# sourceMappingURL=useBannerExitAnimation.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/useBannerExitAnimation.ts", "../../../../../scripts/build/transpile/react-shim.js"],
4
+ "sourcesContent": ["import type React from 'react';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { BANNER_SLIDE_DURATION_MS } from './constants/index.js';\n\n// the css transition is the source of truth for the exit, the timer is the safety net for the cases in which\n// \"transitionend\" never fires (jsdom, display none ancestor, consumer overriding the transition, interrupted transitions)\nconst EXIT_FALLBACK_MS = BANNER_SLIDE_DURATION_MS + 100;\nconst SLIDE_PROPERTY = 'grid-template-rows';\n\nconst prefersReducedMotion = () =>\n typeof window !== 'undefined' &&\n typeof window.matchMedia === 'function' &&\n window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n\ntype ExitProps = React.HTMLAttributes<HTMLDivElement> & { inert?: string };\n\n/**\n * Keeps the banner container mounted while it slides up after `isOpen` turns false.\n * Opening needs no state: the container mounts expanded and the css `@starting-style` slides it down.\n * With `prefers-reduced-motion: reduce` there is no exit phase, the banner is removed right away like it always was.\n */\nexport const useBannerExitAnimation = (isOpen: boolean) => {\n const [wasOpen, setWasOpen] = useState(isOpen);\n const [isExiting, setIsExiting] = useState(false);\n\n // derived during render (not in an effect): the container must still be there in the very commit that closes it,\n // otherwise there is no frame in which the transition can run. Re-opening mid exit cancels the exit.\n if (wasOpen !== isOpen) {\n setWasOpen(isOpen);\n setIsExiting(wasOpen && !isOpen && !prefersReducedMotion());\n }\n\n // synchronizes with an external system (the timers of the browser) while exiting\n // the cleanup runs on re-open, on unmount and when the exit finishes, so the timer can not fire after any of them\n useEffect(() => {\n if (!isExiting) return undefined;\n const timeoutId = setTimeout(() => setIsExiting(false), EXIT_FALLBACK_MS);\n return () => clearTimeout(timeoutId);\n }, [isExiting]);\n\n const handleTransitionEnd = useCallback((e: React.TransitionEvent<HTMLDivElement>) => {\n if (e.target === e.currentTarget && e.propertyName === SLIDE_PROPERTY) setIsExiting(false);\n }, []);\n\n // while sliding up the banner is already closed for everyone: no focus, no pointer, out of the a11y tree\n const containerExitProps = useMemo<ExitProps>(\n () => (isExiting ? { inert: '', 'aria-hidden': true, onTransitionEnd: handleTransitionEnd } : {}),\n [isExiting, handleTransitionEnd],\n );\n\n return {\n isContainerRendered: isOpen || isExiting,\n containerExitProps,\n // the live region does not wait for the slide: it remounts (empty) in the same commit that closes the banner\n liveRegionKey: isOpen ? 'open' : 'closing',\n };\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADCvB,mBAA0D;AAC1D,uBAAyC;AAIzC,MAAM,mBAAmB,4CAA2B;AACpD,MAAM,iBAAiB;AAEvB,MAAM,uBAAuB,MAC3B,OAAO,WAAW,eAClB,OAAO,OAAO,eAAe,cAC7B,OAAO,WAAW,kCAAkC,EAAE;AASjD,MAAM,yBAAyB,CAAC,WAAoB;AACzD,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAS,MAAM;AAC7C,QAAM,CAAC,WAAW,YAAY,QAAI,uBAAS,KAAK;AAIhD,MAAI,YAAY,QAAQ;AACtB,eAAW,MAAM;AACjB,iBAAa,WAAW,CAAC,UAAU,CAAC,qBAAqB,CAAC;AAAA,EAC5D;AAIA,8BAAU,MAAM;AACd,QAAI,CAAC,UAAW,QAAO;AACvB,UAAM,YAAY,WAAW,MAAM,aAAa,KAAK,GAAG,gBAAgB;AACxE,WAAO,MAAM,aAAa,SAAS;AAAA,EACrC,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,0BAAsB,0BAAY,CAAC,MAA6C;AACpF,QAAI,EAAE,WAAW,EAAE,iBAAiB,EAAE,iBAAiB,eAAgB,cAAa,KAAK;AAAA,EAC3F,GAAG,CAAC,CAAC;AAGL,QAAM,yBAAqB;AAAA,IACzB,MAAO,YAAY,EAAE,OAAO,IAAI,eAAe,MAAM,iBAAiB,oBAAoB,IAAI,CAAC;AAAA,IAC/F,CAAC,WAAW,mBAAmB;AAAA,EACjC;AAEA,SAAO;AAAA,IACL,qBAAqB,UAAU;AAAA,IAC/B;AAAA;AAAA,IAEA,eAAe,SAAS,SAAS;AAAA,EACnC;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var usePageNotice_exports = {};
30
+ __export(usePageNotice_exports, {
31
+ usePageNotice: () => usePageNotice
32
+ });
33
+ module.exports = __toCommonJS(usePageNotice_exports);
34
+ var React = __toESM(require("react"));
35
+ var import_react = require("react");
36
+ var import_uid = require("uid");
37
+ const hasName = (attrs) => !!attrs && ("aria-label" in attrs || "aria-labelledby" in attrs);
38
+ const usePageNotice = (propsWithDefaults, originalProps, globalAttrs) => {
39
+ const { isPageNotice, label, CustomBody, containerProps, bannerId } = propsWithDefaults;
40
+ const { dsBannerContainer } = propsWithDefaults;
41
+ const baseId = (0, import_react.useMemo)(() => bannerId ?? `ds-banner-${(0, import_uid.uid)(5)}`, [bannerId]);
42
+ const titleId = `${baseId}-title`;
43
+ const bodyId = `${baseId}-body`;
44
+ const slotProps = typeof dsBannerContainer === "function" ? dsBannerContainer({ ...originalProps }) : dsBannerContainer;
45
+ const hasConsumerName = hasName(slotProps) || [containerProps, globalAttrs].some(hasName);
46
+ const hasCustomBody = !!CustomBody;
47
+ const pageNoticeNameProps = (0, import_react.useMemo)(() => {
48
+ if (!isPageNotice || hasConsumerName || !label) return {};
49
+ return hasCustomBody ? { "aria-label": label } : { "aria-labelledby": titleId };
50
+ }, [isPageNotice, hasConsumerName, label, hasCustomBody, titleId]);
51
+ return { baseId, contentIds: { titleId, bodyId }, pageNoticeNameProps };
52
+ };
53
+ //# sourceMappingURL=usePageNotice.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/usePageNotice.ts", "../../../../../scripts/build/transpile/react-shim.js"],
4
+ "sourcesContent": ["import { useMemo } from 'react';\nimport { uid } from 'uid';\nimport type { DSBannerT } from './react-desc-prop-types.js';\n\ntype AnyAttrs = Record<string, unknown> | null | undefined;\n\nconst hasName = (attrs: AnyAttrs) => !!attrs && ('aria-label' in attrs || 'aria-labelledby' in attrs);\n\n// An element with role=\"region\" must have an accessible name, otherwise it is not exposed as a landmark.\n// The name defaults to the label prop, and any name provided by the consumer (containerProps,\n// global attributes or the dsBannerContainer slot) takes precedence.\nexport const usePageNotice = (\n propsWithDefaults: DSBannerT.InternalProps,\n originalProps: DSBannerT.Props,\n globalAttrs: AnyAttrs,\n) => {\n const { isPageNotice, label, CustomBody, containerProps, bannerId } = propsWithDefaults;\n const { dsBannerContainer } = propsWithDefaults as { dsBannerContainer?: unknown };\n // every id the banner renders derives from this single base, always starting with a letter (valid HTML id)\n const baseId = useMemo(() => bannerId ?? `ds-banner-${uid(5)}`, [bannerId]);\n const titleId = `${baseId}-title`;\n const bodyId = `${baseId}-body`;\n\n const slotProps = (\n typeof dsBannerContainer === 'function'\n ? (dsBannerContainer as (args: object) => AnyAttrs)({ ...originalProps })\n : dsBannerContainer\n ) as AnyAttrs;\n const hasConsumerName = hasName(slotProps) || [containerProps, globalAttrs].some(hasName);\n const hasCustomBody = !!CustomBody;\n\n const pageNoticeNameProps = useMemo<Record<string, string>>(() => {\n if (!isPageNotice || hasConsumerName || !label) return {} as Record<string, string>;\n return hasCustomBody ? { 'aria-label': label } : { 'aria-labelledby': titleId };\n }, [isPageNotice, hasConsumerName, label, hasCustomBody, titleId]);\n\n return { baseId, contentIds: { titleId, bodyId }, pageNoticeNameProps };\n};\n", "import * as React from 'react';\nexport { React };\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;ACAA,YAAuB;ADAvB,mBAAwB;AACxB,iBAAoB;AAKpB,MAAM,UAAU,CAAC,UAAoB,CAAC,CAAC,UAAU,gBAAgB,SAAS,qBAAqB;AAKxF,MAAM,gBAAgB,CAC3B,mBACA,eACA,gBACG;AACH,QAAM,EAAE,cAAc,OAAO,YAAY,gBAAgB,SAAS,IAAI;AACtE,QAAM,EAAE,kBAAkB,IAAI;AAE9B,QAAM,aAAS,sBAAQ,MAAM,YAAY,iBAAa,gBAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC1E,QAAM,UAAU,GAAG,MAAM;AACzB,QAAM,SAAS,GAAG,MAAM;AAExB,QAAM,YACJ,OAAO,sBAAsB,aACxB,kBAAiD,EAAE,GAAG,cAAc,CAAC,IACtE;AAEN,QAAM,kBAAkB,QAAQ,SAAS,KAAK,CAAC,gBAAgB,WAAW,EAAE,KAAK,OAAO;AACxF,QAAM,gBAAgB,CAAC,CAAC;AAExB,QAAM,0BAAsB,sBAAgC,MAAM;AAChE,QAAI,CAAC,gBAAgB,mBAAmB,CAAC,MAAO,QAAO,CAAC;AACxD,WAAO,gBAAgB,EAAE,cAAc,MAAM,IAAI,EAAE,mBAAmB,QAAQ;AAAA,EAChF,GAAG,CAAC,cAAc,iBAAiB,OAAO,eAAe,OAAO,CAAC;AAEjE,SAAO,EAAE,QAAQ,YAAY,EAAE,SAAS,OAAO,GAAG,oBAAoB;AACxE;",
6
+ "names": []
7
+ }