diff --git a/package-lock.json b/package-lock.json
index 294349328..789c80e71 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2399,6 +2399,7 @@
},
"node_modules/@clack/prompts/node_modules/is-unicode-supported": {
"version": "1.3.0",
+ "extraneous": true,
"inBundle": true,
"license": "MIT",
"engines": {
@@ -3549,6 +3550,50 @@
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.1.tgz",
"integrity": "sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw=="
},
+ "node_modules/@formatjs/ecma402-abstract": {
+ "version": "1.18.2",
+ "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.18.2.tgz",
+ "integrity": "sha512-+QoPW4csYALsQIl8GbN14igZzDbuwzcpWrku9nyMXlaqAlwRBgl5V+p0vWMGFqHOw37czNXaP/lEk4wbLgcmtA==",
+ "dependencies": {
+ "@formatjs/intl-localematcher": "0.5.4",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@formatjs/fast-memoize": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz",
+ "integrity": "sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA==",
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@formatjs/icu-messageformat-parser": {
+ "version": "2.7.6",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.6.tgz",
+ "integrity": "sha512-etVau26po9+eewJKYoiBKP6743I1br0/Ie00Pb/S/PtmYfmjTcOn2YCh2yNkSZI12h6Rg+BOgQYborXk46BvkA==",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "1.18.2",
+ "@formatjs/icu-skeleton-parser": "1.8.0",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@formatjs/icu-skeleton-parser": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.0.tgz",
+ "integrity": "sha512-QWLAYvM0n8hv7Nq5BEs4LKIjevpVpbGLAJgOaYzg9wABEoX1j0JO1q2/jVkO6CVlq0dbsxZCngS5aXbysYueqA==",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "1.18.2",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@formatjs/intl-localematcher": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz",
+ "integrity": "sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g==",
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@gar/promisify": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
@@ -3612,6 +3657,39 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@internationalized/date": {
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.5.1.tgz",
+ "integrity": "sha512-LUQIfwU9e+Fmutc/DpRTGXSdgYZLBegi4wygCWDSVmUdLTaMHsQyASDiJtREwanwKuQLq0hY76fCJ9J/9I2xOQ==",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ }
+ },
+ "node_modules/@internationalized/message": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@internationalized/message/-/message-3.1.1.tgz",
+ "integrity": "sha512-ZgHxf5HAPIaR0th+w0RUD62yF6vxitjlprSxmLJ1tam7FOekqRSDELMg4Cr/DdszG5YLsp5BG3FgHgqquQZbqw==",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0",
+ "intl-messageformat": "^10.1.0"
+ }
+ },
+ "node_modules/@internationalized/number": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.5.0.tgz",
+ "integrity": "sha512-ZY1BW8HT9WKYvaubbuqXbbDdHhOUMfE2zHHFJeTppid0S+pc8HtdIxFxaYMsGjCb4UsF+MEJ4n2TfU7iHnUK8w==",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ }
+ },
+ "node_modules/@internationalized/string": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@internationalized/string/-/string-3.2.0.tgz",
+ "integrity": "sha512-Xx3Sy3f2c9ctT+vh8c7euEaEHQZltp0euZ3Hy4UfT3E13r6lxpUS3kgKyumEjboJZSnaZv7JhqWz3D75v+IxQg==",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ }
+ },
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
@@ -7397,6 +7475,141 @@
"@babel/runtime": "^7.13.10"
}
},
+ "node_modules/@react-aria/i18n": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.10.1.tgz",
+ "integrity": "sha512-o05AozIXhropvN8vg0YD0Z0vajYuaALxB1+Km00FE5uGim4u2UKeBXqAk+8QsOs4CHg91paa3C15DcTDDEMJSg==",
+ "dependencies": {
+ "@internationalized/date": "^3.5.1",
+ "@internationalized/message": "^3.1.1",
+ "@internationalized/number": "^3.5.0",
+ "@internationalized/string": "^3.2.0",
+ "@react-aria/ssr": "^3.9.1",
+ "@react-aria/utils": "^3.23.1",
+ "@react-types/shared": "^3.22.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ }
+ },
+ "node_modules/@react-aria/interactions": {
+ "version": "3.21.0",
+ "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.21.0.tgz",
+ "integrity": "sha512-sPuzEl4Xq/BR5gbYr2R/sDzwlX9NdJ02i8Ew2rEy2hLMlf1jAeUAdTg/G+K9baWJ8acV9fZv6h/mdV3dXGLPSg==",
+ "dependencies": {
+ "@react-aria/ssr": "^3.9.1",
+ "@react-aria/utils": "^3.23.1",
+ "@react-types/shared": "^3.22.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ }
+ },
+ "node_modules/@react-aria/landmark": {
+ "version": "3.0.0-beta.9",
+ "resolved": "https://registry.npmjs.org/@react-aria/landmark/-/landmark-3.0.0-beta.9.tgz",
+ "integrity": "sha512-PtYEab60q7nuDmUTPPA2/ku0c4hzr1HiqFhmokYIXom9FTq0c4XBo5kaKKJo9UFD4NbKhNpMPmvCUJInKFYyIg==",
+ "dependencies": {
+ "@react-aria/utils": "^3.23.1",
+ "@react-types/shared": "^3.22.0",
+ "@swc/helpers": "^0.5.0",
+ "use-sync-external-store": "^1.2.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ }
+ },
+ "node_modules/@react-aria/ssr": {
+ "version": "3.9.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.1.tgz",
+ "integrity": "sha512-NqzkLFP8ZVI4GSorS0AYljC13QW2sc8bDqJOkBvkAt3M8gbcAXJWVRGtZBCRscki9RZF+rNlnPdg0G0jYkhJcg==",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ },
+ "engines": {
+ "node": ">= 12"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ }
+ },
+ "node_modules/@react-aria/toast": {
+ "version": "3.0.0-beta.9",
+ "resolved": "https://registry.npmjs.org/@react-aria/toast/-/toast-3.0.0-beta.9.tgz",
+ "integrity": "sha512-x0uDxUIK4P++B6sAxLeQ8JDdEn7ZsNXm78ys+Eq5qqgK7WHSzzF7CS1AP3CmtPH+2emuMiZyrs9JBNUMy0ihXg==",
+ "dependencies": {
+ "@react-aria/i18n": "^3.10.1",
+ "@react-aria/interactions": "^3.21.0",
+ "@react-aria/landmark": "3.0.0-beta.9",
+ "@react-aria/utils": "^3.23.1",
+ "@react-stately/toast": "3.0.0-beta.1",
+ "@react-types/button": "^3.9.1",
+ "@react-types/shared": "^3.22.0",
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ }
+ },
+ "node_modules/@react-aria/utils": {
+ "version": "3.23.1",
+ "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.23.1.tgz",
+ "integrity": "sha512-iXibf9ojqdoygbvy/++v5cKLKgjc/5ZmKV8/9u/2Hkpha1cf5Td/Z+Vl42B6giUBAsuDio5kuZYfYC7Uk+t8ag==",
+ "dependencies": {
+ "@react-aria/ssr": "^3.9.1",
+ "@react-stately/utils": "^3.9.0",
+ "@react-types/shared": "^3.22.0",
+ "@swc/helpers": "^0.5.0",
+ "clsx": "^2.0.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ }
+ },
+ "node_modules/@react-stately/toast": {
+ "version": "3.0.0-beta.1",
+ "resolved": "https://registry.npmjs.org/@react-stately/toast/-/toast-3.0.0-beta.1.tgz",
+ "integrity": "sha512-NeWdLXpHfXu8UXjmn+6iZv39Xvan/D0uNWzIyCxkDOeNNOHt1N4kSwdvQ56ScQ3f7KBVPqKz32t7K466Zpa8Jg==",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0",
+ "use-sync-external-store": "^1.2.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ }
+ },
+ "node_modules/@react-stately/utils": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.9.0.tgz",
+ "integrity": "sha512-yPKFY1F88HxuZ15BG2qwAYxtpE4HnIU0Ofi4CuBE0xC6I8mwo4OQjDzi+DZjxQngM9D6AeTTD6F1V8gkozA0Gw==",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ }
+ },
+ "node_modules/@react-types/button": {
+ "version": "3.9.1",
+ "resolved": "https://registry.npmjs.org/@react-types/button/-/button-3.9.1.tgz",
+ "integrity": "sha512-bf9iTar3PtqnyV9rA+wyFyrskZKhwmOuOd/ifYIjPs56YNVXWH5Wfqj6Dx3xdFBgtKx8mEVQxVhoX+WkHX+rtw==",
+ "dependencies": {
+ "@react-types/shared": "^3.22.0"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ }
+ },
+ "node_modules/@react-types/shared": {
+ "version": "3.22.0",
+ "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.22.0.tgz",
+ "integrity": "sha512-yVOekZWbtSmmiThGEIARbBpnmUIuePFlLyctjvCbgJgGhz8JnEJOipLQ/a4anaWfzAgzSceQP8j/K+VOOePleA==",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0"
+ }
+ },
"node_modules/@rollup/pluginutils": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.3.tgz",
@@ -7735,6 +7948,10 @@
"resolved": "packages/components/slot",
"link": true
},
+ "node_modules/@spark-ui/snackbar": {
+ "resolved": "packages/components/snackbar",
+ "link": true
+ },
"node_modules/@spark-ui/spinner": {
"resolved": "packages/components/spinner",
"link": true
@@ -10778,6 +10995,14 @@
"url": "https://opencollective.com/storybook"
}
},
+ "node_modules/@swc/helpers": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.6.tgz",
+ "integrity": "sha512-aYX01Ke9hunpoCexYAgQucEpARGQ5w/cqHFrIR+e9gdKb1QWTsVJuTJ2ozQzIAxLyRQe/m+2RqzkyOOGiMKRQA==",
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@testing-library/dom": {
"version": "8.20.1",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz",
@@ -19678,6 +19903,17 @@
"node": ">= 0.4"
}
},
+ "node_modules/intl-messageformat": {
+ "version": "10.5.11",
+ "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.5.11.tgz",
+ "integrity": "sha512-eYq5fkFBVxc7GIFDzpFQkDOZgNayNTQn4Oufe8jw6YY6OHVw70/4pA3FyCsQ0Gb2DnvEJEMmN2tOaXUGByM+kg==",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "1.18.2",
+ "@formatjs/fast-memoize": "2.2.0",
+ "@formatjs/icu-messageformat-parser": "2.7.6",
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/invariant": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
@@ -31629,6 +31865,14 @@
}
}
},
+ "node_modules/use-sync-external-store": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
+ "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/util": {
"version": "0.12.5",
"resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
@@ -33761,6 +34005,23 @@
"tailwindcss": "^3.0.0"
}
},
+ "packages/components/snackbar": {
+ "version": "1.0.0",
+ "license": "MIT",
+ "dependencies": {
+ "@react-aria/toast": "3.0.0-beta.9",
+ "@spark-ui/icon": "^2.1.0",
+ "@spark-ui/icon-button": "^2.2.1",
+ "@spark-ui/icons": "^1.21.6",
+ "class-variance-authority": "0.7.0"
+ },
+ "peerDependencies": {
+ "@spark-ui/theme-utils": "^4.0.0",
+ "react": "^16.8 || ^17.0 || ^18.0",
+ "react-dom": "^16.8 || ^17.0 || ^18.0",
+ "tailwindcss": "^3.0.0"
+ }
+ },
"packages/components/spinner": {
"name": "@spark-ui/spinner",
"version": "2.2.1",
diff --git a/packages/components/snackbar/.npmignore b/packages/components/snackbar/.npmignore
new file mode 100644
index 000000000..14144f5f7
--- /dev/null
+++ b/packages/components/snackbar/.npmignore
@@ -0,0 +1,2 @@
+src
+**/*.stories.*
diff --git a/packages/components/snackbar/LICENSE.md b/packages/components/snackbar/LICENSE.md
new file mode 100644
index 000000000..62d374781
--- /dev/null
+++ b/packages/components/snackbar/LICENSE.md
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) Adevinta ASA.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/packages/components/snackbar/README.md b/packages/components/snackbar/README.md
new file mode 100644
index 000000000..ee93dc5b7
--- /dev/null
+++ b/packages/components/snackbar/README.md
@@ -0,0 +1,13 @@
+# Snackbar
+> @spark-ui/snackbar
+
+[![storybook](https://img.shields.io/badge/storybook-black?logo=storybook)](https://sparkui.vercel.app/?path=/docs/components-snackbar--docs)
+[![documentation](https://img.shields.io/badge/documentation-black?logo=googledocs)](https://sparkui-adv.vercel.app/docs/components/snackbar)
+[![issue](https://img.shields.io/badge/report%20a%20bug-black?logo=openbugbounty&logoColor=red)](https://github.com/adevinta/spark/issues/new?&projects=4&template=bug-report.yml&assignees=&labels=component,snackbar)
+[![npm](https://img.shields.io/npm/dt/%40spark-ui/snackbar?logo=npm&labelColor=black)](https://www.npmjs.com/package/@spark-ui/snackbar)
+
+
+This package is part of the [`@spark-ui`](https://github.com/adevinta/spark) react-js user interface component library project.
+
+[![Issues open](https://img.shields.io/github/issues-search/adevinta/spark?query=is%3Aopen%20label%3Acomponent%20label%3Asnackbar&logo=openbugbounty&logoColor=red&label=issues%20open&color=red)](https://github.com/adevinta/spark/issues?q=is%3Aopen+label%3Acomponent+label%3Asnackbar)
+[![NPM](https://img.shields.io/npm/l/%40spark-ui%2Fsnackbar)](https://github.com/adevinta/spark/blob/main/packages/components/snackbar/LICENSE.md)
diff --git a/packages/components/snackbar/package.json b/packages/components/snackbar/package.json
new file mode 100644
index 000000000..9b5d2fe15
--- /dev/null
+++ b/packages/components/snackbar/package.json
@@ -0,0 +1,52 @@
+{
+ "name": "@spark-ui/snackbar",
+ "version": "0.0.0",
+ "description": "Display brief, temporary notifications. Meant to be noticed without disrupting a user's experience or requiring an action to be taken.",
+ "publishConfig": {
+ "access": "public"
+ },
+ "keywords": [
+ "@spark-ui",
+ "react",
+ "component",
+ "accessible",
+ "accessibility",
+ "wai-aria",
+ "aria",
+ "a11y",
+ "snackbar"
+ ],
+ "main": "./dist/index.js",
+ "module": "./dist/index.mjs",
+ "types": "./dist/index.d.ts",
+ "scripts": {
+ "build": "vite build"
+ },
+ "dependencies": {
+ "@react-aria/toast": "3.0.0-beta.9",
+ "@spark-ui/icon": "^2.1.0",
+ "@spark-ui/icon-button": "^2.2.1",
+ "@spark-ui/icons": "^1.21.6",
+ "class-variance-authority": "0.7.0"
+ },
+ "peerDependencies": {
+ "@spark-ui/theme-utils": "^4.0.0",
+ "react": "^16.8 || ^17.0 || ^18.0",
+ "react-dom": "^16.8 || ^17.0 || ^18.0",
+ "tailwindcss": "^3.0.0"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/adevinta/spark.git",
+ "directory": "packages/components/snackbar"
+ },
+ "config": {
+ "title": "snackbar",
+ "category": "components"
+ },
+ "bugs": {
+ "url": "https://github.com/adevinta/spark/issues?q=is%3Aopen+label%3Autility+label%3Asnackbar"
+ },
+ "homepage": "https://sparkui.vercel.app",
+ "license": "MIT"
+}
diff --git a/packages/components/snackbar/src/Snackbar.doc.mdx b/packages/components/snackbar/src/Snackbar.doc.mdx
new file mode 100644
index 000000000..dd74e4a0c
--- /dev/null
+++ b/packages/components/snackbar/src/Snackbar.doc.mdx
@@ -0,0 +1,31 @@
+import { Meta, Canvas } from '@storybook/addon-docs'
+import { ArgTypes } from '@storybook/blocks';
+
+import { Snackbar } from '.'
+
+import * as stories from './Snackbar.stories'
+
+
+
+# Snackbar
+
+Display brief, temporary notifications. Meant to be noticed without disrupting a user's experience or requiring an action to be taken.
+
+## Install
+
+```sh
+npm install @spark-ui/snackbar
+```
+
+## Import
+
+```tsx
+import { Snackbar } from "@spark-ui/snackbar"
+```
+
+## Props
+
+
+
+## Variants
+
diff --git a/packages/components/snackbar/src/Snackbar.stories.tsx b/packages/components/snackbar/src/Snackbar.stories.tsx
new file mode 100644
index 000000000..f36ba06bc
--- /dev/null
+++ b/packages/components/snackbar/src/Snackbar.stories.tsx
@@ -0,0 +1,12 @@
+import { Meta, StoryFn } from '@storybook/react'
+
+import { Snackbar } from '.'
+
+const meta: Meta = {
+ title: 'Experimental/Snackbar',
+ component: Snackbar,
+}
+
+export default meta
+
+export const Default: StoryFn = _args => Hello World!
diff --git a/packages/components/snackbar/src/Snackbar.styles.ts b/packages/components/snackbar/src/Snackbar.styles.ts
new file mode 100644
index 000000000..e69de29bb
diff --git a/packages/components/snackbar/src/Snackbar.test.tsx b/packages/components/snackbar/src/Snackbar.test.tsx
new file mode 100644
index 000000000..0670f6928
--- /dev/null
+++ b/packages/components/snackbar/src/Snackbar.test.tsx
@@ -0,0 +1,27 @@
+import { render, screen } from '@testing-library/react'
+import userEvent from '@testing-library/user-event'
+import { describe, expect, it, vi } from 'vitest'
+
+import { Snackbar } from './Snackbar'
+
+describe('Snackbar', () => {
+ it('should render', () => {
+ render(Hello World!)
+
+ expect(screen.getByText('Hello World!')).toBeInTheDocument()
+ })
+
+ it('should trigger click event', async () => {
+ const user = userEvent.setup()
+ const clickEvent = vi.fn()
+
+ // Given
+ render(Hello World!
)
+
+ // When
+ await user.click(screen.getByText('Hello World!'))
+
+ // Then
+ expect(clickEvent).toHaveBeenCalledTimes(1)
+ })
+})
diff --git a/packages/components/snackbar/src/Snackbar.tsx b/packages/components/snackbar/src/Snackbar.tsx
new file mode 100644
index 000000000..c78bd5fb0
--- /dev/null
+++ b/packages/components/snackbar/src/Snackbar.tsx
@@ -0,0 +1,9 @@
+import { ComponentPropsWithoutRef, forwardRef, PropsWithChildren } from 'react'
+
+export type SnackbarProps = ComponentPropsWithoutRef<'div'>
+
+export const Snackbar = forwardRef>(
+ (props, ref) => {
+ return
+ }
+)
diff --git a/packages/components/snackbar/src/index.ts b/packages/components/snackbar/src/index.ts
new file mode 100644
index 000000000..d4bcf87ad
--- /dev/null
+++ b/packages/components/snackbar/src/index.ts
@@ -0,0 +1 @@
+export { Snackbar } from './Snackbar'
diff --git a/packages/components/snackbar/tsconfig.json b/packages/components/snackbar/tsconfig.json
new file mode 100644
index 000000000..18f4c0e16
--- /dev/null
+++ b/packages/components/snackbar/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "../../../tsconfig.json",
+ "include": ["src/**/*", "../../../global.d.ts"]
+}
diff --git a/packages/components/snackbar/vite.config.ts b/packages/components/snackbar/vite.config.ts
new file mode 100644
index 000000000..64973e5ac
--- /dev/null
+++ b/packages/components/snackbar/vite.config.ts
@@ -0,0 +1,6 @@
+import path from 'path'
+import { getComponentConfiguration } from '../../../config/index'
+
+const { name } = require(path.resolve(__dirname, 'package.json'))
+
+export default getComponentConfiguration(process.cwd(), name)