@sps-woodland/growler 8.0.0-rc1
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/README.md +3 -0
- package/lib/Growler.css.d.ts +17 -0
- package/lib/Growler.d.ts +19 -0
- package/lib/Growler.examples.d.ts +2 -0
- package/lib/GrowlerListProvider.d.ts +7 -0
- package/lib/index.cjs.js +332 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.es.js +611 -0
- package/lib/manifest.d.ts +2 -0
- package/lib/style.css +1 -0
- package/package.json +45 -0
- package/vite.config.js +21 -0
package/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Tokens } from "@sps-woodland/tokens";
|
|
2
|
+
import type { VariantDefinitions, RecipeVariant, BooleanRecipeVariant } from "@sps-woodland/core";
|
|
3
|
+
export declare type GrowlerKind = keyof typeof Tokens.component.growler.kind;
|
|
4
|
+
interface GrowlerVariantDefinitions extends VariantDefinitions {
|
|
5
|
+
kind: RecipeVariant<GrowlerKind>;
|
|
6
|
+
fade: BooleanRecipeVariant;
|
|
7
|
+
}
|
|
8
|
+
export declare const growler: import("@vanilla-extract/recipes/dist/declarations/src/types").RuntimeFn<GrowlerVariantDefinitions>;
|
|
9
|
+
export declare const growlerArea: string;
|
|
10
|
+
export declare const growlerIconBox: string;
|
|
11
|
+
export declare const growlerIcon: string;
|
|
12
|
+
export declare const growlerMessageBox: string;
|
|
13
|
+
export declare const growlerMessageBoxText: string;
|
|
14
|
+
export declare const growlerMessageBoxTitle: string;
|
|
15
|
+
export declare const growlerMessageBoxSubtitle: string;
|
|
16
|
+
export declare const growlerCloseButton: string;
|
|
17
|
+
export {};
|
package/lib/Growler.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { ComponentProps } from "@sps-woodland/core";
|
|
3
|
+
import type { GrowlerKind } from "./Growler.css";
|
|
4
|
+
export declare const GrowlerIcons: Readonly<{
|
|
5
|
+
warning: "status-warning";
|
|
6
|
+
error: "status-error";
|
|
7
|
+
success: "status-ok";
|
|
8
|
+
info: "info-circle";
|
|
9
|
+
}>;
|
|
10
|
+
export declare function Growler({ children, className, imgSrc, kind, onClose, removeFromList, persist, title, id, ...rest }: ComponentProps<{
|
|
11
|
+
imgSrc?: string;
|
|
12
|
+
kind?: GrowlerKind;
|
|
13
|
+
onClose?: () => void;
|
|
14
|
+
removeFromList?: (id: string | number) => void;
|
|
15
|
+
closed?: boolean;
|
|
16
|
+
persist?: boolean;
|
|
17
|
+
title: string;
|
|
18
|
+
id?: string | number;
|
|
19
|
+
}> & React.HTMLAttributes<HTMLDivElement>): JSX.Element;
|
package/lib/index.cjs.js
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const A=require("react"),d=require("@sps-woodland/core"),L=require("@sps-woodland/buttons"),C=require("@sps-woodland/tokens"),N=require("react-dom"),i=require("@spscommerce/utils"),I=r=>r&&typeof r=="object"&&"default"in r?r:{default:r};function x(r){if(r&&r.__esModule)return r;const o=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const t in r)if(t!=="default"){const n=Object.getOwnPropertyDescriptor(r,t);Object.defineProperty(o,t,n.get?n:{enumerable:!0,get:()=>r[t]})}}return o.default=r,Object.freeze(o)}const e=x(A),T=I(N);function j(r,o,t){return o in r?Object.defineProperty(r,o,{value:t,enumerable:!0,configurable:!0,writable:!0}):r[o]=t,r}function b(r,o){var t=Object.keys(r);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(r);o&&(n=n.filter(function(s){return Object.getOwnPropertyDescriptor(r,s).enumerable})),t.push.apply(t,n)}return t}function E(r){for(var o=1;o<arguments.length;o++){var t=arguments[o]!=null?arguments[o]:{};o%2?b(Object(t),!0).forEach(function(n){j(r,n,t[n])}):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(t)):b(Object(t)).forEach(function(n){Object.defineProperty(r,n,Object.getOwnPropertyDescriptor(t,n))})}return r}var D=(r,o,t)=>{for(var n of Object.keys(r)){var s;if(r[n]!==((s=o[n])!==null&&s!==void 0?s:t[n]))return!1}return!0},U=r=>o=>{var t=r.defaultClassName,n=E(E({},r.defaultVariants),o);for(var s in n){var c,a=(c=n[s])!==null&&c!==void 0?c:r.defaultVariants[s];if(a!=null){var l=a;typeof l=="boolean"&&(l=l===!0?"true":"false");var u=r.variantClassNames[s][l];u&&(t+=" "+u)}}for(var[p,m]of r.compoundVariants)D(p,n,r.defaultVariants)&&(t+=" "+m);return t},F=U({defaultClassName:"_1c5fbnk1",variantClassNames:{kind:{activity:"_1c5fbnk2",info:"_1c5fbnk3",progress:"_1c5fbnk4",error:"_1c5fbnk5",success:"_1c5fbnk6",warning:"_1c5fbnk7"},fade:{true:"_1c5fbnk8",false:"_1c5fbnk9"}},defaultVariants:{},compoundVariants:[]}),W="_1c5fbnka",V="_1c5fbnkh",q="_1c5fbnkc",z="_1c5fbnkb",H="_1c5fbnkd",J="_1c5fbnke",Q="_1c5fbnkf";const B=Object.freeze({warning:"status-warning",error:"status-error",success:"status-ok",info:"info-circle"});function g({children:r,className:o,imgSrc:t,kind:n="info",onClose:s,removeFromList:c,persist:a,title:l,id:u,...p}){const m=e.useRef(s);e.useEffect(()=>{m.current=s},[s]);const G=C.Tokens.component.growler.duration.visible,M=C.Tokens.component.growler.duration.fadeout,[O,w]=e.useState(!1),{t:P}=e.useContext(d.I18nContext);function K(){return[window.setTimeout(()=>{w(!0)},G),window.setTimeout(()=>{m.current&&m.current(),c&&u&&c(u)},G+M)]}const f=e.useRef([]);function y(){a||(f.current=K())}function S(){for(const _ of f.current)window.clearTimeout(_);f.current=[]}function h(){S(),w(!1)}function R(){h(),w(!1),s&&s(),c&&u&&c(u)}return e.useEffect(()=>(y(),()=>{S()}),[]),e.createElement("div",{role:"alert","aria-live":"polite",className:d.cl(F({kind:n,fade:O}),o),onMouseEnter:h,onMouseLeave:y,...p},e.createElement("div",{className:z},t&&e.createElement("img",{src:t,alt:""}),n==="progress"?e.createElement(d.Spinner,null):e.createElement(d.Icon,{icon:B[n],className:q})),e.createElement("div",{className:H},e.createElement("div",{className:J},l&&e.createElement("span",{className:Q},l),e.createElement("div",null,r)),e.createElement(L.Button,{kind:"icon",icon:"x",title:P("design-system:growler.dismiss"),className:V,onClick:R})))}d.Metadata.set(g,{name:"Growler",props:{imgSrc:{type:"string"},kind:{type:"GrowlerKind",default:"info"},onClose:{type:"() => void"},persist:{type:"boolean"},title:{type:"string"}}});let X=(r=21)=>crypto.getRandomValues(new Uint8Array(r)).reduce((o,t)=>(t&=63,t<36?o+=t.toString(36):t<62?o+=(t-26).toString(36).toUpperCase():t>62?o+="-":o+="_",o),"");const k=e.createContext({growlerList:[],setGrowlerList:()=>{}});function v(r){const[o,t]=e.useState([]),n=a=>{if(!a){console.error("growlers should have an id");return}t(l=>l.filter(u=>a!==u.id))},s=o.map(({G:a,id:l})=>e.cloneElement(a(),{key:l,id:l,removeFromList:n})).filter(a=>d.Metadata.get(a.type).name==="Growler"?!0:(console.error("addGrowler only accepts a function that returns a Growler"),!1)),c=e.createElement("div",{"data-testid":r["data-testid"],"data-portalid":"growler-portal",className:W},s);return e.createElement(k.Provider,{value:{growlerList:o,setGrowlerList:t}},T.default.createPortal(c,document.body),r.children)}const Y=()=>{const r=e.useContext(k);if(r===void 0)throw new Error("addGrowler must be used within a GrowlerListProvider");return{addGrowler:e.useCallback(t=>{const n=X(),s={G:t,id:n};r.setGrowlerList([s,...r.growlerList])},[r])}},Z={description:()=>e.createElement("p",null,"Use Growlers for dynamic messages in response to a user's action. All Growlers have a Primary Message, and may optionally have a Secondary Message as needed. Growlers may also contain Hyperlinks in the Secondary Message."),components:[g,v],examples:{general:{label:"General Usage",description:()=>e.createElement(e.Fragment,null,e.createElement("p",null,"Use the following guidelines to write an effective Growler message."),e.createElement("ul",null,e.createElement("li",null,"Write all messages in sentence case.",e.createElement("ul",null,e.createElement("li",null,"Capitalize the first word of the message."),e.createElement("li",null,"Add punctuation, such as a period, at the end of the message."))),e.createElement("li",null,"Keep messages as succinct as possible while also providing sufficient information to the customer."),e.createElement("li",null,"If you can clearly convey your message in a single statement, use only the Primary Message."),e.createElement("li",null,"If the message requires additional details, such as further information or instructions, use both the Primary and Secondary Messages.")),e.createElement("p",null,"For more examples of effective feedback message writing, refer to ",e.createElement("a",{href:"https://atlassian.design/content/messaging-guidelines",target:"_blank"},"Atlassian's Messaging Guidelines"),"."))},provider:{label:"Growler List Provider",description:()=>e.createElement(e.Fragment,null,e.createElement("p",null,"Applications that use growlers should be wrapped in the",e.createElement("code",null,"GrowlerListProvider")," component. All growlers should be triggered by the addGrowler function from the ",e.createElement("code",null,"useGrowler")," hook"),e.createElement("p",null,"Wrapping your application in the ",e.createElement("code",null,"GrowlerListProvider"),"will allow you to call the ",e.createElement("code",null,"useGrowler")," hook from anywhere within your application. There is no longer a need to pass anything through to the children components."))},error:{label:"Error",description:()=>e.createElement(e.Fragment,null,e.createElement("p",null,"Acceptable message: Document ABC123 has not been sent. Check the form and try sending it again."),e.createElement("p",null,`Unacceptable message: "Can't send your document."`)),examples:{primary:{description:"Primary Message Only",react:i.code`
|
|
2
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
3
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
4
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
5
|
+
function MyComponent() {
|
|
6
|
+
|
|
7
|
+
const [growl, setGrowl] = React.useState(false);
|
|
8
|
+
const [count, setCount] = React.useState(1);
|
|
9
|
+
const { addGrowler } = useGrowler();
|
|
10
|
+
return (
|
|
11
|
+
|
|
12
|
+
<>
|
|
13
|
+
<SpsButton
|
|
14
|
+
data-testid="btn-error-primary"
|
|
15
|
+
kind={ButtonKind.LINK}
|
|
16
|
+
onClick={() => {
|
|
17
|
+
addGrowler(
|
|
18
|
+
() => (<Growler
|
|
19
|
+
data-testid="growler-error-primary"
|
|
20
|
+
kind="error"
|
|
21
|
+
title="Document ABC123 has not been sent."
|
|
22
|
+
onClose={() => {
|
|
23
|
+
console.log("Growler Closed");
|
|
24
|
+
}}
|
|
25
|
+
/>)
|
|
26
|
+
);
|
|
27
|
+
setCount(count + 1);
|
|
28
|
+
}
|
|
29
|
+
}>
|
|
30
|
+
Show Growler
|
|
31
|
+
</SpsButton>
|
|
32
|
+
</>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
`},primaryAndSecondary:{description:"Primary and Secondary Message",react:i.code`
|
|
36
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
37
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
38
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
39
|
+
function MyComponent() {
|
|
40
|
+
|
|
41
|
+
const [growl, setGrowl] = React.useState(false);
|
|
42
|
+
const [count, setCount] = React.useState(1);
|
|
43
|
+
const { addGrowler } = useGrowler();
|
|
44
|
+
return (
|
|
45
|
+
|
|
46
|
+
<>
|
|
47
|
+
<SpsButton
|
|
48
|
+
data-testid="btn-error-primary-and-secondary"
|
|
49
|
+
kind={ButtonKind.LINK}
|
|
50
|
+
onClick={() => {
|
|
51
|
+
addGrowler(
|
|
52
|
+
() => (<Growler
|
|
53
|
+
data-testid="growler-error-primary-and-secondary"
|
|
54
|
+
kind="error"
|
|
55
|
+
title="Document ABC123 has not been sent."
|
|
56
|
+
onClose={() => {
|
|
57
|
+
console.log("Growler closed.");
|
|
58
|
+
}}
|
|
59
|
+
title="Document ABC123 has not been sent."
|
|
60
|
+
>
|
|
61
|
+
Check the form and try sending it again.
|
|
62
|
+
</Growler>)
|
|
63
|
+
);
|
|
64
|
+
setCount(count + 1);
|
|
65
|
+
}
|
|
66
|
+
}>
|
|
67
|
+
Show Growler
|
|
68
|
+
</SpsButton>
|
|
69
|
+
</>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
`}}},information:{label:"Information",description:()=>e.createElement(e.Fragment,null,e.createElement("p",null,"Acceptable message: System maintenance notice. We'll be offline tonight from 9-11pm CST."),e.createElement("p",null,"Unacceptable message: No access tonight.")),examples:{primary:{description:"Primary Message Only",react:i.code`
|
|
73
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
74
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
75
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
76
|
+
function MyComponent() {
|
|
77
|
+
|
|
78
|
+
const [growl, setGrowl] = React.useState(false);
|
|
79
|
+
const [count, setCount] = React.useState(1);
|
|
80
|
+
const { addGrowler } = useGrowler();
|
|
81
|
+
return (
|
|
82
|
+
|
|
83
|
+
<>
|
|
84
|
+
<SpsButton
|
|
85
|
+
kind={ButtonKind.LINK}
|
|
86
|
+
onClick={() => {
|
|
87
|
+
addGrowler(
|
|
88
|
+
() => (<Growler
|
|
89
|
+
kind="info"
|
|
90
|
+
title="System maintenance tonight from 9-11pm CST."
|
|
91
|
+
onClose={() => {
|
|
92
|
+
console.log("Growler Closed");
|
|
93
|
+
}}
|
|
94
|
+
/>)
|
|
95
|
+
);
|
|
96
|
+
setCount(count + 1);
|
|
97
|
+
}
|
|
98
|
+
}>
|
|
99
|
+
Show Growler
|
|
100
|
+
</SpsButton>
|
|
101
|
+
</>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
`},primaryAndSecondary:{description:"Primary and Secondary Message",react:i.code`
|
|
105
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
106
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
107
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
108
|
+
function MyComponent() {
|
|
109
|
+
|
|
110
|
+
const [growl, setGrowl] = React.useState(false);
|
|
111
|
+
const [count, setCount] = React.useState(1);
|
|
112
|
+
const { addGrowler } = useGrowler();
|
|
113
|
+
return (
|
|
114
|
+
|
|
115
|
+
<>
|
|
116
|
+
<SpsButton
|
|
117
|
+
kind={ButtonKind.LINK}
|
|
118
|
+
onClick={() => {
|
|
119
|
+
addGrowler(
|
|
120
|
+
() => (<Growler
|
|
121
|
+
kind="info"
|
|
122
|
+
title="System maintenance tonight"
|
|
123
|
+
onClose={() => {
|
|
124
|
+
console.log("Growler Closed");
|
|
125
|
+
}} >
|
|
126
|
+
We'll be offline tonight from 9-11pm CST.
|
|
127
|
+
</Growler>)
|
|
128
|
+
);
|
|
129
|
+
setCount(count + 1);
|
|
130
|
+
}
|
|
131
|
+
}>
|
|
132
|
+
Show Growler
|
|
133
|
+
</SpsButton>
|
|
134
|
+
</>
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
`}}},progress:{label:"Progress",description:()=>e.createElement(e.Fragment,null,e.createElement("p",null,"Acceptable message: Export in progress."),e.createElement("p",null,"Unacceptable message: Please wait.")),examples:{primary:{description:"Primary Message Only",react:i.code`
|
|
138
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
139
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
140
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
141
|
+
function MyComponent() {
|
|
142
|
+
|
|
143
|
+
const [growl, setGrowl] = React.useState(false);
|
|
144
|
+
const [count, setCount] = React.useState(1);
|
|
145
|
+
const { addGrowler } = useGrowler();
|
|
146
|
+
return (
|
|
147
|
+
|
|
148
|
+
<>
|
|
149
|
+
<SpsButton
|
|
150
|
+
kind={ButtonKind.LINK}
|
|
151
|
+
onClick={() => {
|
|
152
|
+
addGrowler(
|
|
153
|
+
() => (<Growler
|
|
154
|
+
kind="progress"
|
|
155
|
+
title="Export in progress."
|
|
156
|
+
onClose={() => {
|
|
157
|
+
console.log("Growler Closed");
|
|
158
|
+
}}
|
|
159
|
+
/>)
|
|
160
|
+
);
|
|
161
|
+
setCount(count + 1);
|
|
162
|
+
}
|
|
163
|
+
}>
|
|
164
|
+
Show Growler
|
|
165
|
+
</SpsButton>
|
|
166
|
+
</>
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
`},primaryAndSecondary:{description:"Primary and Secondary Message",react:i.code`
|
|
170
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
171
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
172
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
173
|
+
function MyComponent() {
|
|
174
|
+
|
|
175
|
+
const [growl, setGrowl] = React.useState(false);
|
|
176
|
+
const [count, setCount] = React.useState(1);
|
|
177
|
+
const { addGrowler } = useGrowler();
|
|
178
|
+
return (
|
|
179
|
+
|
|
180
|
+
<>
|
|
181
|
+
<SpsButton
|
|
182
|
+
kind={ButtonKind.LINK}
|
|
183
|
+
onClick={() => {
|
|
184
|
+
addGrowler(
|
|
185
|
+
() => (<Growler
|
|
186
|
+
kind="progress"
|
|
187
|
+
title="Export in progress."
|
|
188
|
+
onClose={() => {
|
|
189
|
+
console.log("Growler Closed");
|
|
190
|
+
}} >
|
|
191
|
+
We'll let you know when it's done.
|
|
192
|
+
</Growler>)
|
|
193
|
+
);
|
|
194
|
+
setCount(count + 1);
|
|
195
|
+
}
|
|
196
|
+
}>
|
|
197
|
+
Show Growler
|
|
198
|
+
</SpsButton>
|
|
199
|
+
</>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
`}}},success:{label:"Success",description:()=>e.createElement(e.Fragment,null,e.createElement("p",null,"Acceptable message: Message sent. Our support team will respond to your message within 24 hours."),e.createElement("p",null,"Unacceptable message: Submitted.")),examples:{primary:{description:"Primary Message Only",react:i.code`
|
|
203
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
204
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
205
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
206
|
+
function MyComponent() {
|
|
207
|
+
|
|
208
|
+
const [growl, setGrowl] = React.useState(false);
|
|
209
|
+
const [count, setCount] = React.useState(1);
|
|
210
|
+
const { addGrowler } = useGrowler();
|
|
211
|
+
return (
|
|
212
|
+
|
|
213
|
+
<>
|
|
214
|
+
<SpsButton
|
|
215
|
+
kind={ButtonKind.LINK}
|
|
216
|
+
onClick={() => {
|
|
217
|
+
addGrowler(
|
|
218
|
+
() => (<Growler
|
|
219
|
+
kind="success"
|
|
220
|
+
title="Message sent."
|
|
221
|
+
onClose={() => {
|
|
222
|
+
console.log("Growler Closed");
|
|
223
|
+
}}
|
|
224
|
+
/>)
|
|
225
|
+
);
|
|
226
|
+
setCount(count + 1);
|
|
227
|
+
}
|
|
228
|
+
}>
|
|
229
|
+
Show Growler
|
|
230
|
+
</SpsButton>
|
|
231
|
+
</>
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
`},primaryAndSecondary:{description:"Primary and Secondary Message",react:i.code`
|
|
235
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
236
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
237
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
238
|
+
function MyComponent() {
|
|
239
|
+
|
|
240
|
+
const [growl, setGrowl] = React.useState(false);
|
|
241
|
+
const [count, setCount] = React.useState(1);
|
|
242
|
+
const { addGrowler } = useGrowler();
|
|
243
|
+
return (
|
|
244
|
+
|
|
245
|
+
<>
|
|
246
|
+
<SpsButton
|
|
247
|
+
kind={ButtonKind.LINK}
|
|
248
|
+
onClick={() => {
|
|
249
|
+
addGrowler(
|
|
250
|
+
() => (<Growler
|
|
251
|
+
kind="success"
|
|
252
|
+
title="Message sent."
|
|
253
|
+
onClose={() => {
|
|
254
|
+
console.log("Growler Closed");
|
|
255
|
+
}} >
|
|
256
|
+
Our support team will respond to your message within 24 hours.
|
|
257
|
+
</Growler>)
|
|
258
|
+
);
|
|
259
|
+
setCount(count + 1);
|
|
260
|
+
}
|
|
261
|
+
}>
|
|
262
|
+
Show Growler
|
|
263
|
+
</SpsButton>
|
|
264
|
+
</>
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
`}}},warning:{label:"Warning",description:()=>e.createElement(e.Fragment,null,e.createElement("p",null,"Acceptable message: No internet connection detected."),e.createElement("p",null,"Unacceptable message: Warning: There is a problem.")),examples:{primary:{description:"Primary Message Only",react:i.code`
|
|
268
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
269
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
270
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
271
|
+
function MyComponent() {
|
|
272
|
+
|
|
273
|
+
const [growl, setGrowl] = React.useState(false);
|
|
274
|
+
const [count, setCount] = React.useState(1);
|
|
275
|
+
const { addGrowler } = useGrowler();
|
|
276
|
+
return (
|
|
277
|
+
|
|
278
|
+
<>
|
|
279
|
+
<SpsButton
|
|
280
|
+
kind={ButtonKind.LINK}
|
|
281
|
+
onClick={() => {
|
|
282
|
+
addGrowler(
|
|
283
|
+
() => (<Growler
|
|
284
|
+
kind="warning"
|
|
285
|
+
title="No internet connection detected."
|
|
286
|
+
onClose={() => {
|
|
287
|
+
console.log("Growler Closed");
|
|
288
|
+
}}
|
|
289
|
+
/>)
|
|
290
|
+
);
|
|
291
|
+
setCount(count + 1);
|
|
292
|
+
}
|
|
293
|
+
}>
|
|
294
|
+
Show Growler
|
|
295
|
+
</SpsButton>
|
|
296
|
+
</>
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
`},primaryAndSecondary:{description:"Primary and Secondary Message",react:i.code`
|
|
300
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
301
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
302
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
303
|
+
function MyComponent() {
|
|
304
|
+
|
|
305
|
+
const [growl, setGrowl] = React.useState(false);
|
|
306
|
+
const [count, setCount] = React.useState(1);
|
|
307
|
+
const { addGrowler } = useGrowler();
|
|
308
|
+
return (
|
|
309
|
+
|
|
310
|
+
<>
|
|
311
|
+
<SpsButton
|
|
312
|
+
kind={ButtonKind.LINK}
|
|
313
|
+
onClick={() => {
|
|
314
|
+
addGrowler(
|
|
315
|
+
() => (<Growler
|
|
316
|
+
kind="warning"
|
|
317
|
+
title="No internet connection detected."
|
|
318
|
+
onClose={() => {
|
|
319
|
+
console.log("Growler Closed");
|
|
320
|
+
}} >
|
|
321
|
+
Check your connection and try again.
|
|
322
|
+
</Growler>)
|
|
323
|
+
);
|
|
324
|
+
setCount(count + 1);
|
|
325
|
+
}
|
|
326
|
+
}>
|
|
327
|
+
Show Growler
|
|
328
|
+
</SpsButton>
|
|
329
|
+
</>
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
`}}}}},$={Growlers:Z};exports.Growler=g;exports.GrowlerIcons=B;exports.GrowlerListProvider=v;exports.MANIFEST=$;exports.useGrowler=Y;
|
package/lib/index.d.ts
ADDED
package/lib/index.es.js
ADDED
|
@@ -0,0 +1,611 @@
|
|
|
1
|
+
import * as e from "react";
|
|
2
|
+
import { Metadata as b, I18nContext as R, cl as A, Spinner as L, Icon as N } from "@sps-woodland/core";
|
|
3
|
+
import { Button as x } from "@sps-woodland/buttons";
|
|
4
|
+
import { Tokens as S } from "@sps-woodland/tokens";
|
|
5
|
+
import _ from "react-dom";
|
|
6
|
+
import { code as i } from "@spscommerce/utils";
|
|
7
|
+
function I(r, o, t) {
|
|
8
|
+
return o in r ? Object.defineProperty(r, o, {
|
|
9
|
+
value: t,
|
|
10
|
+
enumerable: !0,
|
|
11
|
+
configurable: !0,
|
|
12
|
+
writable: !0
|
|
13
|
+
}) : r[o] = t, r;
|
|
14
|
+
}
|
|
15
|
+
function h(r, o) {
|
|
16
|
+
var t = Object.keys(r);
|
|
17
|
+
if (Object.getOwnPropertySymbols) {
|
|
18
|
+
var n = Object.getOwnPropertySymbols(r);
|
|
19
|
+
o && (n = n.filter(function(s) {
|
|
20
|
+
return Object.getOwnPropertyDescriptor(r, s).enumerable;
|
|
21
|
+
})), t.push.apply(t, n);
|
|
22
|
+
}
|
|
23
|
+
return t;
|
|
24
|
+
}
|
|
25
|
+
function C(r) {
|
|
26
|
+
for (var o = 1; o < arguments.length; o++) {
|
|
27
|
+
var t = arguments[o] != null ? arguments[o] : {};
|
|
28
|
+
o % 2 ? h(Object(t), !0).forEach(function(n) {
|
|
29
|
+
I(r, n, t[n]);
|
|
30
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(r, Object.getOwnPropertyDescriptors(t)) : h(Object(t)).forEach(function(n) {
|
|
31
|
+
Object.defineProperty(r, n, Object.getOwnPropertyDescriptor(t, n));
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return r;
|
|
35
|
+
}
|
|
36
|
+
var T = (r, o, t) => {
|
|
37
|
+
for (var n of Object.keys(r)) {
|
|
38
|
+
var s;
|
|
39
|
+
if (r[n] !== ((s = o[n]) !== null && s !== void 0 ? s : t[n]))
|
|
40
|
+
return !1;
|
|
41
|
+
}
|
|
42
|
+
return !0;
|
|
43
|
+
}, U = (r) => (o) => {
|
|
44
|
+
var t = r.defaultClassName, n = C(C({}, r.defaultVariants), o);
|
|
45
|
+
for (var s in n) {
|
|
46
|
+
var c, a = (c = n[s]) !== null && c !== void 0 ? c : r.defaultVariants[s];
|
|
47
|
+
if (a != null) {
|
|
48
|
+
var l = a;
|
|
49
|
+
typeof l == "boolean" && (l = l === !0 ? "true" : "false");
|
|
50
|
+
var u = r.variantClassNames[s][l];
|
|
51
|
+
u && (t += " " + u);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
for (var [d, m] of r.compoundVariants)
|
|
55
|
+
T(d, n, r.defaultVariants) && (t += " " + m);
|
|
56
|
+
return t;
|
|
57
|
+
}, D = U({ defaultClassName: "_1c5fbnk1", variantClassNames: { kind: { activity: "_1c5fbnk2", info: "_1c5fbnk3", progress: "_1c5fbnk4", error: "_1c5fbnk5", success: "_1c5fbnk6", warning: "_1c5fbnk7" }, fade: { true: "_1c5fbnk8", false: "_1c5fbnk9" } }, defaultVariants: {}, compoundVariants: [] }), j = "_1c5fbnka", F = "_1c5fbnkh", W = "_1c5fbnkc", V = "_1c5fbnkb", z = "_1c5fbnkd", q = "_1c5fbnke", H = "_1c5fbnkf";
|
|
58
|
+
const J = Object.freeze({
|
|
59
|
+
warning: "status-warning",
|
|
60
|
+
error: "status-error",
|
|
61
|
+
success: "status-ok",
|
|
62
|
+
info: "info-circle"
|
|
63
|
+
});
|
|
64
|
+
function E({
|
|
65
|
+
children: r,
|
|
66
|
+
className: o,
|
|
67
|
+
imgSrc: t,
|
|
68
|
+
kind: n = "info",
|
|
69
|
+
onClose: s,
|
|
70
|
+
removeFromList: c,
|
|
71
|
+
persist: a,
|
|
72
|
+
title: l,
|
|
73
|
+
id: u,
|
|
74
|
+
...d
|
|
75
|
+
}) {
|
|
76
|
+
const m = e.useRef(s);
|
|
77
|
+
e.useEffect(() => {
|
|
78
|
+
m.current = s;
|
|
79
|
+
}, [s]);
|
|
80
|
+
const f = S.component.growler.duration.visible, k = S.component.growler.duration.fadeout, [v, p] = e.useState(!1), { t: M } = e.useContext(R);
|
|
81
|
+
function K() {
|
|
82
|
+
return [
|
|
83
|
+
window.setTimeout(() => {
|
|
84
|
+
p(!0);
|
|
85
|
+
}, f),
|
|
86
|
+
window.setTimeout(() => {
|
|
87
|
+
m.current && m.current(), c && u && c(u);
|
|
88
|
+
}, f + k)
|
|
89
|
+
];
|
|
90
|
+
}
|
|
91
|
+
const w = e.useRef([]);
|
|
92
|
+
function g() {
|
|
93
|
+
a || (w.current = K());
|
|
94
|
+
}
|
|
95
|
+
function G() {
|
|
96
|
+
for (const P of w.current)
|
|
97
|
+
window.clearTimeout(P);
|
|
98
|
+
w.current = [];
|
|
99
|
+
}
|
|
100
|
+
function y() {
|
|
101
|
+
G(), p(!1);
|
|
102
|
+
}
|
|
103
|
+
function O() {
|
|
104
|
+
y(), p(!1), s && s(), c && u && c(u);
|
|
105
|
+
}
|
|
106
|
+
return e.useEffect(() => (g(), () => {
|
|
107
|
+
G();
|
|
108
|
+
}), []), /* @__PURE__ */ e.createElement("div", {
|
|
109
|
+
role: "alert",
|
|
110
|
+
"aria-live": "polite",
|
|
111
|
+
className: A(D({ kind: n, fade: v }), o),
|
|
112
|
+
onMouseEnter: y,
|
|
113
|
+
onMouseLeave: g,
|
|
114
|
+
...d
|
|
115
|
+
}, /* @__PURE__ */ e.createElement("div", {
|
|
116
|
+
className: V
|
|
117
|
+
}, t && /* @__PURE__ */ e.createElement("img", {
|
|
118
|
+
src: t,
|
|
119
|
+
alt: ""
|
|
120
|
+
}), n === "progress" ? /* @__PURE__ */ e.createElement(L, null) : /* @__PURE__ */ e.createElement(N, {
|
|
121
|
+
icon: J[n],
|
|
122
|
+
className: W
|
|
123
|
+
})), /* @__PURE__ */ e.createElement("div", {
|
|
124
|
+
className: z
|
|
125
|
+
}, /* @__PURE__ */ e.createElement("div", {
|
|
126
|
+
className: q
|
|
127
|
+
}, l && /* @__PURE__ */ e.createElement("span", {
|
|
128
|
+
className: H
|
|
129
|
+
}, l), /* @__PURE__ */ e.createElement("div", null, r)), /* @__PURE__ */ e.createElement(x, {
|
|
130
|
+
kind: "icon",
|
|
131
|
+
icon: "x",
|
|
132
|
+
title: M("design-system:growler.dismiss"),
|
|
133
|
+
className: F,
|
|
134
|
+
onClick: O
|
|
135
|
+
})));
|
|
136
|
+
}
|
|
137
|
+
b.set(E, {
|
|
138
|
+
name: "Growler",
|
|
139
|
+
props: {
|
|
140
|
+
imgSrc: { type: "string" },
|
|
141
|
+
kind: { type: "GrowlerKind", default: "info" },
|
|
142
|
+
onClose: { type: "() => void" },
|
|
143
|
+
persist: { type: "boolean" },
|
|
144
|
+
title: { type: "string" }
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
let Q = (r = 21) => crypto.getRandomValues(new Uint8Array(r)).reduce((o, t) => (t &= 63, t < 36 ? o += t.toString(36) : t < 62 ? o += (t - 26).toString(36).toUpperCase() : t > 62 ? o += "-" : o += "_", o), "");
|
|
148
|
+
const B = e.createContext({
|
|
149
|
+
growlerList: [],
|
|
150
|
+
setGrowlerList: () => {
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
function X(r) {
|
|
154
|
+
const [o, t] = e.useState([]), n = (a) => {
|
|
155
|
+
if (!a) {
|
|
156
|
+
console.error("growlers should have an id");
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
t((l) => l.filter((u) => a !== u.id));
|
|
160
|
+
}, s = o.map(({ G: a, id: l }) => e.cloneElement(a(), { key: l, id: l, removeFromList: n })).filter((a) => b.get(a.type).name === "Growler" ? !0 : (console.error(
|
|
161
|
+
"addGrowler only accepts a function that returns a Growler"
|
|
162
|
+
), !1)), c = /* @__PURE__ */ e.createElement("div", {
|
|
163
|
+
"data-testid": r["data-testid"],
|
|
164
|
+
"data-portalid": "growler-portal",
|
|
165
|
+
className: j
|
|
166
|
+
}, s);
|
|
167
|
+
return /* @__PURE__ */ e.createElement(B.Provider, {
|
|
168
|
+
value: { growlerList: o, setGrowlerList: t }
|
|
169
|
+
}, _.createPortal(c, document.body), r.children);
|
|
170
|
+
}
|
|
171
|
+
const oe = () => {
|
|
172
|
+
const r = e.useContext(B);
|
|
173
|
+
if (r === void 0)
|
|
174
|
+
throw new Error("addGrowler must be used within a GrowlerListProvider");
|
|
175
|
+
return { addGrowler: e.useCallback(
|
|
176
|
+
(t) => {
|
|
177
|
+
const n = Q(), s = {
|
|
178
|
+
G: t,
|
|
179
|
+
id: n
|
|
180
|
+
};
|
|
181
|
+
r.setGrowlerList([s, ...r.growlerList]);
|
|
182
|
+
},
|
|
183
|
+
[r]
|
|
184
|
+
) };
|
|
185
|
+
}, Y = {
|
|
186
|
+
description: () => /* @__PURE__ */ e.createElement("p", null, "Use Growlers for dynamic messages in response to a user's action. All Growlers have a Primary Message, and may optionally have a Secondary Message as needed. Growlers may also contain Hyperlinks in the Secondary Message."),
|
|
187
|
+
components: [E, X],
|
|
188
|
+
examples: {
|
|
189
|
+
general: {
|
|
190
|
+
label: "General Usage",
|
|
191
|
+
description: () => /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement("p", null, "Use the following guidelines to write an effective Growler message."), /* @__PURE__ */ e.createElement("ul", null, /* @__PURE__ */ e.createElement("li", null, "Write all messages in sentence case.", /* @__PURE__ */ e.createElement("ul", null, /* @__PURE__ */ e.createElement("li", null, "Capitalize the first word of the message."), /* @__PURE__ */ e.createElement("li", null, "Add punctuation, such as a period, at the end of the message."))), /* @__PURE__ */ e.createElement("li", null, "Keep messages as succinct as possible while also providing sufficient information to the customer."), /* @__PURE__ */ e.createElement("li", null, "If you can clearly convey your message in a single statement, use only the Primary Message."), /* @__PURE__ */ e.createElement("li", null, "If the message requires additional details, such as further information or instructions, use both the Primary and Secondary Messages.")), /* @__PURE__ */ e.createElement("p", null, "For more examples of effective feedback message writing, refer to ", /* @__PURE__ */ e.createElement("a", {
|
|
192
|
+
href: "https://atlassian.design/content/messaging-guidelines",
|
|
193
|
+
target: "_blank"
|
|
194
|
+
}, "Atlassian's Messaging Guidelines"), "."))
|
|
195
|
+
},
|
|
196
|
+
provider: {
|
|
197
|
+
label: "Growler List Provider",
|
|
198
|
+
description: () => /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement("p", null, "Applications that use growlers should be wrapped in the", /* @__PURE__ */ e.createElement("code", null, "GrowlerListProvider"), " component. All growlers should be triggered by the addGrowler function from the ", /* @__PURE__ */ e.createElement("code", null, "useGrowler"), " hook"), /* @__PURE__ */ e.createElement("p", null, "Wrapping your application in the ", /* @__PURE__ */ e.createElement("code", null, "GrowlerListProvider"), "will allow you to call the ", /* @__PURE__ */ e.createElement("code", null, "useGrowler"), " hook from anywhere within your application. There is no longer a need to pass anything through to the children components."))
|
|
199
|
+
},
|
|
200
|
+
error: {
|
|
201
|
+
label: "Error",
|
|
202
|
+
description: () => /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement("p", null, "Acceptable message: Document ABC123 has not been sent. Check the form and try sending it again."), /* @__PURE__ */ e.createElement("p", null, `Unacceptable message: "Can't send your document."`)),
|
|
203
|
+
examples: {
|
|
204
|
+
primary: {
|
|
205
|
+
description: "Primary Message Only",
|
|
206
|
+
react: i`
|
|
207
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
208
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
209
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
210
|
+
function MyComponent() {
|
|
211
|
+
|
|
212
|
+
const [growl, setGrowl] = React.useState(false);
|
|
213
|
+
const [count, setCount] = React.useState(1);
|
|
214
|
+
const { addGrowler } = useGrowler();
|
|
215
|
+
return (
|
|
216
|
+
|
|
217
|
+
<>
|
|
218
|
+
<SpsButton
|
|
219
|
+
data-testid="btn-error-primary"
|
|
220
|
+
kind={ButtonKind.LINK}
|
|
221
|
+
onClick={() => {
|
|
222
|
+
addGrowler(
|
|
223
|
+
() => (<Growler
|
|
224
|
+
data-testid="growler-error-primary"
|
|
225
|
+
kind="error"
|
|
226
|
+
title="Document ABC123 has not been sent."
|
|
227
|
+
onClose={() => {
|
|
228
|
+
console.log("Growler Closed");
|
|
229
|
+
}}
|
|
230
|
+
/>)
|
|
231
|
+
);
|
|
232
|
+
setCount(count + 1);
|
|
233
|
+
}
|
|
234
|
+
}>
|
|
235
|
+
Show Growler
|
|
236
|
+
</SpsButton>
|
|
237
|
+
</>
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
`
|
|
241
|
+
},
|
|
242
|
+
primaryAndSecondary: {
|
|
243
|
+
description: "Primary and Secondary Message",
|
|
244
|
+
react: i`
|
|
245
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
246
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
247
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
248
|
+
function MyComponent() {
|
|
249
|
+
|
|
250
|
+
const [growl, setGrowl] = React.useState(false);
|
|
251
|
+
const [count, setCount] = React.useState(1);
|
|
252
|
+
const { addGrowler } = useGrowler();
|
|
253
|
+
return (
|
|
254
|
+
|
|
255
|
+
<>
|
|
256
|
+
<SpsButton
|
|
257
|
+
data-testid="btn-error-primary-and-secondary"
|
|
258
|
+
kind={ButtonKind.LINK}
|
|
259
|
+
onClick={() => {
|
|
260
|
+
addGrowler(
|
|
261
|
+
() => (<Growler
|
|
262
|
+
data-testid="growler-error-primary-and-secondary"
|
|
263
|
+
kind="error"
|
|
264
|
+
title="Document ABC123 has not been sent."
|
|
265
|
+
onClose={() => {
|
|
266
|
+
console.log("Growler closed.");
|
|
267
|
+
}}
|
|
268
|
+
title="Document ABC123 has not been sent."
|
|
269
|
+
>
|
|
270
|
+
Check the form and try sending it again.
|
|
271
|
+
</Growler>)
|
|
272
|
+
);
|
|
273
|
+
setCount(count + 1);
|
|
274
|
+
}
|
|
275
|
+
}>
|
|
276
|
+
Show Growler
|
|
277
|
+
</SpsButton>
|
|
278
|
+
</>
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
`
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
information: {
|
|
286
|
+
label: "Information",
|
|
287
|
+
description: () => /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement("p", null, "Acceptable message: System maintenance notice. We'll be offline tonight from 9-11pm CST."), /* @__PURE__ */ e.createElement("p", null, "Unacceptable message: No access tonight.")),
|
|
288
|
+
examples: {
|
|
289
|
+
primary: {
|
|
290
|
+
description: "Primary Message Only",
|
|
291
|
+
react: i`
|
|
292
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
293
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
294
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
295
|
+
function MyComponent() {
|
|
296
|
+
|
|
297
|
+
const [growl, setGrowl] = React.useState(false);
|
|
298
|
+
const [count, setCount] = React.useState(1);
|
|
299
|
+
const { addGrowler } = useGrowler();
|
|
300
|
+
return (
|
|
301
|
+
|
|
302
|
+
<>
|
|
303
|
+
<SpsButton
|
|
304
|
+
kind={ButtonKind.LINK}
|
|
305
|
+
onClick={() => {
|
|
306
|
+
addGrowler(
|
|
307
|
+
() => (<Growler
|
|
308
|
+
kind="info"
|
|
309
|
+
title="System maintenance tonight from 9-11pm CST."
|
|
310
|
+
onClose={() => {
|
|
311
|
+
console.log("Growler Closed");
|
|
312
|
+
}}
|
|
313
|
+
/>)
|
|
314
|
+
);
|
|
315
|
+
setCount(count + 1);
|
|
316
|
+
}
|
|
317
|
+
}>
|
|
318
|
+
Show Growler
|
|
319
|
+
</SpsButton>
|
|
320
|
+
</>
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
`
|
|
324
|
+
},
|
|
325
|
+
primaryAndSecondary: {
|
|
326
|
+
description: "Primary and Secondary Message",
|
|
327
|
+
react: i`
|
|
328
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
329
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
330
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
331
|
+
function MyComponent() {
|
|
332
|
+
|
|
333
|
+
const [growl, setGrowl] = React.useState(false);
|
|
334
|
+
const [count, setCount] = React.useState(1);
|
|
335
|
+
const { addGrowler } = useGrowler();
|
|
336
|
+
return (
|
|
337
|
+
|
|
338
|
+
<>
|
|
339
|
+
<SpsButton
|
|
340
|
+
kind={ButtonKind.LINK}
|
|
341
|
+
onClick={() => {
|
|
342
|
+
addGrowler(
|
|
343
|
+
() => (<Growler
|
|
344
|
+
kind="info"
|
|
345
|
+
title="System maintenance tonight"
|
|
346
|
+
onClose={() => {
|
|
347
|
+
console.log("Growler Closed");
|
|
348
|
+
}} >
|
|
349
|
+
We'll be offline tonight from 9-11pm CST.
|
|
350
|
+
</Growler>)
|
|
351
|
+
);
|
|
352
|
+
setCount(count + 1);
|
|
353
|
+
}
|
|
354
|
+
}>
|
|
355
|
+
Show Growler
|
|
356
|
+
</SpsButton>
|
|
357
|
+
</>
|
|
358
|
+
);
|
|
359
|
+
}
|
|
360
|
+
`
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
progress: {
|
|
365
|
+
label: "Progress",
|
|
366
|
+
description: () => /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement("p", null, "Acceptable message: Export in progress."), /* @__PURE__ */ e.createElement("p", null, "Unacceptable message: Please wait.")),
|
|
367
|
+
examples: {
|
|
368
|
+
primary: {
|
|
369
|
+
description: "Primary Message Only",
|
|
370
|
+
react: i`
|
|
371
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
372
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
373
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
374
|
+
function MyComponent() {
|
|
375
|
+
|
|
376
|
+
const [growl, setGrowl] = React.useState(false);
|
|
377
|
+
const [count, setCount] = React.useState(1);
|
|
378
|
+
const { addGrowler } = useGrowler();
|
|
379
|
+
return (
|
|
380
|
+
|
|
381
|
+
<>
|
|
382
|
+
<SpsButton
|
|
383
|
+
kind={ButtonKind.LINK}
|
|
384
|
+
onClick={() => {
|
|
385
|
+
addGrowler(
|
|
386
|
+
() => (<Growler
|
|
387
|
+
kind="progress"
|
|
388
|
+
title="Export in progress."
|
|
389
|
+
onClose={() => {
|
|
390
|
+
console.log("Growler Closed");
|
|
391
|
+
}}
|
|
392
|
+
/>)
|
|
393
|
+
);
|
|
394
|
+
setCount(count + 1);
|
|
395
|
+
}
|
|
396
|
+
}>
|
|
397
|
+
Show Growler
|
|
398
|
+
</SpsButton>
|
|
399
|
+
</>
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
`
|
|
403
|
+
},
|
|
404
|
+
primaryAndSecondary: {
|
|
405
|
+
description: "Primary and Secondary Message",
|
|
406
|
+
react: i`
|
|
407
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
408
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
409
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
410
|
+
function MyComponent() {
|
|
411
|
+
|
|
412
|
+
const [growl, setGrowl] = React.useState(false);
|
|
413
|
+
const [count, setCount] = React.useState(1);
|
|
414
|
+
const { addGrowler } = useGrowler();
|
|
415
|
+
return (
|
|
416
|
+
|
|
417
|
+
<>
|
|
418
|
+
<SpsButton
|
|
419
|
+
kind={ButtonKind.LINK}
|
|
420
|
+
onClick={() => {
|
|
421
|
+
addGrowler(
|
|
422
|
+
() => (<Growler
|
|
423
|
+
kind="progress"
|
|
424
|
+
title="Export in progress."
|
|
425
|
+
onClose={() => {
|
|
426
|
+
console.log("Growler Closed");
|
|
427
|
+
}} >
|
|
428
|
+
We'll let you know when it's done.
|
|
429
|
+
</Growler>)
|
|
430
|
+
);
|
|
431
|
+
setCount(count + 1);
|
|
432
|
+
}
|
|
433
|
+
}>
|
|
434
|
+
Show Growler
|
|
435
|
+
</SpsButton>
|
|
436
|
+
</>
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
`
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
},
|
|
443
|
+
success: {
|
|
444
|
+
label: "Success",
|
|
445
|
+
description: () => /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement("p", null, "Acceptable message: Message sent. Our support team will respond to your message within 24 hours."), /* @__PURE__ */ e.createElement("p", null, "Unacceptable message: Submitted.")),
|
|
446
|
+
examples: {
|
|
447
|
+
primary: {
|
|
448
|
+
description: "Primary Message Only",
|
|
449
|
+
react: i`
|
|
450
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
451
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
452
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
453
|
+
function MyComponent() {
|
|
454
|
+
|
|
455
|
+
const [growl, setGrowl] = React.useState(false);
|
|
456
|
+
const [count, setCount] = React.useState(1);
|
|
457
|
+
const { addGrowler } = useGrowler();
|
|
458
|
+
return (
|
|
459
|
+
|
|
460
|
+
<>
|
|
461
|
+
<SpsButton
|
|
462
|
+
kind={ButtonKind.LINK}
|
|
463
|
+
onClick={() => {
|
|
464
|
+
addGrowler(
|
|
465
|
+
() => (<Growler
|
|
466
|
+
kind="success"
|
|
467
|
+
title="Message sent."
|
|
468
|
+
onClose={() => {
|
|
469
|
+
console.log("Growler Closed");
|
|
470
|
+
}}
|
|
471
|
+
/>)
|
|
472
|
+
);
|
|
473
|
+
setCount(count + 1);
|
|
474
|
+
}
|
|
475
|
+
}>
|
|
476
|
+
Show Growler
|
|
477
|
+
</SpsButton>
|
|
478
|
+
</>
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
`
|
|
482
|
+
},
|
|
483
|
+
primaryAndSecondary: {
|
|
484
|
+
description: "Primary and Secondary Message",
|
|
485
|
+
react: i`
|
|
486
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
487
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
488
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
489
|
+
function MyComponent() {
|
|
490
|
+
|
|
491
|
+
const [growl, setGrowl] = React.useState(false);
|
|
492
|
+
const [count, setCount] = React.useState(1);
|
|
493
|
+
const { addGrowler } = useGrowler();
|
|
494
|
+
return (
|
|
495
|
+
|
|
496
|
+
<>
|
|
497
|
+
<SpsButton
|
|
498
|
+
kind={ButtonKind.LINK}
|
|
499
|
+
onClick={() => {
|
|
500
|
+
addGrowler(
|
|
501
|
+
() => (<Growler
|
|
502
|
+
kind="success"
|
|
503
|
+
title="Message sent."
|
|
504
|
+
onClose={() => {
|
|
505
|
+
console.log("Growler Closed");
|
|
506
|
+
}} >
|
|
507
|
+
Our support team will respond to your message within 24 hours.
|
|
508
|
+
</Growler>)
|
|
509
|
+
);
|
|
510
|
+
setCount(count + 1);
|
|
511
|
+
}
|
|
512
|
+
}>
|
|
513
|
+
Show Growler
|
|
514
|
+
</SpsButton>
|
|
515
|
+
</>
|
|
516
|
+
);
|
|
517
|
+
}
|
|
518
|
+
`
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
},
|
|
522
|
+
warning: {
|
|
523
|
+
label: "Warning",
|
|
524
|
+
description: () => /* @__PURE__ */ e.createElement(e.Fragment, null, /* @__PURE__ */ e.createElement("p", null, "Acceptable message: No internet connection detected."), /* @__PURE__ */ e.createElement("p", null, "Unacceptable message: Warning: There is a problem.")),
|
|
525
|
+
examples: {
|
|
526
|
+
primary: {
|
|
527
|
+
description: "Primary Message Only",
|
|
528
|
+
react: i`
|
|
529
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
530
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
531
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
532
|
+
function MyComponent() {
|
|
533
|
+
|
|
534
|
+
const [growl, setGrowl] = React.useState(false);
|
|
535
|
+
const [count, setCount] = React.useState(1);
|
|
536
|
+
const { addGrowler } = useGrowler();
|
|
537
|
+
return (
|
|
538
|
+
|
|
539
|
+
<>
|
|
540
|
+
<SpsButton
|
|
541
|
+
kind={ButtonKind.LINK}
|
|
542
|
+
onClick={() => {
|
|
543
|
+
addGrowler(
|
|
544
|
+
() => (<Growler
|
|
545
|
+
kind="warning"
|
|
546
|
+
title="No internet connection detected."
|
|
547
|
+
onClose={() => {
|
|
548
|
+
console.log("Growler Closed");
|
|
549
|
+
}}
|
|
550
|
+
/>)
|
|
551
|
+
);
|
|
552
|
+
setCount(count + 1);
|
|
553
|
+
}
|
|
554
|
+
}>
|
|
555
|
+
Show Growler
|
|
556
|
+
</SpsButton>
|
|
557
|
+
</>
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
`
|
|
561
|
+
},
|
|
562
|
+
primaryAndSecondary: {
|
|
563
|
+
description: "Primary and Secondary Message",
|
|
564
|
+
react: i`
|
|
565
|
+
import { Growler, useGrowler } from "@sps-woodland/growler";
|
|
566
|
+
import { SpsButton } from "@spscommerce/ds-react";
|
|
567
|
+
import { ButtonKind } from "@spscommerce/ds-shared";
|
|
568
|
+
function MyComponent() {
|
|
569
|
+
|
|
570
|
+
const [growl, setGrowl] = React.useState(false);
|
|
571
|
+
const [count, setCount] = React.useState(1);
|
|
572
|
+
const { addGrowler } = useGrowler();
|
|
573
|
+
return (
|
|
574
|
+
|
|
575
|
+
<>
|
|
576
|
+
<SpsButton
|
|
577
|
+
kind={ButtonKind.LINK}
|
|
578
|
+
onClick={() => {
|
|
579
|
+
addGrowler(
|
|
580
|
+
() => (<Growler
|
|
581
|
+
kind="warning"
|
|
582
|
+
title="No internet connection detected."
|
|
583
|
+
onClose={() => {
|
|
584
|
+
console.log("Growler Closed");
|
|
585
|
+
}} >
|
|
586
|
+
Check your connection and try again.
|
|
587
|
+
</Growler>)
|
|
588
|
+
);
|
|
589
|
+
setCount(count + 1);
|
|
590
|
+
}
|
|
591
|
+
}>
|
|
592
|
+
Show Growler
|
|
593
|
+
</SpsButton>
|
|
594
|
+
</>
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
`
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
}, ne = {
|
|
603
|
+
Growlers: Y
|
|
604
|
+
};
|
|
605
|
+
export {
|
|
606
|
+
E as Growler,
|
|
607
|
+
J as GrowlerIcons,
|
|
608
|
+
X as GrowlerListProvider,
|
|
609
|
+
ne as MANIFEST,
|
|
610
|
+
oe as useGrowler
|
|
611
|
+
};
|
package/lib/style.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@keyframes _1c5fbnk0{0%{opacity:1}to{opacity:0}}._1c5fbnk1{border-radius:.25rem;box-shadow:0 0 .3125rem #00000040;display:flex;margin-bottom:1rem;overflow:hidden;width:25rem}._1c5fbnk2{background:#e9e9ea;border:.0625rem #717779 solid}._1c5fbnk3{background:#007db8;border:.0625rem #007db8 solid}._1c5fbnk4{background:#91467f;border:.0625rem #91467f solid}._1c5fbnk5{background:#de002e;border:.0625rem #de002e solid}._1c5fbnk6{background:#0b8940;border:.0625rem #0b8940 solid}._1c5fbnk7{background:#e7760b;border:.0625rem #e7760b solid}._1c5fbnk8{animation-name:_1c5fbnk0;animation-duration:2s}._1c5fbnk9{opacity:1}._1c5fbnka{display:flex;flex-direction:column;position:fixed;right:1.875rem;top:5.625rem;width:25rem}._1c5fbnkb{align-items:center;display:flex;flex-grow:0;flex-shrink:0;flex-basis:4.375rem;justify-content:center}._1c5fbnkc{color:#fff;font-size:1.875rem}._1c5fbnkd{background-color:#fff;padding:1rem 2.625rem 1rem 1rem;position:relative;display:flex;flex-grow:1}._1c5fbnke{flex-grow:1;font-size:.75rem;line-height:1.25rem}._1c5fbnkf{font-weight:600}._1c5fbnkg{color:#4b5356;overflow-wrap:break-word;width:16.5rem}._1c5fbnkh{position:absolute;right:.5rem;top:.5rem}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sps-woodland/growler",
|
|
3
|
+
"description": "SPS Woodland Design System growler component and hook",
|
|
4
|
+
"version": "8.0.0-rc1",
|
|
5
|
+
"author": "SPS Commerce",
|
|
6
|
+
"license": "UNLICENSED",
|
|
7
|
+
"repository": "https://github.com/SPSCommerce/woodland/tree/main/packages/@sps-woodland/growler",
|
|
8
|
+
"homepage": "https://github.com/SPSCommerce/woodland/tree/master/packages/@sps-woodland/growler#readme",
|
|
9
|
+
"main": "./lib/index.es.js",
|
|
10
|
+
"module": "./lib/index.es.js",
|
|
11
|
+
"types": "./lib/index.d.ts",
|
|
12
|
+
"publishConfig": {
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@spscommerce/i18n": "^7.1.3",
|
|
17
|
+
"nanoid": "^3.3.4"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"@spscommerce/utils": "^6.12.1",
|
|
21
|
+
"react": "^16.9.0",
|
|
22
|
+
"react-dom": "^16.9.0",
|
|
23
|
+
"@sps-woodland/core": "8.0.0-rc1",
|
|
24
|
+
"@sps-woodland/tokens": "8.0.0-rc1",
|
|
25
|
+
"@sps-woodland/buttons": "8.0.0-rc1"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@spscommerce/utils": "^6.12.1",
|
|
29
|
+
"@vanilla-extract/css": "^1.9.3",
|
|
30
|
+
"@vanilla-extract/recipes": "^0.2.5",
|
|
31
|
+
"react": "^16.9.0",
|
|
32
|
+
"react-dom": "^16.9.0",
|
|
33
|
+
"@sps-woodland/core": "8.0.0-rc1",
|
|
34
|
+
"@sps-woodland/tokens": "8.0.0-rc1",
|
|
35
|
+
"@sps-woodland/buttons": "8.0.0-rc1"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "pnpm run build:js && pnpm run build:types",
|
|
39
|
+
"build:js": "vite build",
|
|
40
|
+
"build:types": "tsc --emitDeclarationOnly --declaration --declarationDir lib",
|
|
41
|
+
"watch": "vite build --watch",
|
|
42
|
+
"clean": "git clean -fdX",
|
|
43
|
+
"pub": "node ../../../scripts/publish-package.js"
|
|
44
|
+
}
|
|
45
|
+
}
|
package/vite.config.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin";
|
|
3
|
+
import { defineConfig } from "vite";
|
|
4
|
+
|
|
5
|
+
import pkg from "./package.json";
|
|
6
|
+
|
|
7
|
+
export default defineConfig({
|
|
8
|
+
plugins: [vanillaExtractPlugin()],
|
|
9
|
+
build: {
|
|
10
|
+
lib: {
|
|
11
|
+
entry: path.resolve(__dirname, "src/index.ts"),
|
|
12
|
+
formats: ["es", "cjs"],
|
|
13
|
+
fileName: (format) => `index.${format}.js`,
|
|
14
|
+
},
|
|
15
|
+
outDir: path.resolve(__dirname, "./lib"),
|
|
16
|
+
emptyOutDir: false,
|
|
17
|
+
rollupOptions: {
|
|
18
|
+
external: pkg.peerDependencies ? Object.keys(pkg.peerDependencies) : [],
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
});
|