diff --git a/.prettierrc b/.prettierrc
index e69b455b3c..ad50d4c953 100644
--- a/.prettierrc
+++ b/.prettierrc
@@ -5,7 +5,9 @@
"arrowParens": "always",
"semi": false,
"htmlWhitespaceSensitivity": "ignore",
+ "plugins": ["prettier-plugin-svelte"],
"overrides": [
+ { "files": "*.svelte", "options": { "parser": "svelte" } },
{
"files": "*.md",
"options": {
diff --git a/bun.lockb b/bun.lockb
index 931716e907..5ea8f7a740 100755
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/packages/react/src/components/avatar/examples/root-provider.tsx b/packages/react/src/components/avatar/examples/root-provider.tsx
index 2c90455ef8..60d48637e0 100644
--- a/packages/react/src/components/avatar/examples/root-provider.tsx
+++ b/packages/react/src/components/avatar/examples/root-provider.tsx
@@ -5,11 +5,13 @@ export const RootProvider = () => {
return (
<>
-
+
PA
-
+
>
)
diff --git a/packages/svelte/.gitignore b/packages/svelte/.gitignore
deleted file mode 100644
index ac7211b403..0000000000
--- a/packages/svelte/.gitignore
+++ /dev/null
@@ -1,11 +0,0 @@
-.DS_Store
-node_modules
-/build
-/dist
-/.svelte-kit
-/package
-.env
-.env.*
-!.env.example
-vite.config.js.timestamp-*
-vite.config.ts.timestamp-*
diff --git a/packages/svelte/.npmrc b/packages/svelte/.npmrc
deleted file mode 100644
index b6f27f1359..0000000000
--- a/packages/svelte/.npmrc
+++ /dev/null
@@ -1 +0,0 @@
-engine-strict=true
diff --git a/packages/svelte/.storybook/main.css b/packages/svelte/.storybook/main.css
new file mode 100644
index 0000000000..63365cacef
--- /dev/null
+++ b/packages/svelte/.storybook/main.css
@@ -0,0 +1,36 @@
+@import url("./styles/accordion.css");
+@import url("./styles/avatar.css");
+@import url("./styles/carousel.css");
+@import url("./styles/checkbox.css");
+@import url("./styles/collapsible.css");
+@import url("./styles/color-picker.css");
+@import url("./styles/combobox.css");
+@import url("./styles/date-picker.css");
+@import url("./styles/dialog.css");
+@import url("./styles/field.css");
+@import url("./styles/file-upload.css");
+@import url("./styles/hover-card.css");
+@import url("./styles/menu.css");
+@import url("./styles/number-input.css");
+@import url("./styles/pagination.css");
+@import url("./styles/pin-input.css");
+@import url("./styles/popover.css");
+@import url("./styles/presence.css");
+@import url("./styles/progress.css");
+@import url("./styles/qr-code.css");
+@import url("./styles/radio-group.css");
+@import url("./styles/segment-group.css");
+@import url("./styles/select.css");
+@import url("./styles/signature-pad.css");
+@import url("./styles/slider.css");
+@import url("./styles/splitter.css");
+@import url("./styles/steps.css");
+@import url("./styles/switch.css");
+@import url("./styles/tabs.css");
+@import url("./styles/tags-input.css");
+@import url("./styles/time-picker.css");
+@import url("./styles/timer.css");
+@import url("./styles/toast.css");
+@import url("./styles/toggle-group.css");
+@import url("./styles/tooltip.css");
+@import url("./styles/tree-view.css");
diff --git a/packages/svelte/.storybook/main.ts b/packages/svelte/.storybook/main.ts
new file mode 100644
index 0000000000..e9e60a9005
--- /dev/null
+++ b/packages/svelte/.storybook/main.ts
@@ -0,0 +1,21 @@
+import type { StorybookConfig } from '@storybook/sveltekit'
+
+const config: StorybookConfig = {
+ stories: ['../src/**/*.stories.@(js|jsx|ts|tsx|svelte)'],
+ framework: '@storybook/sveltekit',
+ addons: [
+ {
+ name: '@storybook/addon-essentials',
+ options: { backgrounds: false, controls: false, actions: false },
+ },
+ '@storybook/addon-a11y',
+ ],
+ core: {
+ disableTelemetry: true,
+ },
+ docs: {
+ autodocs: false,
+ },
+}
+
+export default config
diff --git a/packages/svelte/.storybook/preview.ts b/packages/svelte/.storybook/preview.ts
new file mode 100644
index 0000000000..e13704db3a
--- /dev/null
+++ b/packages/svelte/.storybook/preview.ts
@@ -0,0 +1,15 @@
+import type { Preview } from '@storybook/react'
+import './main.css'
+
+const preview: Preview = {
+ parameters: {
+ options: {
+ storySort: {
+ method: 'alphabetical',
+ },
+ },
+ layout: 'padded',
+ },
+}
+
+export default preview
diff --git a/packages/svelte/.storybook/styles/accordion.css b/packages/svelte/.storybook/styles/accordion.css
new file mode 100644
index 0000000000..e83b9d5680
--- /dev/null
+++ b/packages/svelte/.storybook/styles/accordion.css
@@ -0,0 +1,53 @@
+@keyframes slideDown {
+ from {
+ opacity: 0.01;
+ height: 0;
+ }
+ to {
+ opacity: 1;
+ height: var(--height);
+ }
+}
+
+@keyframes slideUp {
+ from {
+ opacity: 1;
+ height: var(--height);
+ }
+ to {
+ opacity: 0.01;
+ height: 0;
+ }
+}
+
+
+[data-scope='accordion'][data-part='item-indicator'][data-state='open'] {
+ rotate: 90deg;
+}
+
+[data-scope='accordion'][data-part='item-trigger'] {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+}
+
+[data-scope='accordion'][data-part='item-trigger'] svg {
+ width: 1em;
+ height: 1em;
+}
+
+
+[data-scope="accordion"][data-part="item-content"] {
+ overflow: hidden;
+ max-width: 400px;
+ background-color: cadetblue;
+ color:white;
+}
+
+[data-scope="accordion"][data-part="item-content"][data-state="open"] {
+ animation: slideDown 250ms cubic-bezier(0, 0, 0.38, 0.9);
+}
+
+[data-scope="accordion"][data-part="item-content"][data-state="closed"] {
+ animation: slideUp 200ms cubic-bezier(0, 0, 0.38, 0.9);
+}
diff --git a/packages/svelte/.storybook/styles/avatar.css b/packages/svelte/.storybook/styles/avatar.css
new file mode 100644
index 0000000000..6d2c3c4713
--- /dev/null
+++ b/packages/svelte/.storybook/styles/avatar.css
@@ -0,0 +1,28 @@
+[data-scope='avatar'][data-part='root'] {
+ width: 80px;
+ height: 80px;
+ border-radius: 9999px;
+}
+
+[data-scope='avatar'][data-part='image'] {
+ width: 80px;
+ height: 80px;
+ object-fit: cover;
+ border-radius: inherit;
+}
+
+[data-scope='avatar'][data-part='fallback'] {
+ width: 80px;
+ height: 80px;
+ font-size: 14px;
+ line-height: 1;
+ font-weight: 600;
+ color: white;
+ background-color: #777;
+}
+
+[data-scope='avatar'][data-part='fallback']:not([hidden]) {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
diff --git a/packages/svelte/.storybook/styles/carousel.css b/packages/svelte/.storybook/styles/carousel.css
new file mode 100644
index 0000000000..20baa44a9d
--- /dev/null
+++ b/packages/svelte/.storybook/styles/carousel.css
@@ -0,0 +1,5 @@
+[data-scope='carousel'][data-part='viewport'] {
+ max-width: 600px;
+ margin-top: 40px;
+ overflow-x: hidden;
+}
diff --git a/packages/svelte/.storybook/styles/checkbox.css b/packages/svelte/.storybook/styles/checkbox.css
new file mode 100644
index 0000000000..e2dba355a5
--- /dev/null
+++ b/packages/svelte/.storybook/styles/checkbox.css
@@ -0,0 +1,36 @@
+[data-scope='checkbox'][data-part='root'] {
+ cursor: pointer;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
+
+[data-scope='checkbox'][data-part='group'] {
+ display: flex;
+ gap: 24px;
+}
+
+[data-scope='checkbox'][data-part='control'] {
+ border: 2px solid;
+ border-radius: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 24px;
+ height: 24px;
+
+ &[data-invalid] {
+ border-color: red;
+ }
+
+ &[data-disabled] {
+ opacity: 0.5;
+ }
+}
+
+
+[data-scope='checkbox'][data-part='indicator']:not([hidden]) {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
diff --git a/packages/svelte/.storybook/styles/collapsible.css b/packages/svelte/.storybook/styles/collapsible.css
new file mode 100644
index 0000000000..0a6bb5ba14
--- /dev/null
+++ b/packages/svelte/.storybook/styles/collapsible.css
@@ -0,0 +1,38 @@
+
+@keyframes slideDown {
+ from {
+ opacity: 0.01;
+ height: 0;
+ }
+ to {
+ opacity: 1;
+ height: var(--height);
+ }
+ }
+
+ @keyframes slideUp {
+ from {
+ opacity: 1;
+ height: var(--height);
+ }
+ to {
+ opacity: 0.01;
+ height: 0;
+ }
+ }
+
+ [data-scope="collapsible"][data-part="content"] {
+ overflow: hidden;
+ max-width: 400px;
+ background-color: cadetblue;
+ color:white;
+ }
+
+ [data-scope="collapsible"][data-part="content"][data-state="open"] {
+ animation: slideDown 250ms cubic-bezier(0, 0, 0.38, 0.9);
+ }
+
+ [data-scope="collapsible"][data-part="content"][data-state="closed"] {
+ animation: slideUp 200ms cubic-bezier(0, 0, 0.38, 0.9);
+ }
+
\ No newline at end of file
diff --git a/packages/svelte/.storybook/styles/color-picker.css b/packages/svelte/.storybook/styles/color-picker.css
new file mode 100644
index 0000000000..4808910fee
--- /dev/null
+++ b/packages/svelte/.storybook/styles/color-picker.css
@@ -0,0 +1,81 @@
+[data-scope='color-picker'][data-part='root'] {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ margin-bottom: 10px;
+ max-width: 400px;
+}
+
+[data-scope='color-picker'][data-part='control'] {
+ display: flex;
+ gap: 4px;
+}
+
+[data-scope='color-picker'][data-part='content'] {
+ width: 260px;
+ box-sizing: border-box;
+ padding: 24px;
+ border: 1px solid #d5d5d5;
+ background: white;
+}
+
+[data-scope='color-picker'][data-part='value-text'] {
+ min-width: fit-content;
+}
+
+[data-scope='color-picker'][data-part='content']:not(:is([hidden])) {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+}
+
+[data-scope='color-picker'][data-part='area'] {
+ height: 200px;
+ border-radius: 4px;
+ border: 1px solid #ebebeb;
+}
+
+[data-scope='color-picker'][data-part='area-background'] {
+ background: rgb(142, 142, 142);
+ border-radius: 4px;
+ height: 200px;
+}
+
+[data-scope='color-picker'][data-part='area-thumb'],
+[data-scope='color-picker'][data-part='channel-slider-thumb'] {
+ border: 2px solid white;
+ border-radius: 9999px;
+ box-sizing: border-box;
+ transform: translate(-50%, -50%);
+ box-shadow:
+ black 0px 0px 0px 1px,
+ black 0px 0px 0px 1px inset;
+ width: 16px;
+ height: 16px;
+}
+
+[data-scope='color-picker'][data-part='channel-slider-track'] {
+ height: 20px;
+ border-radius: 4px;
+}
+
+[data-scope='color-picker'][data-part='channel-input'] {
+ border-radius: 4px;
+ width: 100%;
+ border: 1px solid #c2c2c2;
+}
+
+[data-scope='color-picker'][data-part='swatch-group'] {
+ display: flex;
+ gap: 8px;
+}
+
+[data-scope='color-picker'][data-part='swatch'] {
+ width: 20px;
+ height: 20px;
+ flex-shrink: 0;
+}
+
+[data-scope='color-picker'][data-part='transparency-grid'] {
+ border-radius: 4px;
+}
diff --git a/packages/svelte/.storybook/styles/combobox.css b/packages/svelte/.storybook/styles/combobox.css
new file mode 100644
index 0000000000..d4e7696125
--- /dev/null
+++ b/packages/svelte/.storybook/styles/combobox.css
@@ -0,0 +1,47 @@
+[data-scope='combobox'][data-part='content'][data-state='open'] {
+ animation: fadeIn 0.25s ease-out;
+}
+
+[data-scope='combobox'][data-part='content'][data-state='closed'] {
+ animation: fadeOut 0.2s ease-in;
+}
+
+[data-scope='combobox'][data-part='content'] {
+ border: 1px solid gainsboro;
+ padding: 12px;
+}
+
+[data-scope='combobox'][data-part='item'] {
+ display: flex;
+ justify-content: space-between;
+}
+[data-scope='combobox'][data-part='item'][data-highlighted] {
+ background-color: lightblue;
+}
+
+
+[data-scope='combobox'][data-part='item'][data-disabled] {
+ color: silver;
+}
+
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ transform: translateY(-10px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@keyframes fadeOut {
+ from {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ to {
+ opacity: 0;
+ transform: translateY(-10px);
+ }
+}
diff --git a/packages/svelte/.storybook/styles/date-picker.css b/packages/svelte/.storybook/styles/date-picker.css
new file mode 100644
index 0000000000..a29214278b
--- /dev/null
+++ b/packages/svelte/.storybook/styles/date-picker.css
@@ -0,0 +1,78 @@
+[data-scope='date-picker'][data-part='table-cell-trigger'] {
+ padding: 4px;
+ min-width: 30px;
+ min-height: 30px;
+ border-radius: 4px;
+ text-align: center;
+ user-select: none;
+ -webkit-tap-highlight-color: transparent;
+}
+
+[data-scope='date-picker'][data-part='table-cell-trigger']:hover {
+ background: rgba(126, 126, 126, 0.171);
+}
+
+[data-scope='date-picker'][data-part='table-cell-trigger'][data-focus] {
+ background: rgba(165, 151, 165, 0.085);
+ color: rgba(128, 0, 128, 0.959);
+}
+
+[data-scope='date-picker'][data-part='table-cell-trigger'][data-outside-range] {
+ visibility: hidden;
+}
+
+[data-scope='date-picker'][data-part='table-cell-trigger'][data-selected] {
+ background: purple !important;
+ color: white !important ;
+}
+
+[data-scope='date-picker'][data-part='table-cell-trigger'][data-in-range]:not([data-selected]) {
+ background: rgb(240, 219, 240);
+}
+
+[data-scope='date-picker'][data-part='control'] {
+ display: flex;
+ gap: 10px;
+ margin-top: 20px;
+ margin-bottom: 16px;
+}
+
+[data-scope='date-picker'][data-part='table-cell-trigger'][data-today] {
+ color: purple;
+}
+
+[data-scope='date-picker'][data-part='table-cell-trigger'][data-unavailable] {
+ text-decoration: line-through;
+ opacity: 0.4;
+}
+
+[data-scope='date-picker'][data-part='table-cell-trigger'][data-disabled] {
+ opacity: 0.4;
+}
+
+[data-scope='date-picker'][data-part='content'] {
+ border: 1px solid gray;
+ padding: 1.5rem;
+ min-width: 320px;
+ background: white;
+ border-radius: 8px;
+}
+
+[data-scope='date-picker'][data-part='table'] {
+ min-width: 240px;
+ width: 100%;
+ border-collapse: collapse;
+}
+
+[data-scope='date-picker'][data-part='view-trigger'] {
+ border: 0;
+ padding: 4px 20px;
+ border-radius: 4px;
+}
+
+[data-scope='date-picker'][data-part='view-control'] {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-block: 10px;
+}
diff --git a/packages/svelte/.storybook/styles/dialog.css b/packages/svelte/.storybook/styles/dialog.css
new file mode 100644
index 0000000000..816f5b91e3
--- /dev/null
+++ b/packages/svelte/.storybook/styles/dialog.css
@@ -0,0 +1,102 @@
+[data-scope='dialog'][data-part='backdrop'] {
+ background-color: rgba(0, 0, 0, 0.8);
+ position: fixed;
+ inset: 0px;
+}
+
+[data-scope='dialog'][data-part='backdrop'][data-state='open'] {
+ animation: fadeIn 0.25s ease-out;
+}
+
+[data-scope='dialog'][data-part='backdrop'][data-state='closed'] {
+ animation: fadeOut 0.2s ease-in;
+}
+
+[data-scope='dialog'][data-part='container'] {
+ height: 100vh;
+ width: 100vw;
+ position: fixed;
+ inset: 0px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+[data-scope='dialog'][data-part='title'] {
+ margin: 0px;
+ font-weight: 500;
+ color: rgb(26, 21, 35);
+ font-size: 17px;
+}
+
+[data-scope='dialog'][data-part='description'] {
+ margin: 10px 0px 20px;
+ color: rgb(111, 110, 119);
+ font-size: 15px;
+ line-height: 1.5;
+}
+
+[data-scope='dialog'][data-part='content'] {
+ background-color: white;
+ border-radius: 6px;
+ box-shadow:
+ rgb(14 18 22 / 35%) 0px 10px 38px -10px,
+ rgb(14 18 22 / 20%) 0px 10px 20px -15px;
+ width: 100%;
+ max-width: 450px;
+ max-height: 85vh;
+ padding: 24px;
+ position: relative;
+}
+
+[data-scope='dialog'][data-part='content'][data-state='open'] {
+ animation: scaleIn 0.5s ease-out;
+}
+
+[data-scope='dialog'][data-part='content'][data-state='closed'] {
+ animation: scaleOut 0.5s ease-in;
+}
+
+[data-scope='dialog'][data-part='close-trigger'] {
+ position: absolute;
+ top: 10px;
+ right: 10px;
+}
+
+[data-scope='dialog'][data-part='close-trigger']:focus {
+ outline: 2px blue solid;
+ outline-offset: 2px;
+}
+
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+@keyframes fadeOut {
+ from {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ }
+}
+
+@keyframes scaleIn {
+ from {
+ scale: 0.8;
+ }
+ to {
+ scale: 1;
+ }
+}
+
+@keyframes scaleOut {
+ to {
+ scale: 0.8;
+ }
+}
diff --git a/packages/svelte/.storybook/styles/field.css b/packages/svelte/.storybook/styles/field.css
new file mode 100644
index 0000000000..313c827ce2
--- /dev/null
+++ b/packages/svelte/.storybook/styles/field.css
@@ -0,0 +1,7 @@
+[data-scope='field'][data-part='root'] {
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+ align-items: start;
+ }
+
\ No newline at end of file
diff --git a/packages/svelte/.storybook/styles/file-upload.css b/packages/svelte/.storybook/styles/file-upload.css
new file mode 100644
index 0000000000..fae6da9e70
--- /dev/null
+++ b/packages/svelte/.storybook/styles/file-upload.css
@@ -0,0 +1,60 @@
+[data-scope='file-upload'][data-part='root'] {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ width: 80%;
+}
+
+[data-scope='file-upload'][data-part='dropzone'] {
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ gap: 0.5rem;
+ border-width: 2px;
+ border-style: dashed;
+ padding-top: var(--space-8);
+ padding-bottom: var(--space-8);
+ padding-inline-start: var(--space-2);
+ padding-inline-end: var(--space-2);
+}
+
+[data-scope='file-upload'][data-part='trigger'] {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ text-align: start;
+ cursor: pointer;
+ font-weight: var(--fontWeights-medium);
+ padding-inline-start: var(--space-4);
+ padding-inline-end: var(--space-4);
+ padding-top: var(--space-1);
+ padding-bottom: var(--space-1);
+ background: var(--colors-bg-primary-subtle);
+ color: var(--colors-white);
+}
+
+[data-scope='file-upload'][data-part='item-group'] {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+}
+
+[data-scope='file-upload'][data-part='item'] {
+ display: flex;
+ align-items: center;
+ flex-direction: row;
+ gap: 0.5rem;
+ padding-inline-start: var(--space-3);
+ padding-inline-end: var(--space-3);
+ padding-top: var(--space-2);
+ padding-bottom: var(--space-2);
+ background: var(--colors-bg-subtle);
+ border-width: 1px;
+}
+
+[data-scope='file-upload'][data-part='item-preview-image'] {
+ aspect-ratio: 1;
+ object-fit: cover;
+ width: 40px;
+ height: 40px;
+}
diff --git a/packages/svelte/.storybook/styles/hover-card.css b/packages/svelte/.storybook/styles/hover-card.css
new file mode 100644
index 0000000000..1eea396239
--- /dev/null
+++ b/packages/svelte/.storybook/styles/hover-card.css
@@ -0,0 +1,45 @@
+[data-scope='hover-card'][data-part='trigger'] {
+ text-decoration: none;
+}
+
+[data-scope='hover-card'][data-part='content'] {
+ padding: 0.5rem;
+ border: 1px solid lightgray;
+ background: white;
+ filter: drop-shadow(0px 4px 6px rgba(0, 0, 0, 0.15));
+}
+
+[data-scope='hover-card'][data-part='arrow'] {
+ --arrow-background: white;
+ --arrow-size: 8px;
+}
+
+[data-scope='hover-card'][data-part='content'][data-state='open'] {
+ animation: fadeIn 0.25s ease-out;
+}
+
+[data-scope='hover-card'][data-part='content'][data-state='closed'] {
+ animation: fadeOut 0.2s ease-in;
+}
+
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ transform: translateY(-10px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@keyframes fadeOut {
+ from {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ to {
+ opacity: 0;
+ transform: translateY(-10px);
+ }
+}
diff --git a/packages/svelte/.storybook/styles/menu.css b/packages/svelte/.storybook/styles/menu.css
new file mode 100644
index 0000000000..7cd5cf2db6
--- /dev/null
+++ b/packages/svelte/.storybook/styles/menu.css
@@ -0,0 +1,57 @@
+[data-scope="menu"][data-part="content"] {
+ margin: 0;
+ width: 160px;
+ background-color: white;
+ border-radius: 6px;
+ padding: 5px;
+ border: 1px solid lightgray;
+ list-style-type: none;
+}
+[data-scope="menu"][data-part="trigger"] {
+ display: flex;
+ gap: 4px;
+}
+
+[data-scope='menu'][data-part='indicator'][data-state='open'] {
+ rotate: 90deg;
+}
+
+[data-scope="menu"][data-part="item"],
+[data-scope="menu"][data-part="trigger-item"],
+[data-scope="menu"][data-part="option-item"] {
+ all: unset;
+ font-size: 14px;
+ line-height: 1;
+ color: rgb(87, 70, 175);
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ height: 25px;
+ position: relative;
+ user-select: none;
+ border-radius: 3px;
+ padding: 0px 5px;
+}
+
+[data-scope="menu"][data-part="item"][data-highlighted],
+[data-scope="menu"][data-part="trigger-item"][data-highlighted],
+[data-scope="menu"][data-part="option-item"][data-highlighted] {
+ outline: none;
+ background-color: rgb(110, 86, 207);
+ color: rgb(253, 252, 254);
+}
+
+[data-scope="menu"][data-part="item"][data-disabled],
+[data-scope="menu"][data-part="trigger-item"][data-disabled],
+[data-scope="menu"][data-part="option-item"][data-disabled] {
+ opacity: 0.4;
+}
+
+[data-scope="menu"][data-part="context-trigger"] {
+ border: 2px dashed blue;
+ border-radius: 4px;
+ font-size: 15px;
+ padding-block: 40px;
+ width: 300px;
+ text-align: center;
+}
diff --git a/packages/svelte/.storybook/styles/number-input.css b/packages/svelte/.storybook/styles/number-input.css
new file mode 100644
index 0000000000..5310b958fd
--- /dev/null
+++ b/packages/svelte/.storybook/styles/number-input.css
@@ -0,0 +1,5 @@
+[data-scope='number-input'][data-part='scrubber'] {
+ width: 16px;
+ height: 16px;
+ background-color: red;
+}
diff --git a/packages/svelte/.storybook/styles/pagination.css b/packages/svelte/.storybook/styles/pagination.css
new file mode 100644
index 0000000000..d9b66bda37
--- /dev/null
+++ b/packages/svelte/.storybook/styles/pagination.css
@@ -0,0 +1,9 @@
+[data-scope='pagination'][data-part='item'][data-selected] {
+ background-color: aqua;
+}
+
+[data-scope='pagination'][data-part='prev-item'][data-disabled],
+[data-scope='pagination'][data-part='next-item'][data-disabled] {
+ cursor: not-allowed;
+ opacity: 0.4;
+}
diff --git a/packages/svelte/.storybook/styles/pin-input.css b/packages/svelte/.storybook/styles/pin-input.css
new file mode 100644
index 0000000000..8577a8445c
--- /dev/null
+++ b/packages/svelte/.storybook/styles/pin-input.css
@@ -0,0 +1,18 @@
+[data-scope='pin-input'][data-part='control'] {
+ width: 300px;
+ display: flex;
+ margin-bottom: 12px;
+ gap: 12px;
+}
+
+[data-scope='pin-input'][data-part='label'] {
+ display: block;
+ margin-bottom: 8px;
+}
+
+[data-scope='pin-input'][data-part='input'] {
+ width: 48px;
+ height: 48px;
+ text-align: center;
+ font-size: 24px;
+}
diff --git a/packages/svelte/.storybook/styles/popover.css b/packages/svelte/.storybook/styles/popover.css
new file mode 100644
index 0000000000..c2f0cce285
--- /dev/null
+++ b/packages/svelte/.storybook/styles/popover.css
@@ -0,0 +1,56 @@
+[data-scope='popover'][data-part='content'] {
+ background: white;
+ padding: 16px;
+ border-radius: 4px;
+ position: relative;
+ filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.2));
+ min-width: 240px;
+}
+[data-scope='popover'][data-part='content'][data-state='open'] {
+ animation: fadeIn 0.25s ease-out;
+}
+
+[data-scope='popover'][data-part='content'][data-state='closed'] {
+ animation: fadeOut 0.2s ease-in;
+}
+
+[data-scope='popover'][data-part='title'] {
+ font-weight: bold;
+}
+
+[data-scope='popover'][data-part='close-trigger'] {
+ position: absolute;
+ right: 4px;
+ top: 4px;
+}
+
+[data-scope='popover'][data-part='anchor'] {
+ display: inline;
+ margin-left: 200px;
+}
+
+[data-scope='popover'][data-part='indicator'][data-state='open'] {
+ rotate: 90deg;
+}
+
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ transform: translateY(-10px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@keyframes fadeOut {
+ from {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ to {
+ opacity: 0;
+ transform: translateY(-10px);
+ }
+}
diff --git a/packages/svelte/.storybook/styles/presence.css b/packages/svelte/.storybook/styles/presence.css
new file mode 100644
index 0000000000..800edd8ba9
--- /dev/null
+++ b/packages/svelte/.storybook/styles/presence.css
@@ -0,0 +1,32 @@
+[data-scope='presence'][data-part='root'] {
+ background-color: brown;
+ color: white;
+ padding: 24px;
+ max-width: fit-content;
+}
+
+[data-scope='presence'][data-part='root'][data-state='open'] {
+ animation: fadeIn 0.25s ease-out;
+}
+
+[data-scope='presence'][data-part='root'][data-state='closed'] {
+ animation: fadeOut 0.5s ease-in;
+}
+
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ scale: 0.8;
+ }
+ to {
+ opacity: 1;
+ scale: 1;
+ }
+}
+
+@keyframes fadeOut {
+ to {
+ opacity: 0;
+ scale: 0.8;
+ }
+}
diff --git a/packages/svelte/.storybook/styles/progress.css b/packages/svelte/.storybook/styles/progress.css
new file mode 100644
index 0000000000..04c753851b
--- /dev/null
+++ b/packages/svelte/.storybook/styles/progress.css
@@ -0,0 +1,105 @@
+[data-scope='progress'][data-part='root'] {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
+
+/* We should consider adding some div grouping track and range for vertical prop like in slider */
+[data-scope='progress'][data-part='control'] {
+ position: relative;
+ align-items: center;
+ display: flex;
+}
+
+[data-scope='progress'][data-part='control'][data-orientation='vertical'] {
+ height: 20rem;
+ width: 8px;
+ flex-direction: column;
+}
+
+[data-scope='progress'][data-part='track'] {
+ background: silver;
+ height: 8px;
+ flex: 1;
+}
+
+[data-scope='progress'][data-part='track'][data-orientation='horizontal'] {
+ height: 8px;
+}
+
+[data-scope='progress'][data-part='track'][data-orientation='vertical'] {
+ width: 8px;
+}
+
+[data-scope='progress'][data-part='range'] {
+ background: orange;
+}
+
+[data-scope='progress'][data-part='range'][data-orientation='horizontal'] {
+ height: inherit;
+}
+
+[data-scope='progress'][data-part='range'][data-orientation='vertical'] {
+ width: inherit;
+}
+
+[data-scope='progress'][data-part='range'][data-state='indeterminate'] {
+ width: 210%;
+ background: orange;
+ animation: 1s cubic-bezier(0.694, 0.0482, 0.335, 1) 0s infinite normal none running
+ linearAnimation;
+}
+
+@keyframes linearAnimation {
+ from {
+ transform: scaleX(1) translateX(var(--translate-x));
+ }
+ to {
+ transform: scaleX(0) translateX(var(--translate-x));
+ }
+}
+
+[data-scope='progress'][data-part='circle'] {
+ --size: 100px;
+ --thickness: 10px;
+}
+
+[data-scope='progress'][data-part='circle'][data-state='indeterminate'] {
+ width: 210%;
+ background: orange;
+ animation: spin 2s linear infinite;
+}
+
+[data-scope='progress'][data-part='circle-track'] {
+ stroke: silver;
+}
+
+[data-scope='progress'][data-part='circle-range'] {
+ stroke: orange;
+}
+
+[data-scope='progress'][data-part='circle-range'][data-state='indeterminate'] {
+ width: 210%;
+ background: orange;
+ animation: circleAnimation 1.5s ease-in-out infinite;
+}
+
+@keyframes spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+@keyframes circleAnimation {
+ from {
+ stroke-dasharray: 1, 400;
+ stroke-dashoffset: 0;
+ }
+ to {
+ stroke-dasharray: 400, 400;
+ stroke-dashoffset: -260;
+ }
+}
diff --git a/packages/svelte/.storybook/styles/qr-code.css b/packages/svelte/.storybook/styles/qr-code.css
new file mode 100644
index 0000000000..a368b18545
--- /dev/null
+++ b/packages/svelte/.storybook/styles/qr-code.css
@@ -0,0 +1,26 @@
+[data-scope="qr-code"][data-part="root"] {
+ width: fit-content;
+}
+
+[data-scope="qr-code"][data-part="frame"] {
+ width: 120px;
+ height: 120px;
+ background-color: white;
+ }
+
+ [data-scope="qr-code"][data-part="pattern"] {
+ fill: black;
+ }
+
+ [data-scope="qr-code"][data-part="overlay"] {
+ width: 32px;
+ height: 32px;
+ outline: 1px solid white;
+ background-color: white;
+
+ & img {
+ width: 100%;
+ height: 100%;
+ }
+ }
+
\ No newline at end of file
diff --git a/packages/svelte/.storybook/styles/radio-group.css b/packages/svelte/.storybook/styles/radio-group.css
new file mode 100644
index 0000000000..117762e3c2
--- /dev/null
+++ b/packages/svelte/.storybook/styles/radio-group.css
@@ -0,0 +1,73 @@
+[data-scope='radio-group'][data-part='root'] {
+ position: relative;
+ display: flex;
+ align-items: center;
+ gap: 16px;
+}
+
+[data-scope='radio-group'][data-part='item'] {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ position: relative;
+ z-index: 2;
+}
+
+[data-scope='radio-group'][data-part='item'][data-disabled] {
+ cursor: not-allowed;
+}
+
+[data-scope='radio-group'][data-part='item-label'][data-disabled] {
+ opacity: 0.4;
+}
+
+[data-scope='radio-group'][data-part='item-control'] {
+ height: 20px;
+ width: 20px;
+ background-color: #eee;
+ border: solid 2px grey;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+[data-scope='radio-group'][data-part='item-control'][data-focus] {
+ outline: 2px solid royalblue;
+}
+
+[data-scope='radio-group'][data-part='item-control'][data-hover] {
+ background-color: #ccc;
+}
+
+[data-scope='radio-group'][data-part='item-control'][data-state='checked'] {
+ background-color: #2196f3;
+ border-color: #2196f3;
+}
+
+[data-scope='radio-group'][data-part='item-control'][data-state='checked']::after {
+ display: initial;
+}
+
+[data-scope='radio-group'][data-part='item-control']::after {
+ content: '';
+ display: none;
+ width: 4px;
+ height: 9px;
+ border: solid white;
+ border-width: 0 2px 2px 0;
+ transform: rotate(45deg);
+ position: relative;
+ top: -1px;
+}
+
+[data-scope='radio-group'][data-part='indicator'] {
+ height: 4px;
+ background-color: red;
+ z-index: 1;
+ border-radius: 0.25rem;
+ box-shadow:
+ rgba(0, 0, 0, 0.05) 0px 0.0625rem 0.1875rem,
+ rgba(0, 0, 0, 0.1) 0px 0.0625rem 0.125rem;
+ background-color: rgb(255, 255, 255);
+}
diff --git a/packages/svelte/.storybook/styles/segment-group.css b/packages/svelte/.storybook/styles/segment-group.css
new file mode 100644
index 0000000000..98a93c2008
--- /dev/null
+++ b/packages/svelte/.storybook/styles/segment-group.css
@@ -0,0 +1,82 @@
+[data-scope='segment-group'][data-part='root'] {
+ position: relative;
+ display: flex;
+ align-items: center;
+ gap: 16px;
+ width: fit-content;
+ padding: 4px;
+ background-color: #f1f3f5;
+ border-radius: 4px;
+ gap: 8px;
+}
+
+[data-scope='segment-group'][data-part='item'] {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ position: relative;
+ z-index: 2;
+ padding-left: 0;
+ padding: 8px;
+ width: 100%;
+ text-align: center;
+}
+
+[data-scope='segment-group'][data-part='item'][data-disabled] {
+ cursor: not-allowed;
+}
+
+[data-scope='segment-group'][data-part='item-text'][data-disabled] {
+ opacity: 0.4;
+}
+
+[data-scope='segment-group'][data-part='item-control'] {
+ height: 20px;
+ width: 20px;
+ background-color: #eee;
+ border: solid 2px grey;
+ border-radius: 50%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+[data-scope='segment-group'][data-part='item-control'][data-focus] {
+ outline: 2px solid royalblue;
+}
+
+[data-scope='segment-group'][data-part='item-control'][data-hover] {
+ background-color: #ccc;
+}
+
+[data-scope='segment-group'][data-part='item-control'][data-state='checked'] {
+ background-color: #2196f3;
+ border-color: #2196f3;
+}
+
+[data-scope='segment-group'][data-part='item-control'][data-state='checked']::after {
+ display: initial;
+}
+
+[data-scope='segment-group'][data-part='item-control']::after {
+ content: '';
+ display: none;
+ width: 4px;
+ height: 9px;
+ border: solid white;
+ border-width: 0 2px 2px 0;
+ transform: rotate(45deg);
+ position: relative;
+ top: -1px;
+}
+
+[data-scope='segment-group'][data-part='indicator'] {
+ height: 4px;
+ background-color: red;
+ z-index: 1;
+ border-radius: 0.25rem;
+ box-shadow:
+ rgba(0, 0, 0, 0.05) 0px 0.0625rem 0.1875rem,
+ rgba(0, 0, 0, 0.1) 0px 0.0625rem 0.125rem;
+ background-color: rgb(255, 255, 255);
+}
diff --git a/packages/svelte/.storybook/styles/select.css b/packages/svelte/.storybook/styles/select.css
new file mode 100644
index 0000000000..c17e2940a7
--- /dev/null
+++ b/packages/svelte/.storybook/styles/select.css
@@ -0,0 +1,59 @@
+[data-scope='select'][data-part='content'][data-state='open'] {
+ animation: fadeIn 0.25s ease-out;
+}
+
+[data-scope='select'][data-part='content'][data-state='closed'] {
+ animation: fadeOut 0.2s ease-in;
+}
+
+[data-scope='select'][data-part='content'] {
+ border: 1px solid gainsboro;
+ background: white;
+ z-index: 1;
+ padding: 12px;
+}
+
+[data-scope='select'][data-part='item-group-label'] {
+ font-weight: bold;
+}
+
+[data-scope='select'][data-part='item'] {
+ display: flex;
+ justify-content: space-between;
+}
+
+[data-scope='select'][data-part='item'][data-disabled] {
+ color: silver;
+}
+
+[data-scope='select'][data-part='trigger'] {
+ display: inline-flex;
+ gap: 8px;
+}
+
+[data-scope='select'][data-part='trigger'] svg {
+ width: 1em;
+ height: 1em;
+}
+
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ transform: translateY(-10px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@keyframes fadeOut {
+ from {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ to {
+ opacity: 0;
+ transform: translateY(-10px);
+ }
+}
diff --git a/packages/svelte/.storybook/styles/signature-pad.css b/packages/svelte/.storybook/styles/signature-pad.css
new file mode 100644
index 0000000000..51d70e6d74
--- /dev/null
+++ b/packages/svelte/.storybook/styles/signature-pad.css
@@ -0,0 +1,36 @@
+[data-scope=signature-pad][data-part=root] {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ max-width: 400px;
+ width:100%;
+}
+
+[data-scope=signature-pad][data-part=label] {
+ display: inline-block;
+ margin-block-end: 8px;
+}
+
+[data-scope="signature-pad"][data-part="control"] {
+ height: 120px;
+ background-color: #efefef;
+ border-radius: 8px;
+}
+
+[data-scope=signature-pad][data-part=guide] {
+ position: absolute;
+ bottom: 12%;
+ left: 8px;
+ right: 8px;
+ border-bottom: 1px dashed #2f2f2f;
+}
+
+[data-scope=signature-pad][data-part=clear-trigger] {
+ position: absolute;
+ top: 8px;
+ right: 8px;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 1rem;
+}
\ No newline at end of file
diff --git a/packages/svelte/.storybook/styles/slider.css b/packages/svelte/.storybook/styles/slider.css
new file mode 100644
index 0000000000..dd9c1a9c83
--- /dev/null
+++ b/packages/svelte/.storybook/styles/slider.css
@@ -0,0 +1,129 @@
+.slider > * {
+ width: 100%;
+}
+
+[data-scope="slider"][data-part="root"] {
+ max-width: 320px;
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+}
+
+[data-scope="slider"][data-part="root"][data-orientation="vertical"] {
+ height: 240px;
+}
+
+[data-scope="slider"][data-part="control"] {
+ --slider-thumb-size: 20px;
+ --slider-track-height: 4px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+}
+
+[data-scope="slider"][data-part="control"][data-orientation="horizontal"] {
+ height: var(--slider-thumb-size);
+}
+
+[data-scope="slider"][data-part="control"][data-orientation="vertical"] {
+ width: var(--slider-thumb-size);
+}
+
+[data-scope="slider"][data-part="thumb"] {
+ all: unset;
+ width: var(--slider-thumb-size);
+ height: var(--slider-thumb-size);
+ border-radius: 999px;
+ background: white;
+ box-shadow: rgba(0, 0, 0, 0.14) 0px 2px 10px;
+}
+
+[data-scope="slider"][data-part="thumb"]:focus-visible {
+ box-shadow: rgb(0 0 0 / 22%) 0px 0px 0px 5px;
+}
+
+[data-scope="slider"][data-part="thumb"]:hover:not([data-disabled]) {
+ background-color: rgb(245, 242, 255);
+}
+
+[data-scope="slider"][data-part="thumb"][data-disabled] {
+ background-color: lightgray;
+}
+
+[data-scope="slider"] .control-area {
+ margin-top: 12px;
+ display: flex;
+}
+
+.slider [data-orientation="horizontal"] .control-area {
+ flex-direction: column;
+ width: 100%;
+}
+
+.slider [data-orientation="vertical"] .control-area {
+ flex-direction: row;
+ height: 100%;
+}
+
+[data-scope="slider"][data-part="track"] {
+ background: rgba(0, 0, 0, 0.2);
+ border-radius: 9999px;
+}
+
+[data-scope="slider"][data-part="track"][data-orientation="horizontal"] {
+ height: var(--slider-track-height);
+ width: 100%;
+}
+
+[data-scope="slider"][data-part="track"][data-orientation="vertical"] {
+ height: 100%;
+ width: var(--slider-track-height);
+}
+
+[data-scope="slider"][data-part="range"] {
+ background: magenta;
+ border-radius: inherit;
+}
+
+[data-scope="slider"][data-part="range"][data-disabled] {
+ background: rgba(0, 0, 0, 0.4);
+}
+
+[data-scope="slider"][data-part="range"][data-orientation="horizontal"] {
+ height: 100%;
+}
+
+[data-scope="slider"][data-part="range"][data-orientation="vertical"] {
+ width: 100%;
+}
+
+[data-scope="slider"][data-part="value-text"] {
+ margin-inline-start: 12px;
+}
+
+[data-scope="slider"][data-part="marker-group"][data-orientation="vertical"] {
+ height: 100%;
+}
+
+[data-scope="slider"][data-part="marker"] {
+ color: lightgray;
+}
+
+[data-scope="slider"][data-part="marker"]:is([data-state="under-value"], [data-state="at-value"]) {
+ color: red;
+}
+
+[data-scope="slider"][data-part="dragging-indicator"] {
+ background: magenta;
+ border-radius: 4px;
+ padding: 2px 4px;
+ color: white;
+ &[data-orientation="horizontal"] {
+ top: calc(var(--slider-thumb-size) + 8px);
+ }
+
+ &[data-orientation="vertical"] {
+ left: calc(var(--slider-thumb-size) + 8px);
+ }
+}
diff --git a/packages/svelte/.storybook/styles/splitter.css b/packages/svelte/.storybook/styles/splitter.css
new file mode 100644
index 0000000000..0246a07d8c
--- /dev/null
+++ b/packages/svelte/.storybook/styles/splitter.css
@@ -0,0 +1,27 @@
+[data-scope='splitter'][data-part='root'] {
+ gap: 4px;
+}
+
+[data-scope='splitter'][data-part='root'][data-orientation='horizontal'] {
+ min-height: 300px;
+}
+
+[data-scope='splitter'][data-part='root'][data-orientation='vertical'] {
+ min-height: 300px;
+}
+
+[data-scope='splitter'][data-part='panel'] {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: 1px solid lightgray;
+ overflow: auto;
+}
+
+[data-scope='splitter'][data-part='panel']:has([data-scope='splitter'][data-part='panel']) {
+ border: none;
+}
+
+[data-scope='splitter'][data-part='resize-trigger'][data-orientation='vertical'] {
+ min-height: 12px;
+}
diff --git a/packages/svelte/.storybook/styles/steps.css b/packages/svelte/.storybook/styles/steps.css
new file mode 100644
index 0000000000..9db55611b7
--- /dev/null
+++ b/packages/svelte/.storybook/styles/steps.css
@@ -0,0 +1,119 @@
+[data-scope="steps"][data-part="root"] {
+ width: 100%;
+ max-width: 400px;
+ display: flex;
+ gap: 16px;
+
+ &[data-orientation="vertical"] {
+ flex-direction: row;
+ }
+ &[data-orientation="horizontal"] {
+ flex-direction: column;
+ }
+ }
+
+ [data-scope="steps"][data-part="list"] {
+ display: flex;
+ justify-content: space-between;
+ --steps-gutter: 12px;
+ --steps-size: 24px;
+ --steps-icon-size: 20px;
+
+ &[data-orientation="vertical"] {
+ flex-direction: column;
+ align-items: flex-start;
+ }
+
+ &[data-orientation="horizontal"] {
+ flex-direction: row;
+ align-items: center;
+ }
+ }
+
+ [data-scope="steps"][data-part="separator"] {
+ flex: 1;
+ background-color: gray;
+
+ &[data-orientation="vertical"] {
+ position: absolute;
+ width: 2px;
+ height: 100%;
+ max-height: calc(100% - var(--steps-size) - var(--steps-gutter) * 2);
+ top: calc(var(--steps-size) + var(--steps-gutter));
+ inset-inline-start: calc(var(--steps-size) / 2 - 1px);
+ }
+
+ &[data-orientation="horizontal"] {
+ width: 100%;
+ height: 2px;
+ margin-inline: var(--steps-gutter);
+ }
+
+ &[data-complete] {
+ background-color: blue;
+ }
+ }
+
+ [data-scope="steps"][data-part="indicator"] {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ flex-shrink: 0;
+ border-radius: 9999px;
+ font-weight: 600;
+ width: var(--steps-size);
+ height: var(--steps-size);
+
+ & svg {
+ flex-shrink: 0;
+ width: var(--steps-icon-size);
+ height: var(--steps-icon-size);
+ }
+
+ &[data-incomplete] {
+ border-width: 2px;
+ }
+
+ &[data-current] {
+ background-color: lightgray;
+ border-width: 2px;
+ border-color: blue;
+ color: darkblue;
+ }
+
+ &[data-complete] {
+ background-color: blue;
+ color: white;
+ }
+ }
+
+ [data-scope="steps"][data-part="item"] {
+ position: relative;
+ display: flex;
+ flex: 1 0 0;
+
+ &:last-of-type {
+ flex: initial;
+
+ & [data-part="separator"] {
+ display: none;
+ }
+ }
+
+ &[data-orientation="vertical"] {
+ align-items: flex-start;
+ }
+
+ &[data-orientation="horizontal"] {
+ align-items: center;
+ }
+ }
+
+ [data-scope="steps"][data-part="trigger"] {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ text-align: start;
+ border-radius: 5px;
+ }
+
\ No newline at end of file
diff --git a/packages/svelte/.storybook/styles/switch.css b/packages/svelte/.storybook/styles/switch.css
new file mode 100644
index 0000000000..10204f389b
--- /dev/null
+++ b/packages/svelte/.storybook/styles/switch.css
@@ -0,0 +1,84 @@
+[data-scope='switch'][data-part='root'] {
+ display: flex;
+ align-items: center;
+ position: relative;
+ width: fit-content;
+
+ --switch-track-diff: calc(var(--switch-track-width) - var(--switch-track-height));
+ --switch-thumb-x: var(--switch-track-diff);
+ --switch-track-width: 1.875rem;
+ --switch-track-height: 1rem;
+}
+
+[data-scope='switch'][data-part='control'] {
+ display: inline-flex;
+ flex-shrink: 0;
+ -webkit-box-pack: start;
+ justify-content: flex-start;
+ box-sizing: content-box;
+ cursor: pointer;
+ border-radius: 9999px;
+ padding: 0.125rem;
+ width: var(--switch-track-width);
+ height: var(--switch-track-height);
+ transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow,
+ transform;
+ transition-duration: 150ms;
+
+ --switch-bg: #cbd5e0;
+ background: var(--switch-bg);
+}
+
+[data-scope='switch'][data-part='control'][data-state='checked'] {
+ --switch-bg: #3182ce;
+}
+
+[data-scope='switch'][data-part='control'][data-focus] {
+ box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.6);
+}
+
+[data-scope='switch'][data-part='control'][data-disabled] {
+ opacity: 0.4;
+ cursor: not-allowed;
+}
+
+[data-scope='switch'][data-part='thumb'] {
+ background: white;
+ transition-property: transform;
+ transition-duration: 200ms;
+ border-radius: inherit;
+ width: var(--switch-track-height);
+ height: var(--switch-track-height);
+ position: relative;
+}
+
+[data-scope='switch'][data-part='thumb']:before {
+ transition: background-color 0.2s ease-in-out;
+ position: absolute;
+ --thumb-size: calc(var(--switch-track-height) + 0.7rem);
+ height: var(--thumb-size);
+ width: var(--thumb-size);
+ background-color: transparent;
+ content: '';
+ z-index: 1;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ border-radius: inherit;
+}
+
+[data-scope='switch'][data-part='thumb'][data-hover]:before {
+ background-color: rgba(0, 0, 0, 0.048);
+}
+[data-scope='switch'][data-part='thumb'][data-hover][data-state='checked']:before {
+ background-color: rgba(144, 202, 249, 0.295);
+}
+
+[data-scope='switch'][data-part='thumb'][data-state='checked'] {
+ transform: translateX(var(--switch-thumb-x));
+}
+
+[data-scope='switch'][data-part='label'] {
+ user-select: none;
+ margin-inline-start: 0.5rem;
+}
diff --git a/packages/svelte/.storybook/styles/tabs.css b/packages/svelte/.storybook/styles/tabs.css
new file mode 100644
index 0000000000..c8be01fd32
--- /dev/null
+++ b/packages/svelte/.storybook/styles/tabs.css
@@ -0,0 +1,123 @@
+[data-scope='tabs'][data-part='root'] {
+ max-width: 20em;
+}
+
+[data-scope='tabs'][data-part='root'][data-orientation='vertical'] {
+ display: flex;
+}
+
+[data-scope='tabs'][data-part='list'] {
+ margin: 0 0 -0.1em;
+ overflow: visible;
+}
+
+[data-scope='tabs'][data-part='list'][data-orientation='vertical'] {
+ display: flex;
+ flex-direction: column;
+}
+
+[data-scope='tabs'][data-part='trigger'] {
+ position: relative;
+ margin: 0;
+ padding: 0.3em 0.5em 0.4em;
+ border: 1px solid hsl(219, 1%, 72%);
+ border-radius: 0.2em 0.2em 0 0;
+ box-shadow: 0 0 0.2em hsl(219, 1%, 72%);
+ overflow: visible;
+ font-size: inherit;
+ background: hsl(220, 20%, 94%);
+}
+
+[data-scope='tabs'][data-part='trigger']:hover,
+[data-scope='tabs'][data-part='trigger']:focus,
+[data-scope='tabs'][data-part='trigger']:active {
+ outline: 0;
+ border-radius: 0;
+ color: inherit;
+}
+
+[data-scope='tabs'][data-part='trigger'][data-state='active'] {
+ border-radius: 0;
+ background: hsl(220, 43%, 99%);
+ outline: 0;
+}
+
+[data-scope='tabs'][data-part='trigger'][data-state='active']:not(:focus):not(:hover)::before {
+ border-top: 5px solid hsl(218, 96%, 48%);
+}
+
+[data-scope='tabs'][data-part='trigger'][data-state='active']::after {
+ position: absolute;
+ z-index: 3;
+ bottom: -1px;
+ right: 0;
+ left: 0;
+ height: 0.3em;
+ background: hsl(220, 43%, 99%);
+ box-shadow: none;
+ content: '';
+}
+
+[data-scope='tabs'][data-part='trigger']:hover::before,
+[data-scope='tabs'][data-part='trigger']:focus::before {
+ border-color: hsl(20, 96%, 48%);
+}
+
+[data-scope='tabs'][data-part='trigger']:hover::before,
+[data-scope='tabs'][data-part='trigger']:focus::before,
+[data-scope='tabs'][data-part='trigger'][data-state='active']::before {
+ position: absolute;
+ bottom: 100%;
+ right: -1px;
+ left: -1px;
+ border-radius: 0.2em 0.2em 0 0;
+ border-top: 3px solid hsl(20, 96%, 48%);
+ content: '';
+}
+
+[data-scope='tabs'][data-part='content'] {
+ position: relative;
+ z-index: 2;
+ padding: 0.5em 0.5em 0.7em;
+ border: 1px solid hsl(219, 1%, 72%);
+ border-radius: 0 0.2em 0.2em 0.2em;
+ box-shadow: 0 0 0.2em hsl(219, 1%, 72%);
+ background: hsl(220, 43%, 99%);
+}
+
+[data-scope='tabs'][data-part='content'] p {
+ margin: 0;
+}
+
+[data-scope='tabs'][data-part='content'] * + p {
+ margin-top: 1em;
+}
+
+[data-scope='tabs'][data-part='content']:focus {
+ border-color: hsl(20, 96%, 48%);
+ box-shadow: 0 0 0.2em hsl(20, 96%, 48%);
+ outline: 0;
+}
+
+[data-scope='tabs'][data-part='content']:focus::after {
+ position: absolute;
+ bottom: 0;
+ right: -1px;
+ left: -1px;
+ border-bottom: 3px solid hsl(20, 96%, 48%);
+ border-radius: 0 0 0.2em 0.2em;
+ content: '';
+}
+
+[data-scope='tabs'][data-part='indicator'] {
+ background-color: red;
+ z-index: 10;
+}
+
+[data-scope='tabs'][data-part='indicator'][data-orientation='horizontal'] {
+ height: 4px;
+}
+
+[data-scope='tabs'][data-part='indicator'][data-orientation='vertical'] {
+ width: 4px;
+}
diff --git a/packages/svelte/.storybook/styles/tags-input.css b/packages/svelte/.storybook/styles/tags-input.css
new file mode 100644
index 0000000000..aab9433792
--- /dev/null
+++ b/packages/svelte/.storybook/styles/tags-input.css
@@ -0,0 +1,14 @@
+[data-scope='tags-input'][data-part='item-preview'] {
+ border-radius: 4px;
+ padding: 0 8px;
+ margin-right: 8px;
+}
+
+[data-scope='tags-input'][data-part='control'] {
+ display: flex;
+ gap: 2px;
+}
+
+[data-scope='tags-input'][data-part='item-preview'][data-highlighted] {
+ background-color: aqua;
+}
diff --git a/packages/svelte/.storybook/styles/time-picker.css b/packages/svelte/.storybook/styles/time-picker.css
new file mode 100644
index 0000000000..e542980db9
--- /dev/null
+++ b/packages/svelte/.storybook/styles/time-picker.css
@@ -0,0 +1,61 @@
+[hidden] {
+ display: none !important;
+}
+
+[data-scope="time-picker"][data-part="content"] {
+ border: 1px solid gray;
+ background: white;
+ border-radius: 8px;
+ overflow: hidden;
+ display: flex;
+ max-height: 200px;
+}
+
+[data-scope="time-picker"][data-part="column"] {
+ display: flex;
+ gap: 4px;
+ flex-direction: column;
+ overflow-y: scroll;
+ padding: 4px;
+
+ &[data-focus] {
+ background: rgb(247, 247, 247);
+ }
+
+ /* hide scroll bar */
+ scrollbar-width: none;
+ -ms-overflow-style: none;
+ &::-webkit-scrollbar {
+ display: none;
+ }
+ & + & {
+ border-inline-start: 1px solid rgb(209, 209, 209);
+ }
+}
+
+[data-scope="time-picker"][data-part="spacer"] {
+ display: block;
+ flex-shrink: 0;
+ height: calc(100% - 36px);
+}
+
+[data-scope="time-picker"][data-part="cell"] {
+ background: none;
+ border: none;
+ padding: 8px;
+ border-radius: 4px;
+
+ &[data-now] {
+ background: lightblue;
+ }
+
+ &[data-selected] {
+ background: purple;
+ color: white;
+ }
+
+ &[data-disabled] {
+ opacity: 0.25;
+ cursor: not-allowed;
+ }
+}
diff --git a/packages/svelte/.storybook/styles/timer.css b/packages/svelte/.storybook/styles/timer.css
new file mode 100644
index 0000000000..9998eb13fe
--- /dev/null
+++ b/packages/svelte/.storybook/styles/timer.css
@@ -0,0 +1,26 @@
+[data-scope="timer"][data-part="root"] {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+[data-scope="timer"][data-part="area"] {
+ display: flex;
+ align-items: center;
+}
+
+[data-scope="timer"][data-part="item"] {
+ font-size: 2rem;
+ font-weight: 500;
+}
+
+[data-scope="timer"][data-part="separator"] {
+ font-size: 1rem;
+ font-weight: 500;
+ margin-inline: 0.5rem;
+}
+
+[data-scope="timer"][data-part="control"] {
+ display: flex;
+ gap: 4px;
+}
diff --git a/packages/svelte/.storybook/styles/toast.css b/packages/svelte/.storybook/styles/toast.css
new file mode 100644
index 0000000000..cd406fdf77
--- /dev/null
+++ b/packages/svelte/.storybook/styles/toast.css
@@ -0,0 +1,122 @@
+@keyframes spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+@keyframes shrink {
+ from {
+ transform: scaleX(1);
+ }
+ to {
+ transform: scaleX(0);
+ }
+}
+
+[data-scope="toast"][data-part="root"] {
+ background: white;
+ padding: 8px 12px;
+ box-shadow:
+ 0 3px 10px rgba(0, 0, 0, 0.1),
+ 0 3px 3px rgba(0, 0, 0, 0.05);
+ width: 360px;
+ overflow-wrap: anywhere;
+ translate: var(--x) var(--y);
+ scale: var(--scale);
+ z-index: var(--z-index);
+ height: var(--height);
+ opacity: var(--opacity);
+
+ will-change: translate, opacity, scale;
+ transition:
+ translate 400ms,
+ scale 400ms,
+ opacity 400ms,
+ height 400ms,
+ box-shadow 200ms;
+ transition-timing-function: cubic-bezier(0.21, 1.02, 0.73, 1);
+
+ &[data-state="closed"] {
+ transition:
+ translate 400ms,
+ scale 400ms,
+ opacity 200ms;
+ transition-timing-function: cubic-bezier(0.06, 0.71, 0.55, 1);
+ }
+}
+
+[data-scope="toast"][data-part="close-trigger"] {
+ position: absolute;
+ right: 8px;
+ top: 8px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 24px;
+ height: 24px;
+ font-size: 18px;
+ padding: 0;
+
+ & svg {
+ width: 1em;
+ height: 1em;
+ }
+}
+
+[data-scope="toast"][data-part="title"] {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+}
+
+[data-scope="toast"][data-part="root"][data-type="error"] {
+ background: red;
+ color: white;
+}
+
+[data-scope="toast"][data-part="root"][data-type="info"] {
+ background: blue;
+ color: white;
+}
+
+[data-scope="toast"][data-part="root"][data-type="warning"] {
+ background: orange;
+}
+
+[data-scope="toast"][data-part="root"][data-type="success"] {
+ background: green;
+ color: white;
+}
+
+[data-scope="toast"] .spinner {
+ animation: spin 1s linear infinite;
+}
+
+[data-scope="toast"][data-part="progressbar"] {
+ height: 4px;
+ background: rgb(116, 116, 116);
+ width: 100%;
+ position: absolute;
+ bottom: 0;
+ inset-inline: 0;
+ animation-name: shrink;
+ animation-fill-mode: forwards;
+}
+
+[data-scope="toast"][data-part="progressbar"][data-type="loading"] {
+ animation-name: none;
+}
+
+@media (max-width: 640px) {
+ [data-scope="toast"][data-part="group"] {
+ width: 100%;
+ }
+
+ [data-scope="toast"][data-part="root"] {
+ inset-inline: 0;
+ width: calc(100% - var(--gap) * 2);
+ }
+}
diff --git a/packages/svelte/.storybook/styles/toggle-group.css b/packages/svelte/.storybook/styles/toggle-group.css
new file mode 100644
index 0000000000..e90bf37b44
--- /dev/null
+++ b/packages/svelte/.storybook/styles/toggle-group.css
@@ -0,0 +1,3 @@
+[data-state='on'] {
+ border-color: blue;
+}
diff --git a/packages/svelte/.storybook/styles/tooltip.css b/packages/svelte/.storybook/styles/tooltip.css
new file mode 100644
index 0000000000..4b862ffc5e
--- /dev/null
+++ b/packages/svelte/.storybook/styles/tooltip.css
@@ -0,0 +1,38 @@
+[data-scope='tooltip'][data-part='content'] {
+ background: black;
+ color: white;
+ padding: 6px 8px;
+ border-radius: 4px;
+ font-size: 14px;
+}
+
+[data-scope='tooltip'][data-part='content'][data-state='open'] {
+ animation: fadeIn 0.5s ease-out;
+}
+
+[data-scope='tooltip'][data-part='content'][data-state='closed'] {
+ animation: fadeOut 0.5s ease-in;
+}
+
+[data-scope='tooltip'][data-part='arrow'] {
+ --arrow-size: 8px;
+ --arrow-background: black;
+}
+
+@keyframes fadeIn {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+@keyframes fadeOut {
+ from {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ }
+}
diff --git a/packages/svelte/.storybook/styles/tree-view.css b/packages/svelte/.storybook/styles/tree-view.css
new file mode 100644
index 0000000000..2e695815c0
--- /dev/null
+++ b/packages/svelte/.storybook/styles/tree-view.css
@@ -0,0 +1,98 @@
+[data-scope="tree-view"][data-part="tree"] {
+ margin-top: 20px;
+ width: 240px;
+}
+
+[data-scope="tree-view"][data-part="item"],
+[data-scope="tree-view"][data-part="branch-control"] {
+ user-select: none;
+ --padding-inline: 16px;
+ padding-inline-start: calc(var(--depth) * var(--padding-inline));
+ padding-inline-end: var(--padding-inline);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ border-radius: 2px;
+ min-height: 32px;
+
+ & svg {
+ width: 16px;
+ height: 16px;
+ opacity: 0.5;
+ }
+
+ &:hover {
+ background: rgb(243, 243, 243);
+ }
+
+ &[data-selected] {
+ background: rgb(226, 226, 226);
+ }
+
+ &:focus {
+ outline: 1px solid rgb(148, 148, 148);
+ outline-offset: -1px;
+ }
+}
+
+[data-scope="tree-view"][data-part="item-text"],
+[data-scope="tree-view"][data-part="branch-text"] {
+ flex: 1;
+}
+
+[data-scope="tree-view"][data-part="branch-content"] {
+ position: relative;
+ isolation: isolate;
+}
+
+[data-scope="tree-view"][data-part="branch-indent-guide"] {
+ position: absolute;
+ content: "";
+ border-left: 1px solid rgb(226, 226, 226);
+ height: 100%;
+ translate: calc(var(--depth) * 1.25rem);
+ z-index: 0;
+}
+
+[data-scope="tree-view"][data-part="branch-indicator"] {
+ display: flex;
+ align-items: center;
+ &[data-state="open"] svg {
+ transform: rotate(90deg);
+ }
+}
+
+@keyframes slideDown {
+ from {
+ opacity: 0.01;
+ height: 0;
+ }
+ to {
+ opacity: 1;
+ height: var(--height);
+ }
+}
+
+@keyframes slideUp {
+ from {
+ opacity: 1;
+ height: var(--height);
+ }
+ to {
+ opacity: 0.01;
+ height: 0;
+ }
+}
+
+[data-scope="tree-view"][data-part="branch-content"] {
+ overflow: hidden;
+ max-width: 400px;
+}
+
+[data-scope="tree-view"][data-part="branch-content"][data-state="open"] {
+ animation: slideDown 250ms cubic-bezier(0, 0, 0.38, 0.9);
+}
+
+[data-scope="tree-view"][data-part="branch-content"][data-state="closed"] {
+ animation: slideUp 200ms cubic-bezier(0, 0, 0.38, 0.9);
+}
diff --git a/packages/svelte/CHANGELOG.md b/packages/svelte/CHANGELOG.md
new file mode 100644
index 0000000000..fd338bec53
--- /dev/null
+++ b/packages/svelte/CHANGELOG.md
@@ -0,0 +1,11 @@
+---
+id: changelog
+title: Changelog
+description: All notable changes will be documented in this file.
+---
+
+## [Unreleased]
+
+### Added
+
+- Added `Avatar` component.
diff --git a/packages/svelte/package.json b/packages/svelte/package.json
index 759c0d8d1a..0174aca797 100644
--- a/packages/svelte/package.json
+++ b/packages/svelte/package.json
@@ -1,44 +1,84 @@
{
"name": "@ark-ui/svelte",
"version": "0.0.1",
- "scripts": {
- "dev": "vite dev",
- "preview": "vite preview",
- "package": "svelte-kit sync && svelte-package && publint",
- "prepublishOnly": "npm run package",
- "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
- "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
- "test": "vitest"
+ "description": "A collection of unstyled, accessible UI components for Svelte",
+ "keywords": ["avatar", "svelte"],
+ "license": "MIT",
+ "homepage": "https://ark-ui.com",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/chakra-ui/ark.git",
+ "directory": "packages/svelte"
},
+ "bugs": {
+ "url": "https://github.com/chakra-ui/ark/issues"
+ },
+ "type": "module",
+ "svelte": "./dist/index.js",
+ "types": "./dist/index.d.ts",
+ "files": ["dist", "!dist/**/*.stories.*", "!dist/**/examples/**", "!dist/**/*.test.*"],
"exports": {
".": {
- "types": "./dist/index.d.ts",
- "svelte": "./dist/index.js"
+ "types": "./src/lib/index.ts",
+ "svelte": "./src/lib/index.ts"
+ },
+ "./*": {
+ "types": "./src/lib/components/*/index.ts",
+ "svelte": "./src/lib/components/*/index.ts"
}
},
- "files": ["dist", "!dist/**/*.test.*", "!dist/**/*.spec.*"],
- "peerDependencies": {
- "svelte": "5.1.3"
+ "scripts": {
+ "build": "svelte-kit sync && svelte-package",
+ "dev": "vite dev",
+ "storybook": "storybook dev -p 6006",
+ "test": "vitest",
+ "test:ci": "vitest --run",
+ "typecheck": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
+ "release-it": "release-it --config ../../release-it.json",
+ "prepack": "clean-package",
+ "postpack": "clean-package restore"
+ },
+ "clean-package": {
+ "replace": {
+ "exports.\\..svelte": "./dist/index.js",
+ "exports.\\..types": "./dist/index.d.ts",
+ "exports.\\./*.svelte": "./dist/components/*/index.js",
+ "exports.\\./*.types": "./dist/components/*/index.d.ts"
+ }
+ },
+ "publishConfig": {
+ "access": "public"
},
+ "sideEffects": false,
"dependencies": {
"@zag-js/avatar": "0.77.1",
"@zag-js/core": "0.77.1",
- "@zag-js/svelte": "0.77.1"
+ "@zag-js/svelte": "0.77.1",
+ "nanoid": "5.0.9"
},
"devDependencies": {
+ "@release-it/keep-a-changelog": "5.0.0",
+ "@storybook/addon-a11y": "8.4.5",
+ "@storybook/addon-essentials": "8.4.5",
+ "@storybook/sveltekit": "8.4.5",
"@sveltejs/adapter-auto": "3.3.1",
"@sveltejs/kit": "2.8.4",
"@sveltejs/package": "2.3.7",
"@sveltejs/vite-plugin-svelte": "4.0.2",
- "publint": "0.2.12",
- "svelte": "5.2.3",
+ "@testing-library/jest-dom": "6.6.3",
+ "@testing-library/svelte": "5.2.6",
+ "@testing-library/user-event": "14.5.2",
+ "clean-package": "2.2.0",
+ "release-it": "17.10.0",
+ "storybook": "8.4.5",
+ "svelte": "5.2.8",
"svelte-check": "4.1.0",
"tslib": "2.8.1",
"typescript": "5.6.3",
"vite": "5.4.11",
"vitest": "2.1.5"
},
- "svelte": "./dist/index.js",
- "types": "./dist/index.d.ts",
- "type": "module"
+ "peerDependencies": {
+ "svelte": ">=5.0.0"
+ }
}
diff --git a/packages/svelte/src/index.test.ts b/packages/svelte/src/index.test.ts
deleted file mode 100644
index 31ae142976..0000000000
--- a/packages/svelte/src/index.test.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { describe, expect, it } from 'vitest'
-
-describe('sum test', () => {
- it('adds 1 + 2 to equal 3', () => {
- expect(1 + 2).toBe(3)
- })
-})
diff --git a/packages/svelte/src/lib/components/avatar/avatar-context.svelte b/packages/svelte/src/lib/components/avatar/avatar-context.svelte
new file mode 100644
index 0000000000..a16494ee51
--- /dev/null
+++ b/packages/svelte/src/lib/components/avatar/avatar-context.svelte
@@ -0,0 +1,17 @@
+
+
+
+
+{@render api?.(avatar)}
diff --git a/packages/svelte/src/lib/components/avatar/avatar-fallback.svelte b/packages/svelte/src/lib/components/avatar/avatar-fallback.svelte
index a398b0c811..f731263ec7 100644
--- a/packages/svelte/src/lib/components/avatar/avatar-fallback.svelte
+++ b/packages/svelte/src/lib/components/avatar/avatar-fallback.svelte
@@ -1,20 +1,18 @@
-
-
+
-
-
-{@render children()}
+
+ {@render props.children?.()}
-
-
\ No newline at end of file
diff --git a/packages/svelte/src/lib/components/avatar/avatar-image.svelte b/packages/svelte/src/lib/components/avatar/avatar-image.svelte
index 76cba371ac..d588f29b7c 100644
--- a/packages/svelte/src/lib/components/avatar/avatar-image.svelte
+++ b/packages/svelte/src/lib/components/avatar/avatar-image.svelte
@@ -1,18 +1,16 @@
-
-
+
-
-
-
-
\ No newline at end of file
+
diff --git a/packages/svelte/src/lib/components/avatar/avatar-root-provider.svelte b/packages/svelte/src/lib/components/avatar/avatar-root-provider.svelte
new file mode 100644
index 0000000000..d91940c2b8
--- /dev/null
+++ b/packages/svelte/src/lib/components/avatar/avatar-root-provider.svelte
@@ -0,0 +1,26 @@
+
+
+
+
+
+ {@render props.children?.()}
+
diff --git a/packages/svelte/src/lib/components/avatar/avatar-root.svelte b/packages/svelte/src/lib/components/avatar/avatar-root.svelte
index b279ce328d..6971cfda60 100644
--- a/packages/svelte/src/lib/components/avatar/avatar-root.svelte
+++ b/packages/svelte/src/lib/components/avatar/avatar-root.svelte
@@ -1,21 +1,28 @@
-
-
-
- {@render children()}
+
+
+ {@render props.children?.()}
diff --git a/packages/svelte/src/lib/components/avatar/avatar.anatomy.ts b/packages/svelte/src/lib/components/avatar/avatar.anatomy.ts
new file mode 100644
index 0000000000..c738affd3f
--- /dev/null
+++ b/packages/svelte/src/lib/components/avatar/avatar.anatomy.ts
@@ -0,0 +1 @@
+export { anatomy as avatarAnatomy } from '@zag-js/avatar'
diff --git a/packages/svelte/src/lib/components/avatar/avatar.stories.ts b/packages/svelte/src/lib/components/avatar/avatar.stories.ts
new file mode 100644
index 0000000000..198153c88e
--- /dev/null
+++ b/packages/svelte/src/lib/components/avatar/avatar.stories.ts
@@ -0,0 +1,28 @@
+import type { Meta } from '@storybook/svelte'
+import BasicExample from './examples/basic.svelte'
+import ContextExample from './examples/context.svelte'
+import RootProviderExample from './examples/root-provider.svelte'
+
+const meta = {
+ title: 'Components / Avatar',
+} as Meta
+
+export default meta
+
+export const Basic = {
+ render: () => ({
+ Component: BasicExample,
+ }),
+}
+
+export const RootProvider = {
+ render: () => ({
+ Component: RootProviderExample,
+ }),
+}
+
+export const Context = {
+ render: () => ({
+ Component: ContextExample,
+ }),
+}
diff --git a/packages/svelte/src/lib/components/avatar/avatar.test.ts b/packages/svelte/src/lib/components/avatar/avatar.test.ts
new file mode 100644
index 0000000000..af64016475
--- /dev/null
+++ b/packages/svelte/src/lib/components/avatar/avatar.test.ts
@@ -0,0 +1,10 @@
+import { render, screen } from '@testing-library/svelte'
+import { describe, expect, it } from 'vitest'
+import ComponentUnderTest from './examples/basic.svelte'
+
+describe('Avatar', async () => {
+ it("should render the user's initials", async () => {
+ render(ComponentUnderTest)
+ expect(screen.getByText('PA')).toBeInTheDocument()
+ })
+})
diff --git a/packages/svelte/src/lib/components/avatar/avatar.ts b/packages/svelte/src/lib/components/avatar/avatar.ts
new file mode 100644
index 0000000000..61b5ca7714
--- /dev/null
+++ b/packages/svelte/src/lib/components/avatar/avatar.ts
@@ -0,0 +1,25 @@
+export type { StatusChangeDetails } from '@zag-js/avatar'
+export {
+ default as Context,
+ type AvatarContextProps as ContextProps,
+} from './avatar-context.svelte'
+export {
+ default as Fallback,
+ type AvatarFallbackProps as FallbackProps,
+ type AvatarFallbackBaseProps as FallbackBaseProps,
+} from './avatar-fallback.svelte'
+export {
+ default as Image,
+ type AvatarImageProps as ImageProps,
+ type AvatarImageBaseProps as ImageBaseProps,
+} from './avatar-image.svelte'
+export {
+ default as RootProvider,
+ type AvatarRootProviderProps as RootProviderProps,
+ type AvatarRootProviderBaseProps as RootProviderBaseProps,
+} from './avatar-root-provider.svelte'
+export {
+ default as Root,
+ type AvatarRootBaseProps as RootBaseProps,
+ type AvatarRootProps as RootProps,
+} from './avatar-root.svelte'
diff --git a/packages/svelte/src/lib/components/avatar/examples/basic.svelte b/packages/svelte/src/lib/components/avatar/examples/basic.svelte
new file mode 100644
index 0000000000..b4b5c32a6b
--- /dev/null
+++ b/packages/svelte/src/lib/components/avatar/examples/basic.svelte
@@ -0,0 +1,8 @@
+
+
+
+ PA
+
+
diff --git a/packages/svelte/src/lib/components/avatar/examples/context.svelte b/packages/svelte/src/lib/components/avatar/examples/context.svelte
new file mode 100644
index 0000000000..2c00d54bf1
--- /dev/null
+++ b/packages/svelte/src/lib/components/avatar/examples/context.svelte
@@ -0,0 +1,18 @@
+
+
+
+
+ {#snippet api(avatar)}
+
+ {#if avatar().loaded}
+ PA
+ {:else}
+ Loading
+ {/if}
+
+ {/snippet}
+
+
+
diff --git a/packages/svelte/src/lib/components/avatar/examples/root-provider.svelte b/packages/svelte/src/lib/components/avatar/examples/root-provider.svelte
new file mode 100644
index 0000000000..ee8899ff27
--- /dev/null
+++ b/packages/svelte/src/lib/components/avatar/examples/root-provider.svelte
@@ -0,0 +1,18 @@
+
+
+
+
+
+ PA
+
+
diff --git a/packages/svelte/src/lib/components/avatar/index.ts b/packages/svelte/src/lib/components/avatar/index.ts
index 8360879d4f..018bba0cf3 100644
--- a/packages/svelte/src/lib/components/avatar/index.ts
+++ b/packages/svelte/src/lib/components/avatar/index.ts
@@ -1,11 +1,27 @@
export type { StatusChangeDetails as AvatarStatusChangeDetails } from '@zag-js/avatar'
-// export { default as AvatarContext, type AvatarContextProps } from './avatar-context.svelte'
-export { default as AvatarFallback, type AvatarFallbackProps } from './avatar-fallback.svelte'
-export { default as AvatarImage, type AvatarImageProps } from './avatar-image.svelte'
+export { default as AvatarContext } from './avatar-context.svelte'
+export {
+ default as AvatarFallback,
+ type AvatarFallbackProps,
+ type AvatarFallbackBaseProps,
+} from './avatar-fallback.svelte'
+export {
+ default as AvatarImage,
+ type AvatarImageProps,
+ type AvatarImageBaseProps,
+} from './avatar-image.svelte'
export {
default as AvatarRoot,
+ type AvatarRootBaseProps,
type AvatarRootProps,
} from './avatar-root.svelte'
export { useAvatarContext, type UseAvatarContext } from './use-avatar-context'
+export { useAvatar, type UseAvatarProps, type UseAvatarReturn } from './use-avatar.svelte'
+export {
+ default as AvatarRootProvider,
+ type AvatarRootProviderProps,
+ type AvatarRootProviderBaseProps,
+} from './avatar-root-provider.svelte'
+export { avatarAnatomy } from './avatar.anatomy'
-// export * as Avatar from './avatar'
+export * as Avatar from './avatar'
diff --git a/packages/svelte/src/lib/components/avatar/use-avatar-context.ts b/packages/svelte/src/lib/components/avatar/use-avatar-context.ts
index a2dc8cf55c..aebd6fd0e1 100644
--- a/packages/svelte/src/lib/components/avatar/use-avatar-context.ts
+++ b/packages/svelte/src/lib/components/avatar/use-avatar-context.ts
@@ -1,4 +1,4 @@
-import { createContext } from '../../utils'
+import { createContext } from '$lib/utils/create-context'
import type { UseAvatarReturn } from './use-avatar.svelte'
export interface UseAvatarContext extends UseAvatarReturn {}
diff --git a/packages/svelte/src/lib/components/avatar/use-avatar.svelte.ts b/packages/svelte/src/lib/components/avatar/use-avatar.svelte.ts
index 7907ffb732..45fa66f7ca 100644
--- a/packages/svelte/src/lib/components/avatar/use-avatar.svelte.ts
+++ b/packages/svelte/src/lib/components/avatar/use-avatar.svelte.ts
@@ -1,19 +1,19 @@
+import type { Accessor, Optional } from '$lib/types'
+import { createId } from '$lib/utils/create-id'
import * as avatar from '@zag-js/avatar'
import { type PropTypes, normalizeProps, useMachine } from '@zag-js/svelte'
-import type { Optional } from '../../../typts'
export interface UseAvatarProps
extends Optional
, 'id'> {}
-export interface UseAvatarReturn extends avatar.Api {}
+export interface UseAvatarReturn extends Accessor> {}
-export const useAvatar = (props: UseAvatarProps) => {
- const [snapshot, send] = useMachine(avatar.machine({ id: '1' }))
- const _api = avatar.connect(snapshot, send, normalizeProps)
- const api = $derived(_api)
-
- return new Proxy(api, {
- get(_, key: keyof typeof api) {
- return api[key]
- },
+export const useAvatar = (props: UseAvatarProps = {}) => {
+ const context = $derived({
+ id: createId(),
+ ...props,
})
+
+ const [state, send] = useMachine(avatar.machine(context), { context })
+ const api = $derived(() => avatar.connect(state, send, normalizeProps))
+ return api
}
diff --git a/packages/svelte/src/lib/types.ts b/packages/svelte/src/lib/types.ts
new file mode 100644
index 0000000000..bf034f9fe9
--- /dev/null
+++ b/packages/svelte/src/lib/types.ts
@@ -0,0 +1,9 @@
+import type { SvelteHTMLElements } from 'svelte/elements'
+
+export type Assign = Omit & U
+export type Optional = Pick, K> & Omit
+
+export type CollectionItem = string | object
+
+export type HTMLProps = SvelteHTMLElements[T]
+export type Accessor = () => T
diff --git a/packages/svelte/src/lib/utils/create-id.ts b/packages/svelte/src/lib/utils/create-id.ts
new file mode 100644
index 0000000000..e7c2bbb68a
--- /dev/null
+++ b/packages/svelte/src/lib/utils/create-id.ts
@@ -0,0 +1,4 @@
+import { nanoid } from 'nanoid/non-secure'
+
+// TODO https://github.com/sveltejs/svelte/issues/7517
+export const createId = () => nanoid(10)
diff --git a/packages/svelte/src/lib/utils/create-split-props.ts b/packages/svelte/src/lib/utils/create-split-props.ts
new file mode 100644
index 0000000000..d5b6d221ea
--- /dev/null
+++ b/packages/svelte/src/lib/utils/create-split-props.ts
@@ -0,0 +1,25 @@
+type EnsureKeys<
+ ExpectedKeys extends (keyof Target)[],
+ Target,
+> = keyof Target extends ExpectedKeys[number]
+ ? unknown
+ : `Missing required keys: ${Exclude & string}`
+
+export const createSplitProps =
+ () =>
+ (
+ props: Props,
+ keys: Keys & EnsureKeys,
+ ) =>
+ (keys as string[]).reduce<[Target, Omit>]>(
+ (previousValue, currentValue) => {
+ const [target, source] = previousValue
+ const key = currentValue as keyof Target & keyof typeof source
+ if (source[key] !== undefined) {
+ target[key] = source[key]
+ }
+ delete source[key]
+ return [target, source]
+ },
+ [{} as Target, { ...props }],
+ )
diff --git a/packages/svelte/src/lib/utils/index.ts b/packages/svelte/src/lib/utils/index.ts
deleted file mode 100644
index 365408a04a..0000000000
--- a/packages/svelte/src/lib/utils/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { createContext } from './create-context'
diff --git a/packages/svelte/src/routes/+page.svelte b/packages/svelte/src/routes/+page.svelte
index a660466dac..fb3ee53272 100644
--- a/packages/svelte/src/routes/+page.svelte
+++ b/packages/svelte/src/routes/+page.svelte
@@ -1,10 +1,8 @@
-
- Welcome to your library project
-
- CS
-
-
-
\ No newline at end of file
+
+
+ CS
+
+
diff --git a/packages/svelte/src/test-setup.ts b/packages/svelte/src/test-setup.ts
new file mode 100644
index 0000000000..a9d0dd31aa
--- /dev/null
+++ b/packages/svelte/src/test-setup.ts
@@ -0,0 +1 @@
+import '@testing-library/jest-dom/vitest'
diff --git a/packages/svelte/src/typts.d.ts b/packages/svelte/src/typts.d.ts
deleted file mode 100644
index dd849ceb51..0000000000
--- a/packages/svelte/src/typts.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export type Assign = Omit & U
-export type Optional = Pick, K> & Omit
-export type CollectionItem = string | object
diff --git a/packages/svelte/src/typts.ts b/packages/svelte/src/typts.ts
deleted file mode 100644
index 182c69dd66..0000000000
--- a/packages/svelte/src/typts.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export type Assign = Omit & U
-export type Optional = Pick, K> & Omit
-
-export type CollectionItem = string | object
diff --git a/packages/svelte/static/favicon.png b/packages/svelte/static/favicon.png
deleted file mode 100644
index 825b9e65af..0000000000
Binary files a/packages/svelte/static/favicon.png and /dev/null differ
diff --git a/packages/svelte/vite.config.ts b/packages/svelte/vite.config.ts
index 7808fb1b8d..bd8e4ac09a 100644
--- a/packages/svelte/vite.config.ts
+++ b/packages/svelte/vite.config.ts
@@ -1,9 +1,12 @@
import { sveltekit } from '@sveltejs/kit/vite'
+import { svelteTesting } from '@testing-library/svelte/vite'
import { defineConfig } from 'vitest/config'
export default defineConfig({
- plugins: [sveltekit()],
+ plugins: [sveltekit(), svelteTesting()],
test: {
+ environment: 'jsdom',
+ setupFiles: ['./src/test-setup.ts'],
include: ['src/**/*.{test,spec}.{js,ts}'],
},
})
diff --git a/scripts/package.json b/scripts/package.json
index 1b722a07a6..128f34ed49 100644
--- a/scripts/package.json
+++ b/scripts/package.json
@@ -15,6 +15,7 @@
"postvue:props": "bun biome format --write ../packages/vue/src/",
"play": "bun run src/play.ts",
"format:vue": "prettier --write '../**/*.vue'",
+ "format:svelte": "prettier --write '../**/*.svelte'",
"format:mdx": "prettier --write '../**/CHANGELOG.md'",
"local:sync": "bun run src/symlink.ts"
},
@@ -29,6 +30,7 @@
"pkg-dir": "8.0.0",
"prettier": "3.4.0",
"prettier-plugin-organize-imports": "4.1.0",
+ "prettier-plugin-svelte": "3.3.2",
"ts-morph": "24.0.0",
"ts-pattern": "5.5.0",
"typescript": "5.6.3",