diff --git a/.changeset/blue-animals-hang.md b/.changeset/blue-animals-hang.md new file mode 100644 index 0000000000..08e78d8376 --- /dev/null +++ b/.changeset/blue-animals-hang.md @@ -0,0 +1,6 @@ +--- +'@solid-design-system/components': major +'@solid-design-system/docs': major +--- + +Added the `floating-label`attribute to the components `sd-select`, `sd-datepicker`, `sd-combobox` and `sd-textarea`, as well as some improvements related to the handling of placeholders to the floating label logic of the `sd-input` component. diff --git a/.changeset/blue-crabs-cry.md b/.changeset/blue-crabs-cry.md new file mode 100644 index 0000000000..02f53af370 --- /dev/null +++ b/.changeset/blue-crabs-cry.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/docs': patch +--- + +Updated `sd-range` tooltip story documentation. diff --git a/.changeset/brave-pots-know.md b/.changeset/brave-pots-know.md new file mode 100644 index 0000000000..f07d9d9776 --- /dev/null +++ b/.changeset/brave-pots-know.md @@ -0,0 +1,6 @@ +--- +'@solid-design-system/components': minor +'@solid-design-system/docs': minor +--- + +Implemented new utility componented named `sd-theme-listener`, used to listen to theme changes. diff --git a/.changeset/busy-crabs-warn.md b/.changeset/busy-crabs-warn.md new file mode 100644 index 0000000000..d6f70de3fa --- /dev/null +++ b/.changeset/busy-crabs-warn.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/docs': minor +--- + +Add and update documentation regarding multi-theming for tokens, components and styles diff --git a/.changeset/cold-ghosts-check.md b/.changeset/cold-ghosts-check.md new file mode 100644 index 0000000000..0a43f8593b --- /dev/null +++ b/.changeset/cold-ghosts-check.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/components': patch +--- + +remove unneeded border in quickfact diff --git a/.changeset/cold-parts-guess.md b/.changeset/cold-parts-guess.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/cold-parts-guess.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/common-hoops-wash.md b/.changeset/common-hoops-wash.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/common-hoops-wash.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/config.json b/.changeset/config.json index 5d058e10a8..29d48f8494 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -7,7 +7,7 @@ } ], "commit": false, - "fixed": [], + "fixed": [["@solid-design-system/components", "@solid-design-system/styles", "@solid-design-system/tokens"]], "linked": [], "access": "public", "baseBranch": "main", diff --git a/.changeset/cozy-windows-throw.md b/.changeset/cozy-windows-throw.md new file mode 100644 index 0000000000..462bc26956 --- /dev/null +++ b/.changeset/cozy-windows-throw.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/tokens': patch +--- + +- Fix SCSS token generation by consistently escaping token names containing dots. diff --git a/.changeset/curvy-memes-stand.md b/.changeset/curvy-memes-stand.md new file mode 100644 index 0000000000..900bdd9ce3 --- /dev/null +++ b/.changeset/curvy-memes-stand.md @@ -0,0 +1,7 @@ +--- +'@solid-design-system/components': major +--- + +Implemented `tooltip` attribute on `sd-range` to define the tooltip behaviour. + +Removed the `no-tooltip` attribute from `sd-range`. \ No newline at end of file diff --git a/.changeset/dark-cougars-drive.md b/.changeset/dark-cougars-drive.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/dark-cougars-drive.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/deep-bats-jog.md b/.changeset/deep-bats-jog.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/deep-bats-jog.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/eight-baboons-post.md b/.changeset/eight-baboons-post.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/eight-baboons-post.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/eighty-zoos-begin.md b/.changeset/eighty-zoos-begin.md new file mode 100644 index 0000000000..d84f32330d --- /dev/null +++ b/.changeset/eighty-zoos-begin.md @@ -0,0 +1,48 @@ +--- +'@solid-design-system/components': minor +'@solid-design-system/theming': minor +'@solid-design-system/styles': minor +'@solid-design-system/tokens': minor +'@solid-design-system/docs': minor +--- + +Added more semantic tokens to the following components: + +- sd-accordion +- sd-audio +- sd-badge +- sd-brandshape +- sd-breadcrumb +- sd-button +- sd-carousel +- sd-checkbox +- sd-chip +- sd-combobox +- sd-container +- sd-date-picker +- sd-divider +- sd-flag +- sd-footnotes +- sd-header +- sd-input +- sd-interactive +- sd-loader +- sd-map-marker +- sd-menu-item +- sd-navigation-item +- sd-notification +- sd-quick-fact +- sd-radio +- sd-radio-button +- sd-radio-group +- sd-range-tick +- sd-select +- sd-step +- sd-switch +- sd-tab +- sd-tag +- sd-teaser +- sd-teaser-media +- sd-textarea +- sd-tooltip +- sd-video \ No newline at end of file diff --git a/.changeset/every-readers-stare.md b/.changeset/every-readers-stare.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/every-readers-stare.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/famous-wolves-read.md b/.changeset/famous-wolves-read.md new file mode 100644 index 0000000000..cd0ae53302 --- /dev/null +++ b/.changeset/famous-wolves-read.md @@ -0,0 +1,7 @@ +--- +'@solid-design-system/components': major +'@solid-design-system/styles': major +'@solid-design-system/tokens': major +--- + +Introduce multi-theming with new CSS variables diff --git a/.changeset/fast-ties-fix.md b/.changeset/fast-ties-fix.md new file mode 100644 index 0000000000..47c5ee965f --- /dev/null +++ b/.changeset/fast-ties-fix.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/components': patch +--- + +Fixed `sd-step` text color. diff --git a/.changeset/fifty-ducks-shave.md b/.changeset/fifty-ducks-shave.md new file mode 100644 index 0000000000..ef70e92794 --- /dev/null +++ b/.changeset/fifty-ducks-shave.md @@ -0,0 +1,6 @@ +--- +'@solid-design-system/components': major +'@solid-design-system/docs': major +--- + +`sd-radio-group` label set to bold as default (removed `boldLabel` attribute). diff --git a/.changeset/forty-crabs-stick.md b/.changeset/forty-crabs-stick.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/forty-crabs-stick.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/funky-books-chew.md b/.changeset/funky-books-chew.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/funky-books-chew.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/funky-files-relate.md b/.changeset/funky-files-relate.md new file mode 100644 index 0000000000..c93d329727 --- /dev/null +++ b/.changeset/funky-files-relate.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/tokens': patch +--- + +Optimize output for TailwindCSS diff --git a/.changeset/fuzzy-webs-kiss.md b/.changeset/fuzzy-webs-kiss.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/fuzzy-webs-kiss.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/goofy-goats-cheat.md b/.changeset/goofy-goats-cheat.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/goofy-goats-cheat.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/green-headphones-cry.md b/.changeset/green-headphones-cry.md new file mode 100644 index 0000000000..29838f19c0 --- /dev/null +++ b/.changeset/green-headphones-cry.md @@ -0,0 +1,6 @@ +--- +'@solid-design-system/components': patch +'@solid-design-system/tokens': patch +--- + +Updated documentation for multi-theming feature diff --git a/.changeset/green-tigers-see.md b/.changeset/green-tigers-see.md new file mode 100644 index 0000000000..ec380ec43f --- /dev/null +++ b/.changeset/green-tigers-see.md @@ -0,0 +1,3 @@ +--- +--- + diff --git a/.changeset/happy-files-leave.md b/.changeset/happy-files-leave.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/happy-files-leave.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/hip-roses-love.md b/.changeset/hip-roses-love.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/hip-roses-love.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/humble-bananas-unite.md b/.changeset/humble-bananas-unite.md new file mode 100644 index 0000000000..b59c1c61cf --- /dev/null +++ b/.changeset/humble-bananas-unite.md @@ -0,0 +1,9 @@ +--- +'@solid-design-system/components': patch +'@solid-design-system/theming': patch +'@solid-design-system/styles': patch +'@solid-design-system/tokens': patch +'@solid-design-system/docs': patch +--- + +Internal: version bump to align with main (no user-facing changes). diff --git a/.changeset/humble-eyes-prove.md b/.changeset/humble-eyes-prove.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/humble-eyes-prove.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/jolly-baboons-join.md b/.changeset/jolly-baboons-join.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/jolly-baboons-join.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/kind-papayas-join.md b/.changeset/kind-papayas-join.md new file mode 100644 index 0000000000..0ac38ff6ef --- /dev/null +++ b/.changeset/kind-papayas-join.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/tokens': minor +--- + +Implement shadow tokens generation according to Figma. diff --git a/.changeset/large-dancers-train.md b/.changeset/large-dancers-train.md new file mode 100644 index 0000000000..1b528c2040 --- /dev/null +++ b/.changeset/large-dancers-train.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/docs': patch +--- + +Updated the validation messages for `sd-combobox`, `sd-input`, `sd-radio-group`, `sd-select`, `sd-switch` and `sd-textarea` diff --git a/.changeset/lazy-numbers-jog.md b/.changeset/lazy-numbers-jog.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/lazy-numbers-jog.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/loud-aliens-drive.md b/.changeset/loud-aliens-drive.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/loud-aliens-drive.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/loud-animals-post.md b/.changeset/loud-animals-post.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/loud-animals-post.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/loud-oranges-report.md b/.changeset/loud-oranges-report.md new file mode 100644 index 0000000000..7d75835366 --- /dev/null +++ b/.changeset/loud-oranges-report.md @@ -0,0 +1,6 @@ +--- +'@solid-design-system/components': patch +'@solid-design-system/docs': patch +--- + +fixed the restriction of changing the font size and margin for headline in `sd-teased-media`. diff --git a/.changeset/lovely-jobs-trade.md b/.changeset/lovely-jobs-trade.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/lovely-jobs-trade.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/major-lemons-cover.md b/.changeset/major-lemons-cover.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/major-lemons-cover.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/modern-cobras-post.md b/.changeset/modern-cobras-post.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/modern-cobras-post.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/modern-nights-say.md b/.changeset/modern-nights-say.md new file mode 100644 index 0000000000..1a820a4ffb --- /dev/null +++ b/.changeset/modern-nights-say.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/styles': patch +--- + +Fixed styles build output to correctly resolve imports. diff --git a/.changeset/new-friends-dress.md b/.changeset/new-friends-dress.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/new-friends-dress.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/nice-deer-lick.md b/.changeset/nice-deer-lick.md new file mode 100644 index 0000000000..ede32286c2 --- /dev/null +++ b/.changeset/nice-deer-lick.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/tokens': patch +--- + +Remove semicolon breaking imports in other TailwindCSS projects diff --git a/.changeset/petite-singers-return.md b/.changeset/petite-singers-return.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/petite-singers-return.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/pink-memes-hear.md b/.changeset/pink-memes-hear.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/pink-memes-hear.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/plain-bananas-brake.md b/.changeset/plain-bananas-brake.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/plain-bananas-brake.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 0000000000..bfb748be3d --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,102 @@ +{ + "mode": "pre", + "tag": "next", + "initialVersions": { + "@solid-design-system/components": "5.15.12", + "@solid-design-system/docs": "1.29.2", + "@solid-design-system/eslint-plugin": "1.0.2", + "@solid-design-system/placeholders": "2.1.3", + "@solid-design-system/styles": "1.5.5", + "@solid-design-system/theming": "1.1.2", + "@solid-design-system/tokens": "5.6.0", + "@solid-design-system/versioning": "1.0.0" + }, + "changesets": [ + "blue-animals-hang", + "blue-crabs-cry", + "brave-pots-know", + "busy-crabs-warn", + "cold-ghosts-check", + "cold-parts-guess", + "common-hoops-wash", + "cozy-windows-throw", + "curvy-memes-stand", + "dark-cougars-drive", + "deep-bats-jog", + "eight-baboons-post", + "eighty-zoos-begin", + "every-readers-stare", + "famous-wolves-read", + "fast-ties-fix", + "fifty-ducks-shave", + "forty-crabs-stick", + "funky-books-chew", + "funky-files-relate", + "fuzzy-webs-kiss", + "goofy-goats-cheat", + "green-headphones-cry", + "green-tigers-see", + "happy-files-leave", + "hip-roses-love", + "humble-bananas-unite", + "humble-eyes-prove", + "jolly-baboons-join", + "kind-papayas-join", + "large-dancers-train", + "lazy-numbers-jog", + "loud-aliens-drive", + "loud-animals-post", + "loud-oranges-report", + "lovely-jobs-trade", + "major-lemons-cover", + "modern-cobras-post", + "modern-nights-say", + "new-friends-dress", + "nice-deer-lick", + "petite-singers-return", + "pink-memes-hear", + "plain-bananas-brake", + "public-apes-admire", + "puny-beans-smell", + "puny-pianos-bet", + "quick-rice-brake", + "ready-bikes-dig", + "ready-words-visit", + "real-lions-thank", + "salty-glasses-judge", + "shaky-planets-cover", + "silly-streets-tap", + "silver-baths-send", + "six-showers-end", + "slow-carrots-fly", + "slow-grapes-yell", + "slow-stars-grin", + "social-loops-repeat", + "soft-kings-pick", + "some-emus-hide", + "spicy-oranges-fall", + "spicy-parents-dance", + "stupid-socks-occur", + "tall-lions-enter", + "tasty-years-jam", + "ten-hats-happen", + "ten-ties-reply", + "tender-rice-rhyme", + "thick-cars-prove", + "thick-masks-watch", + "thick-sides-spend", + "tired-lies-cut", + "tired-tables-write", + "tough-jeans-go", + "tricky-news-bow", + "twelve-bats-shake", + "twelve-streets-mate", + "two-maps-sit", + "upset-pants-behave", + "wild-tigers-wave", + "wise-parks-train", + "yellow-dolls-retire", + "yellow-dragons-relax", + "yummy-rules-love" + ] +} diff --git a/.changeset/public-apes-admire.md b/.changeset/public-apes-admire.md new file mode 100644 index 0000000000..7390094ae0 --- /dev/null +++ b/.changeset/public-apes-admire.md @@ -0,0 +1,4 @@ +--- + +--- + diff --git a/.changeset/puny-beans-smell.md b/.changeset/puny-beans-smell.md new file mode 100644 index 0000000000..43fa7659ad --- /dev/null +++ b/.changeset/puny-beans-smell.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/components': patch +--- + +fix accordion group margin for vb diff --git a/.changeset/puny-pianos-bet.md b/.changeset/puny-pianos-bet.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/puny-pianos-bet.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/quick-rice-brake.md b/.changeset/quick-rice-brake.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/quick-rice-brake.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/ready-bikes-dig.md b/.changeset/ready-bikes-dig.md new file mode 100644 index 0000000000..88940b75f5 --- /dev/null +++ b/.changeset/ready-bikes-dig.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/components': patch +--- + +Bump components next version. diff --git a/.changeset/ready-words-visit.md b/.changeset/ready-words-visit.md new file mode 100644 index 0000000000..1d4ef4f7fa --- /dev/null +++ b/.changeset/ready-words-visit.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/docs': patch +--- + +Add new package versioning strategy information for `components`, `styles` and `tokens` in installation pages and migration guides. diff --git a/.changeset/real-lions-thank.md b/.changeset/real-lions-thank.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/real-lions-thank.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/salty-glasses-judge.md b/.changeset/salty-glasses-judge.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/salty-glasses-judge.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/shaky-planets-cover.md b/.changeset/shaky-planets-cover.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/shaky-planets-cover.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/silly-streets-tap.md b/.changeset/silly-streets-tap.md new file mode 100644 index 0000000000..1ebd885356 --- /dev/null +++ b/.changeset/silly-streets-tap.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/components': patch +--- + +Fixed theming background color issue on `sd-tooltip` arrow. diff --git a/.changeset/silver-baths-send.md b/.changeset/silver-baths-send.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/silver-baths-send.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/six-showers-end.md b/.changeset/six-showers-end.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/six-showers-end.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/slow-carrots-fly.md b/.changeset/slow-carrots-fly.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/slow-carrots-fly.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/slow-grapes-yell.md b/.changeset/slow-grapes-yell.md new file mode 100644 index 0000000000..3b7ddd77fa --- /dev/null +++ b/.changeset/slow-grapes-yell.md @@ -0,0 +1,6 @@ +--- +'@solid-design-system/components': patch +'@solid-design-system/tokens': patch +--- + +Fix theme shadows generation. diff --git a/.changeset/slow-stars-grin.md b/.changeset/slow-stars-grin.md new file mode 100644 index 0000000000..c660b491a6 --- /dev/null +++ b/.changeset/slow-stars-grin.md @@ -0,0 +1,9 @@ +--- +'@solid-design-system/components': patch +'@solid-design-system/theming': patch +'@solid-design-system/styles': patch +'@solid-design-system/tokens': patch +'@solid-design-system/docs': patch +--- + +- Add `kid-starter` theme. diff --git a/.changeset/social-loops-repeat.md b/.changeset/social-loops-repeat.md new file mode 100644 index 0000000000..df8d7b04ea --- /dev/null +++ b/.changeset/social-loops-repeat.md @@ -0,0 +1,6 @@ +--- +'@solid-design-system/docs': patch +--- + +- Update favicon to support dark mode. + diff --git a/.changeset/soft-kings-pick.md b/.changeset/soft-kings-pick.md new file mode 100644 index 0000000000..b5e3d4c4df --- /dev/null +++ b/.changeset/soft-kings-pick.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/components': patch +--- + +fix icon color default library (content/system) diff --git a/.changeset/some-emus-hide.md b/.changeset/some-emus-hide.md new file mode 100644 index 0000000000..54e6b379e0 --- /dev/null +++ b/.changeset/some-emus-hide.md @@ -0,0 +1,6 @@ +--- +'@solid-design-system/components': minor +'@solid-design-system/docs': minor +--- + +Implement `icon-left` property for the `sd-tag` diff --git a/.changeset/spicy-oranges-fall.md b/.changeset/spicy-oranges-fall.md new file mode 100644 index 0000000000..3666c6eaad --- /dev/null +++ b/.changeset/spicy-oranges-fall.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/docs': minor +--- + +Implemented a new `sd-menu` template diff --git a/.changeset/spicy-parents-dance.md b/.changeset/spicy-parents-dance.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/spicy-parents-dance.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/stupid-socks-occur.md b/.changeset/stupid-socks-occur.md new file mode 100644 index 0000000000..951eaaa820 --- /dev/null +++ b/.changeset/stupid-socks-occur.md @@ -0,0 +1,10 @@ +--- +'@solid-design-system/components': major +--- + +Updated the following in `sd-datepicker`: + +- Changed `range-start` and `range-end` attributes from camelCase to kebab case to align with the rest of the component API. +- Added date conversion in `value`, `disabled-dates`, `range-start`, `range-end`, `min` and `max` attributes. +- Added missing `required` attribute. +- Updated properties descritions and other minor fixes. diff --git a/.changeset/tall-lions-enter.md b/.changeset/tall-lions-enter.md new file mode 100644 index 0000000000..23e7870eef --- /dev/null +++ b/.changeset/tall-lions-enter.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/tokens': patch +--- + +Add new icons to vb and kid icons. diff --git a/.changeset/tasty-years-jam.md b/.changeset/tasty-years-jam.md new file mode 100644 index 0000000000..8ded61c256 --- /dev/null +++ b/.changeset/tasty-years-jam.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/components': patch +--- + +Adjusted theme generator to support rgba instead of hex. diff --git a/.changeset/ten-hats-happen.md b/.changeset/ten-hats-happen.md new file mode 100644 index 0000000000..6d991c4851 --- /dev/null +++ b/.changeset/ten-hats-happen.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/components': patch +--- + +Fixed `sd-accordion` focus outline being cropped when grouped with multiple `sd-accordion` diff --git a/.changeset/ten-ties-reply.md b/.changeset/ten-ties-reply.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/ten-ties-reply.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/tender-rice-rhyme.md b/.changeset/tender-rice-rhyme.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/tender-rice-rhyme.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/thick-cars-prove.md b/.changeset/thick-cars-prove.md new file mode 100644 index 0000000000..f878206d96 --- /dev/null +++ b/.changeset/thick-cars-prove.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/components': patch +--- + +Changed icon library to `_internal` on the `sd-input` step buttons. diff --git a/.changeset/thick-masks-watch.md b/.changeset/thick-masks-watch.md new file mode 100644 index 0000000000..8e5031eeef --- /dev/null +++ b/.changeset/thick-masks-watch.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/components': patch +--- + +Fix`sd-accordion` border margin-top when using preflight. diff --git a/.changeset/thick-sides-spend.md b/.changeset/thick-sides-spend.md new file mode 100644 index 0000000000..223e3767e1 --- /dev/null +++ b/.changeset/thick-sides-spend.md @@ -0,0 +1,7 @@ +--- +'@solid-design-system/tokens': patch +--- + +Fixed semantic tokens generation to enable multi theming on the same page. + +Added `:root` selector to all theme files. diff --git a/.changeset/tired-lies-cut.md b/.changeset/tired-lies-cut.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/tired-lies-cut.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/tired-tables-write.md b/.changeset/tired-tables-write.md new file mode 100644 index 0000000000..bd9c5f8607 --- /dev/null +++ b/.changeset/tired-tables-write.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/components': patch +--- + +Fix broken sd-icon load with multi theming. diff --git a/.changeset/tough-jeans-go.md b/.changeset/tough-jeans-go.md new file mode 100644 index 0000000000..83c9e70dcf --- /dev/null +++ b/.changeset/tough-jeans-go.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/tokens': patch +--- + +Improve themes token generation to include all utility tokens. diff --git a/.changeset/tricky-news-bow.md b/.changeset/tricky-news-bow.md new file mode 100644 index 0000000000..cd3194d418 --- /dev/null +++ b/.changeset/tricky-news-bow.md @@ -0,0 +1,8 @@ +--- +'@solid-design-system/docs': patch +--- + +Improvements on `sd-datepicker` documentation: + +- Updated `range` and `disabled-dates` stories to reflect new date conversion. +- Added new screenshot test for `min` and `max`. diff --git a/.changeset/twelve-bats-shake.md b/.changeset/twelve-bats-shake.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/twelve-bats-shake.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/twelve-streets-mate.md b/.changeset/twelve-streets-mate.md new file mode 100644 index 0000000000..853d812bb3 --- /dev/null +++ b/.changeset/twelve-streets-mate.md @@ -0,0 +1,3 @@ +--- + +--- diff --git a/.changeset/two-maps-sit.md b/.changeset/two-maps-sit.md new file mode 100644 index 0000000000..381c63bd56 --- /dev/null +++ b/.changeset/two-maps-sit.md @@ -0,0 +1,7 @@ +--- +'@solid-design-system/components': patch +'@solid-design-system/styles': patch +'@solid-design-system/tokens': patch +--- + +Sync packages versions. diff --git a/.changeset/upset-pants-behave.md b/.changeset/upset-pants-behave.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/upset-pants-behave.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/wild-tigers-wave.md b/.changeset/wild-tigers-wave.md new file mode 100644 index 0000000000..d561c98e4f --- /dev/null +++ b/.changeset/wild-tigers-wave.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/tokens': patch +--- + +Generate theme colors in rgb instead of hex to reduce breaking changes. diff --git a/.changeset/wise-parks-train.md b/.changeset/wise-parks-train.md new file mode 100644 index 0000000000..83f9412eeb --- /dev/null +++ b/.changeset/wise-parks-train.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/components': patch +--- + +Fix `sd-video` play button issue where styles are being reset. diff --git a/.changeset/yellow-dolls-retire.md b/.changeset/yellow-dolls-retire.md new file mode 100644 index 0000000000..9eccb00fc9 --- /dev/null +++ b/.changeset/yellow-dolls-retire.md @@ -0,0 +1,5 @@ +--- +'@solid-design-system/tokens': patch +--- + +Optimize exports for themes, TailwindCSS and SCSS diff --git a/.changeset/yellow-dragons-relax.md b/.changeset/yellow-dragons-relax.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/yellow-dragons-relax.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.changeset/yummy-rules-love.md b/.changeset/yummy-rules-love.md new file mode 100644 index 0000000000..a845151cc8 --- /dev/null +++ b/.changeset/yummy-rules-love.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml index e72b6451e5..da7af4e502 100644 --- a/.github/workflows/check-pr.yml +++ b/.github/workflows/check-pr.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest if: github.event.pull_request.draft == false container: - image: mcr.microsoft.com/playwright:v1.55.1-noble + image: mcr.microsoft.com/playwright:v1.57.0-noble strategy: matrix: package: @@ -48,40 +48,10 @@ jobs: cd ${{ matrix.package }} pnpm verify - playwright-tests: - name: Verify (docs/a11y-tree) - runs-on: ubuntu-latest - if: github.event.pull_request.draft == false - container: - image: mcr.microsoft.com/playwright:v1.55.0-noble - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Install Node.js - uses: actions/setup-node@v4 - with: - node-version: 22 - - - uses: pnpm/action-setup@v4 - name: Install pnpm - with: - run_install: false - - - name: Install dependencies - run: pnpm i - - - name: Run Playwright tests - run: | - cd packages/docs - pnpm run build - pnpm run test.a11y - # Check Chromatic for visual changes after all other checks have passed chromatic-deployment-pr: name: Verify Chromatic - needs: [quality-gate, playwright-tests] + needs: [quality-gate] if: ${{!contains(github.event.pull_request.title, '[skip chromatic]') && !startsWith(github.event.pull_request.title, 'chore(security deps):')}} runs-on: ubuntu-latest steps: @@ -114,4 +84,4 @@ jobs: # TurboSnap is an advanced Chromatic feature that speeds up builds for faster UI testing and review using Git and Webpack’s dependency graph onlyChanged: false # We need to manually build storybook with pnpm - storybookBuildDir: packages/docs/dist/storybook + storybookBuildDir: packages/docs/dist/storybook \ No newline at end of file diff --git a/.prettierignore b/.prettierignore index 37f72171e8..f458d49ee4 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,12 +3,6 @@ .github **/dist **/dist-versioned -**/components/cdn -**/components/cdn-versioned -**/styles/cdn -**/styles/cdn-versioned -# Automatically generated by Figma -packages/tokens/src/tokens.json **/node_modules **/package-lock.json **/pnpm-lock.yaml @@ -16,7 +10,29 @@ packages/tokens/src/tokens.json **/tokens.json **/*.d.ts +# Components +packages/components/cdn +packages/components/cdn-versioned +# Styles +packages/styles/cdn +packages/styles/cdn-versioned +# Tokens +packages/tokens/cdn +packages/tokens/dist +## Automatically generated by Figma +packages/tokens/src/tokens.json +packages/tokens/src/figma-variables +# Docs +packages/docs/axe-reports +packages/docs/build +packages/docs/playwright-report +packages/docs/test-results +packages/tokens/themes +# eslint-plugin +packages/eslint-plugin/dist + + packages/autocomplete/src .changeset/*.md .changeset/pre.json -packages/docs/.storybook/solid-tw-configuration.json \ No newline at end of file +packages/docs/.storybook/solid-tw-configuration.json diff --git a/package.json b/package.json index 5a58add69c..0f888b228f 100644 --- a/package.json +++ b/package.json @@ -62,8 +62,8 @@ }, "pnpm": { "patchedDependencies": { - "tailwindcss@3.4.17": "patches/tailwindcss@3.4.1.patch", - "wc-storybook-helpers": "patches/wc-storybook-helpers.patch" + "wc-storybook-helpers": "patches/wc-storybook-helpers.patch", + "tailwindcss": "patches/tailwindcss.patch" } } } diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 2f75d715e9..aec6c981f0 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -1,5 +1,238 @@ # @solid-design-system/components +## 6.0.0-next.24 + +### Major Changes + +- Added the `floating-label`attribute to the components `sd-select`, `sd-datepicker`, `sd-combobox` and `sd-textarea`, as well as some improvements related to the handling of placeholders to the floating label logic of the `sd-input` component. _[`#2679`](https://github.com/solid-design-system/solid/pull/2679) [`6ab3afe`](https://github.com/solid-design-system/solid/commit/6ab3afefc4c9d29b5fcaf3d541170e5e6a78dd7f) [@martascorreia](https://github.com/martascorreia)_ + +### 📈 Stats +* Uncompressed: 587 KB (+4 KB / +1%) +* Gzipped: 133 KB (+1 KB / +1%) + +## 6.0.0-next.23 + +### Major Changes + +- `sd-radio-group` label set to bold as default (removed `boldLabel` attribute). _[`#2681`](https://github.com/solid-design-system/solid/pull/2681) [`878ad8d`](https://github.com/solid-design-system/solid/commit/878ad8d05bb10d09381a049eb07714b930293b10) [@martascorreia](https://github.com/martascorreia)_ + +## 6.0.0-next.22 + +### 📈 Stats + +- Uncompressed: 583 KB (+3 KB / +1%) +- Gzipped: 132 KB (unchanged) + +## 6.0.0-next.21 + +### Minor Changes + +- Implement `icon-left` property for the `sd-tag` _[`#2707`](https://github.com/solid-design-system/solid/pull/2707) [`1055de1`](https://github.com/solid-design-system/solid/commit/1055de18cbcbdcc20d2f62d5f1c77da4cd925053) [@balco0110](https://github.com/balco0110)_ + +## 6.0.0-next.19 + +### Major Changes + +- Updated the following in `sd-datepicker`: _[`#2640`](https://github.com/solid-design-system/solid/pull/2640) [`3cc8aab`](https://github.com/solid-design-system/solid/commit/3cc8aab1836b39e66cbdc1850af9056f075e4b26) [@smfonseca](https://github.com/smfonseca)_ + - Changed `range-start` and `range-end` attributes from camelCase to kebab case to align with the rest of the component API. + - Added date conversion in `value`, `disabled-dates`, `range-start`, `range-end`, `min` and `max` attributes. + - Added missing `required` attribute. + - Updated properties descritions and other minor fixes. + +### 📈 Stats + +- Uncompressed: 580 KB (+1 KB / +0%) +- Gzipped: 132 KB (+1 KB / +1%) + +## 6.0.0-next.18 + +### Patch Changes + +- Updated documentation for multi-theming feature _[`#2709`](https://github.com/solid-design-system/solid/pull/2709) [`4c240e0`](https://github.com/solid-design-system/solid/commit/4c240e0209cd7a4c90a344ec043969272ef4471d) [@mariohamann](https://github.com/mariohamann)_ + +## 6.0.0-next.17 + +## 6.0.0-next.16 + +### Patch Changes + +- Add `kid-starter` theme. _[`#2663`](https://github.com/solid-design-system/solid/pull/2663) [`575bcf1`](https://github.com/solid-design-system/solid/commit/575bcf1ae1ce4bf0ee1773be5519ae07c5c8981a) [@auroraVasconcelos](https://github.com/auroraVasconcelos)_ + +### 📈 Stats + +- Uncompressed: 579 KB (+2 KB / +0%) +- Gzipped: 131 KB (unchanged) + +## 6.0.0-next.15 + +### Patch Changes + +- Internal: version bump to align with main (no user-facing changes). _[`#2656`](https://github.com/solid-design-system/solid/pull/2656) [`34dbd53`](https://github.com/solid-design-system/solid/commit/34dbd5304ad4bd6486068c40e307742841c25f4d) [@paulovareiro29](https://github.com/paulovareiro29)_ + +### 📈 Stats + +- Uncompressed: 577 KB (+3 KB / +1%) +- Gzipped: 131 KB (+1 KB / +1%) + +## 6.0.0-next.14 + +### Patch Changes + +- Fixed `sd-step` text color. _[`#2648`](https://github.com/solid-design-system/solid/pull/2648) [`e39d834`](https://github.com/solid-design-system/solid/commit/e39d83492d00f72afc82a2692d0dc9156ac03db1) [@paulovareiro29](https://github.com/paulovareiro29)_ + +## 6.0.0-next.13 + +### Minor Changes + +- Added more semantic tokens to the following components: _[`#2646`](https://github.com/solid-design-system/solid/pull/2646) [`24e0bff`](https://github.com/solid-design-system/solid/commit/24e0bffe2a91c5ddbd39cef6c7a3bb46df89f472) [@paulovareiro29](https://github.com/paulovareiro29)_ + - sd-accordion + - sd-audio + - sd-badge + - sd-brandshape + - sd-breadcrumb + - sd-button + - sd-carousel + - sd-checkbox + - sd-chip + - sd-combobox + - sd-container + - sd-date-picker + - sd-divider + - sd-flag + - sd-footnotes + - sd-header + - sd-input + - sd-interactive + - sd-loader + - sd-map-marker + - sd-menu-item + - sd-navigation-item + - sd-notification + - sd-quick-fact + - sd-radio + - sd-radio-button + - sd-radio-group + - sd-range-tick + - sd-select + - sd-step + - sd-switch + - sd-tab + - sd-tag + - sd-teaser + - sd-teaser-media + - sd-textarea + - sd-tooltip + - sd-video + +### Patch Changes + +- Fixed `sd-accordion` focus outline being cropped when grouped with multiple `sd-accordion` _[`#2646`](https://github.com/solid-design-system/solid/pull/2646) [`24e0bff`](https://github.com/solid-design-system/solid/commit/24e0bffe2a91c5ddbd39cef6c7a3bb46df89f472) [@paulovareiro29](https://github.com/paulovareiro29)_ + +### 📈 Stats + +- Uncompressed: 574 KB (+12 KB / +2%) +- Gzipped: 130 KB (+1 KB / +1%) + +## 6.0.0-next.12 + +### Patch Changes + +- Remove unneeded border in quickfact _[`#2570`](https://github.com/solid-design-system/solid/pull/2570) [`e829dec`](https://github.com/solid-design-system/solid/commit/e829decbe1b704007a1d38a93405ee9344df6529) [@paulovareiro29](https://github.com/paulovareiro29)_ + +### 📈 Stats + +- Uncompressed: 562 KB (+1 KB / +0%) +- Gzipped: 129 KB (unchanged) + +## 6.0.0-next.11 + +### Patch Changes + +- Fix icon color default library (content/system) _[`#2628`](https://github.com/solid-design-system/solid/pull/2628) [`1e743d6`](https://github.com/solid-design-system/solid/commit/1e743d6458fc728151d44ebdc1bd5e0a665e2739) [@mariohamann](https://github.com/mariohamann)_ + +## 6.0.0-next.10 + +### Patch Changes + +- Adjusted theme generator to support rgba instead of hex. _[`#2621`](https://github.com/solid-design-system/solid/pull/2621) [`5a3a5a5`](https://github.com/solid-design-system/solid/commit/5a3a5a575a2fab8cd5e8c56533e215ae94a5aaab) [@paulovareiro29](https://github.com/paulovareiro29)_ + +### 📈 Stats + +- Uncompressed: 561 KB (+2 KB / +0%) +- Gzipped: 129 KB (unchanged) + +## 6.0.0-next.9 + +### Patch Changes + +- Fixed the restriction of changing the font size and margin for headline in `sd-teased-media`. _[`#2405`](https://github.com/solid-design-system/solid/pull/2405) [`22c42e7`](https://github.com/solid-design-system/solid/commit/22c42e72319e4e409735420cdab52092fe6b74b2) [@balco0110](https://github.com/balco0110)_ + +### 📈 Stats + +- Uncompressed: 559 KB (-1 KB / 0%) +- Gzipped: 129 KB (unchanged) + +## 6.0.0-next.8 + +### Patch Changes + +- Sync packages versions. _[`#2618`](https://github.com/solid-design-system/solid/pull/2618) [`c87b6ef`](https://github.com/solid-design-system/solid/commit/c87b6ef3c8db38b6add6cb87a712a50bc2068935) [@paulovareiro29](https://github.com/paulovareiro29)_ + +## 6.0.0-next.6 + +### Patch Changes + +- Fix`sd-accordion` border margin-top when using preflight. _[`#2616`](https://github.com/solid-design-system/solid/pull/2616) [`cc19dec`](https://github.com/solid-design-system/solid/commit/cc19decb97490275bdb401316d51443b115b134a) [@paulovareiro29](https://github.com/paulovareiro29)_ + +## 6.0.0-next.5 + +### Patch Changes + +- Fix accordion group margin for vb _[`#2570`](https://github.com/solid-design-system/solid/pull/2570) [`e9d350f`](https://github.com/solid-design-system/solid/commit/e9d350f0c5f88b71f74fb5ae44f7b4027bd9dcd1) [@paulovareiro29](https://github.com/paulovareiro29)_ + +## 6.0.0-next.4 + +### Patch Changes + +- Fixed theming background color issue on `sd-tooltip` arrow. _[`#2613`](https://github.com/solid-design-system/solid/pull/2613) [`c75ef18`](https://github.com/solid-design-system/solid/commit/c75ef180b55e89f6f730675c40e53dcaa6fd8979) [@paulovareiro29](https://github.com/paulovareiro29)_ + +## 6.0.0-next.3 + +### Major Changes + +- Implemented `tooltip` attribute on `sd-range` to define the tooltip behaviour. _[`#2607`](https://github.com/solid-design-system/solid/pull/2607) [`87d3e4d`](https://github.com/solid-design-system/solid/commit/87d3e4de892a0b7109ac0e9d68dd63a5bcaf8302) [@paulovareiro29](https://github.com/paulovareiro29)_ + + Removed the `no-tooltip` attribute from `sd-range`. + +### 📈 Stats + +- Uncompressed: 560 KB (+1 KB / +0%) +- Gzipped: 129 KB (+1 KB / +1%) + +## 6.0.0-next.2 + +### Patch Changes + +- Bump components next version. _[`#2612`](https://github.com/solid-design-system/solid/pull/2612) [`6d68731`](https://github.com/solid-design-system/solid/commit/6d68731f1e4c21c39cfe0b8e55133eed0909e6c6) [@paulovareiro29](https://github.com/paulovareiro29)_ + +## 5.16.2-next.1 + +### Patch Changes + +- Fix `sd-video` play button issue where styles are being reset. _[`#2609`](https://github.com/solid-design-system/solid/pull/2609) [`9556c9f`](https://github.com/solid-design-system/solid/commit/9556c9fa38e20df410d67a7fde13b0cae3b052b9) [@paulovareiro29](https://github.com/paulovareiro29)_ + +## 5.16.2-next.0 + +### Patch Changes + +- Fix theme shadows generation. _[`#2608`](https://github.com/solid-design-system/solid/pull/2608) [`a051aea`](https://github.com/solid-design-system/solid/commit/a051aeaeccf68fd1af8839ff1d463fcc98b325e4) [@paulovareiro29](https://github.com/paulovareiro29)_ + +## 5.16.1-next.0 + +### Patch Changes + +- Fix broken sd-icon load with multi theming. _[`#2595`](https://github.com/solid-design-system/solid/pull/2595) [`89d7ac7`](https://github.com/solid-design-system/solid/commit/89d7ac7fbe51b382544765de6e08cb9be6c9e9fc) [@paulovareiro29](https://github.com/paulovareiro29)_ + ## 5.17.4 ### Patch Changes @@ -118,8 +351,7 @@ ### Patch Changes -- - Update pnpm to 10.17 _[`#2522`](https://github.com/solid-design-system/solid/pull/2522) [`7cc6bb7`](https://github.com/solid-design-system/solid/commit/7cc6bb7bdfc9ccb26c2ecfa58b27021d15379312) [@auroraVasconcelos](https://github.com/auroraVasconcelos)_ - +- Update pnpm to 10.17 _[`#2522`](https://github.com/solid-design-system/solid/pull/2522) [`7cc6bb7`](https://github.com/solid-design-system/solid/commit/7cc6bb7bdfc9ccb26c2ecfa58b27021d15379312) [@auroraVasconcelos](https://github.com/auroraVasconcelos)_ - Add minimumReleaseAge to 5 days - Update all actions to ensure that they're using the correct version @@ -332,7 +564,7 @@ ### Patch Changes -- - Add motion design to sd-tab _[`#2256`](https://github.com/solid-design-system/solid/pull/2256) [`6f9d3fa`](https://github.com/solid-design-system/solid/commit/6f9d3fa42e95fbe3a13dcf89c499294facb25052) [@smfonseca](https://github.com/smfonseca)_ +- Add motion design to sd-tab _[`#2256`](https://github.com/solid-design-system/solid/pull/2256) [`6f9d3fa`](https://github.com/solid-design-system/solid/commit/6f9d3fa42e95fbe3a13dcf89c499294facb25052) [@smfonseca](https://github.com/smfonseca)_ ### 📈 Stats @@ -395,7 +627,7 @@ ### Minor Changes -- - Add tooltip slot to `sd-switch`; _[`#2319`](https://github.com/solid-design-system/solid/pull/2319) [`5d20c51`](https://github.com/solid-design-system/solid/commit/5d20c51b9e0b15be47cfd60e24bb179cef42bf27) [@auroraVasconcelos](https://github.com/auroraVasconcelos)_ +- Add tooltip slot to `sd-switch`; _[`#2319`](https://github.com/solid-design-system/solid/pull/2319) [`5d20c51`](https://github.com/solid-design-system/solid/commit/5d20c51b9e0b15be47cfd60e24bb179cef42bf27) [@auroraVasconcelos](https://github.com/auroraVasconcelos)_ ## 5.9.0 @@ -455,7 +687,7 @@ ### Minor Changes -- - Implement `reversed-layout` attribute for the `sd-teaser`. _[`#2283`](https://github.com/solid-design-system/solid/pull/2283) [`e65a94a`](https://github.com/solid-design-system/solid/commit/e65a94a7120525d73c40f58ad565911a81cff97b) [@auroraVasconcelos](https://github.com/auroraVasconcelos)_ +- Implement `reversed-layout` attribute for the `sd-teaser`. _[`#2283`](https://github.com/solid-design-system/solid/pull/2283) [`e65a94a`](https://github.com/solid-design-system/solid/commit/e65a94a7120525d73c40f58ad565911a81cff97b) [@auroraVasconcelos](https://github.com/auroraVasconcelos)_ ## 5.6.0 diff --git a/packages/components/CONTRIBUTING.md b/packages/components/CONTRIBUTING.md index 8f46f2edd3..b98debd45b 100644 --- a/packages/components/CONTRIBUTING.md +++ b/packages/components/CONTRIBUTING.md @@ -22,6 +22,16 @@ We ensure consistency and try to minimize bundle size by following these rules: - Utilize IDs or part selectors for any custom CSS needs. - Use `@apply` inside `css` tagged template literals to generate CSS, but do not use arbitrary values like `mt-[var(--spacing-xxl)]` there (!), as this increases the bundle size of the main TailwindCSS file. Add those custom values as plain CSS outside the `@apply` directive +#### Consistency with Figma + +In Figma, some design variables are used differently than in code. For example, Figma might use a variable like `icon-fill-color`, whereas in code, the corresponding property could be `background-color`. + +To maintain consistency with Figma’s naming conventions, certain styles in the codebase directly assign CSS variables to properties instead of relying on Tailwind utilities. + +```css +background-color: var(--sd-color-icon-fill-neutral-800, var(--sd-color-neutral-800)); +``` + ### Importing other components When you use a component inside another component, you need to import it in the component file to ensure stability with Cherry Picking. E. g. if you use the `sd-icon` component inside your component, you need to import it like this: diff --git a/packages/components/package.json b/packages/components/package.json index 3cfbc7a41e..6821c05680 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,7 +1,7 @@ { "name": "@solid-design-system/components", "description": "Solid Design System: Components", - "version": "5.17.4", + "version": "6.0.0-next.24", "homepage": "https://solid-design-system.fe.union-investment.de/docs/", "author": "Union Investment", "license": "MIT", @@ -60,6 +60,7 @@ }, "scripts": { "build": "node scripts/build.js", + "build.tailwind": "node scripts/build-tailwind-configuration.js", "watch": "pnpm build --watch", "verify": "pnpm build && echo '✅ Build verified' && pnpm ts.verify && pnpm test.verify && echo '✅ Test verified'", "ts.verify": "tsc --noEmit --project ./tsconfig.json && echo '✅ TypeScript verified'", @@ -75,7 +76,8 @@ "@shoelace-style/animations": "^1.2.0", "@shoelace-style/localize": "^3.2.1", "classix": "^2.2.4", - "lit": "^3.3.1" + "lit": "^3.3.1", + "style-observer": "^0.1.2" }, "devDependencies": { "@custom-elements-manifest/analyzer": "^0.10.8", @@ -83,6 +85,9 @@ "@open-wc/testing": "^4.0.0", "@open-wc/testing-helpers": "^3.0.1", "@solid-design-system/versioning": "workspace:^", + "@tailwindcss/node": "^4.1.12", + "@tailwindcss/oxide": "^4.1.12", + "@tailwindcss/postcss": "^4.1.11", "@tarekraafat/autocomplete.js": "^10.2.9", "@types/mocha": "^10.0.10", "@types/sinon": "^17.0.4", @@ -102,9 +107,11 @@ "del": "^8.0.1", "esbuild": "^0.25.10", "esbuild-plugin-replace": "^1.4.0", + "esbuild-plugin-tailwindcss": "^2.0.1", "globby": "^15.0.0", "gzip-size": "^7.0.0", "jsonata": "^2.1.0", + "lightningcss": "^1.30.1", "lit-html": "^3.3.1", "minify-html-literals": "^1.3.5", "ora": "^9.0.0", @@ -113,18 +120,19 @@ "plop": "^4.0.4", "postcss": "^8.5.6", "postcss-import": "^16.1.1", + "postcss-nested": "^7.0.2", "prettier": "^3.6.2", "recursive-copy": "^2.0.14", "sinon": "^21.0.0", - "tailwindcss": "^3.4.17", + "tailwindcss": "^4.1.13", "typescript": "5.8.3", "user-agent-data-types": "^0.4.2" }, "readme": "README.md", "meta": { "bundleSizeInKb": { - "uncompressed": 522, - "gzip": 123 + "uncompressed": 587, + "gzip": 133 } } } diff --git a/packages/components/postcss.config.cjs b/packages/components/postcss.config.cjs deleted file mode 100644 index b063a5f4ab..0000000000 --- a/packages/components/postcss.config.cjs +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - plugins: { - 'postcss-import': {}, - 'tailwindcss/nesting': {}, - tailwindcss: {}, - autoprefixer: {} - } -}; diff --git a/packages/components/scripts/build-tailwind-configuration.js b/packages/components/scripts/build-tailwind-configuration.js new file mode 100644 index 0000000000..e495bc89b3 --- /dev/null +++ b/packages/components/scripts/build-tailwind-configuration.js @@ -0,0 +1,36 @@ +import ora from 'ora'; +import pc from 'picocolors'; +import { execSync } from 'child_process'; +import { cp } from 'fs/promises'; + +const spinner = ora({ hideCursor: false }).start(); + +/** + * Helper function to draw a spinner while tasks run. + */ +async function nextTask(label, action) { + spinner.text = label; + spinner.start(); + + try { + await action(); + spinner.stop(); + console.log(`${pc.green('✔')} ${label}`); + } catch (err) { + spinner.stop(); + console.error(`${pc.red('✘')} ${err}`); + if (err.stdout) console.error(pc.red(err.stdout)); + if (err.stderr) console.error(pc.red(err.stderr)); + process.exit(1); + } +} + +const runTailwindVariablesBuild = () => execSync('pnpm --filter=@solid-design-system/tokens run build'); + +async function buildTailwindConfiguration() { + await nextTask('Building tailwind config', () => { + runTailwindVariablesBuild(); + }); +} + +buildTailwindConfiguration(); diff --git a/packages/components/scripts/build.js b/packages/components/scripts/build.js index f81667bb5c..d529161d45 100644 --- a/packages/components/scripts/build.js +++ b/packages/components/scripts/build.js @@ -143,6 +143,10 @@ async function runBuild() { }); } + await nextTask('Building tailwind configuration', () => { + return execPromise(`node scripts/build-tailwind-configuration.js`, { stdio: 'inherit' }); + }); + await nextTask('Generating Utility CSS', () => { const args = lite ? '--lite' : ''; return execPromise(`node scripts/make-css.js ${args}`, { stdio: 'inherit' }); diff --git a/packages/components/scripts/esbuild-plugin-lit-tailwind-and-minify.js b/packages/components/scripts/esbuild-plugin-lit-tailwind-and-minify.js index 3c7fa9f619..353850bdf9 100644 --- a/packages/components/scripts/esbuild-plugin-lit-tailwind-and-minify.js +++ b/packages/components/scripts/esbuild-plugin-lit-tailwind-and-minify.js @@ -1,18 +1,101 @@ +import { compile, optimize } from '@tailwindcss/node'; import { minifyHTMLLiterals } from 'minify-html-literals'; -import atImportPlugin from 'postcss-import'; +import { readFile } from 'node:fs/promises'; +import { Scanner } from '@tailwindcss/oxide'; import autoprefixer from 'autoprefixer'; -import cssnano from 'cssnano'; -import fs from 'fs/promises'; +import cssnested from 'postcss-nested'; import postcss from 'postcss'; -import tailwindcss from 'tailwindcss'; -import tailwindcssNesting from 'tailwindcss/nesting/index.js'; +import path from 'node:path'; +import tailwindcss from '@tailwindcss/postcss'; +import { fileURLToPath } from 'node:url'; +import atImportPlugin from 'postcss-import'; + +export function minimizeCss(source) { + return optimize(source, { minify: true }).code; +} + +export async function processTailwind( + source, + options = { standalone: false, minify: false, storybook: false, from: undefined, resolveImports: false } +) { + const base = path.resolve(fileURLToPath(import.meta.url), '../../'); + + const prepend = [ + '@layer theme, base, components, utilities;', + `${options.standalone || options.storybook ? '@import' : '@reference'} 'tailwindcss/theme';`, + `${options.standalone || options.storybook ? '@import' : '@reference'} 'tailwindcss/utilities';`, + `${options.standalone ? '@import' : '@reference'} 'tailwindcss/preflight';`, + `${options.standalone ? '@import' : '@reference'} '${path.resolve(base, '../tokens/themes/tailwind.css')}';`, + `${options.standalone ? '@import' : '@reference'} '${path.resolve(base, '../tokens/themes/components.css')}';`, + `@source '${path.resolve(base, '../components/src')}';` + ]; + + if (options.storybook) { + prepend.push(`@source '${path.resolve(base, '../docs/src')}';`); + + /* Safelist */ + prepend.push(`@source inline('w-{1.5}');`); + } + + let css = `${source}`; + + try { + /** + * (Optional) Step 1: Resolve all imports on the css before tailwindcss + */ + if (options.resolveImports) { + css = await postcss([atImportPlugin]) + .process(source, { from: options.from ? options.from : base, onDependency: () => {} }) + .then(r => r.css); + } + + /** + * Step 2: Compile the css content with tailwindcss + */ + css = `${prepend.join('\n')} ${css}`; + + const compiler = await compile(css, { + base: options.from ? options.from : base, + onDependency: () => {} + }); + + let candidates = []; + if (compiler.features > 0) { + let sources = [...compiler.sources]; + if (compiler.root === null) { + sources.push({ base, pattern: '**/*', negated: false }); + } + let scanner = new Scanner({ + sources + }); + candidates = scanner.scan(); + } + + css = compiler.build(candidates); + + /** + * Step 3: Use PostCSS to resolve nested CSS, autoprefix and minify + */ + const plugins = [cssnested, tailwindcss, autoprefixer]; + css = await postcss(plugins) + .process(css, { from: undefined }) + .then(r => r.css); + + if (options.minify) { + return minimizeCss(css); + } + + return css; + } catch (error) { + console.error(`PostCSS error: ${error}`); + return 'postcss error: ' + error; + } +} /** * Escapes tailwind special characters in a string and wraps it in a CSS template literal. * * @param source - The source string where the replacement occurs. - * @param match - The substring to replace in the source string. - * @param content - The string to be escaped and wrapped in a CSS template literal. * @returns The updated source string with the replacement applied. */ export async function processCssTags(source) { @@ -22,26 +105,15 @@ export async function processCssTags(source) { while ((match = cssTagRegex.exec(source)) !== null) { const [fullMatch, cssContent] = match; - try { - const result = await postcss([ - atImportPlugin({ allowDuplicates: false }), - tailwindcssNesting, - tailwindcss, - autoprefixer, - cssnano - ]) - .process(cssContent, { from: undefined }) - .then(result => result.css); - - source = source.replace( - fullMatch, - `css\`${result - .replaceAll('\\', '\\\\') // Escape backslashes - .replaceAll('`', '\\`')}\`` - ); - } catch (error) { - console.error(`PostCSS error: ${error}`); - } + const result = await processTailwind(cssContent, { + standalone: source.includes('default class SolidElement') + }); + source = source.replace( + fullMatch, + `css\`${result + .replaceAll('\\', '\\\\') // Escape backslashes + .replaceAll('`', '\\`')}\`` + ); } return source; @@ -56,19 +128,17 @@ export function litTailwindAndMinifyPlugin(options = {}) { return { name: 'lit-tailwind-and-minify', - setup(build) { - build.onLoad({ filter: includePattern }, async args => { - if (excludePattern.test(args.path)) { + async setup(build) { + build.onLoad({ filter: includePattern }, async ({ path }) => { + if (excludePattern.test(path)) { return; } - // Read the file content - let source = await fs.readFile(args.path, 'utf8'); + let source = await readFile(path, 'utf8'); /** * Step 1: Process CSS in Lit `css` tagged template literals */ - source = await processCssTags(source); /** @@ -123,13 +193,13 @@ export function litTailwindAndMinifyPlugin(options = {}) { const preparedCode = replaceDynamicTags(source); try { - const minified = minifyHTMLLiterals(preparedCode, { fileName: args.path }); + const minified = minifyHTMLLiterals(preparedCode, { fileName: path }); if (minified) { source = restoreDynamicTags(minified.code, true); } } catch (error) { - console.error(`Error minifying HTML literals in ${args.path}: ${error}`); + console.error(`Error minifying HTML literals in ${path}: ${error}`); } // Return the fully transformed code diff --git a/packages/components/scripts/make-css.js b/packages/components/scripts/make-css.js index 2a7a6e603c..c0b4b8d330 100644 --- a/packages/components/scripts/make-css.js +++ b/packages/components/scripts/make-css.js @@ -4,43 +4,19 @@ * CSS to the `dist` directory and a minified version to the `cdn` directory. */ -import atImportPlugin from 'postcss-import'; -import autoprefixer from 'autoprefixer'; -import cssnano from 'cssnano'; import fs from 'fs/promises'; -import postcss from 'postcss'; -import tailwindcss from 'tailwindcss'; -import tailwindcssNesting from 'tailwindcss/nesting/index.js'; -import theme from './postcss-token-variables.js'; +import { processTailwind } from './esbuild-plugin-lit-tailwind-and-minify.js'; (async () => { const lite = process.argv.includes('--lite'); - const css = await fs.readFile('./src/solid-components.css', 'utf8'); - - const result = await postcss([ - atImportPlugin({ allowDuplicates: false }), - tailwindcssNesting, - tailwindcss, - autoprefixer, - theme - ]) - .process(css, { from: undefined }) - .then(result => result.css); + const path = './src/solid-components.css'; + const css = await fs.readFile(path, 'utf8'); + const result = await processTailwind(css); await fs.writeFile('./dist/solid-components.css', result); if (lite) return; - const minifiedResult = await postcss([ - atImportPlugin({ allowDuplicates: false }), - tailwindcssNesting, - tailwindcss, - autoprefixer, - theme, - cssnano - ]) - .process(css, { from: undefined }) - .then(result => result.css); - - await fs.writeFile('./cdn/solid-components.css', minifiedResult); + const minified = await processTailwind(css, { minify: true }); + await fs.writeFile('./cdn/solid-components.css', minified); })(); diff --git a/packages/components/scripts/plop/templates/component/overview.hbs b/packages/components/scripts/plop/templates/component/overview.hbs index 7b51bf9600..00ea0133e5 100644 --- a/packages/components/scripts/plop/templates/component/overview.hbs +++ b/packages/components/scripts/plop/templates/component/overview.hbs @@ -1,4 +1,4 @@ -import { Meta, Canvas } from '@storybook/blocks'; +import { Meta, Canvas } from '@storybook/addon-docs/blocks'; import { OverviewFormatter } from '../../Overview.jsx'; import * as {{ properCase tag }}Stories from './{{ tagWithoutPrefix tag }}.stories'; diff --git a/packages/components/scripts/postcss-token-variables.js b/packages/components/scripts/postcss-token-variables.js deleted file mode 100644 index 129944a713..0000000000 --- a/packages/components/scripts/postcss-token-variables.js +++ /dev/null @@ -1,34 +0,0 @@ -import postcss from 'postcss'; -import getToken from '../../tokens/src/get-token.js'; - -const TOKENS = ['duration']; - -const processors = { - duration: value => `${value}ms` -}; - -function tokens() { - return { - postcssPlugin: 'postcss-token-variables', - Once(root) { - const rootRule = postcss.rule({ selector: ':root' }); - - const theme = TOKENS.map(name => ({ name, tokens: getToken(name) })); - - theme.forEach(({ name, tokens }) => { - Object.entries(tokens).forEach(([key, value]) => { - rootRule.append({ prop: `--sd-${name}-${key}`, value: processors[name]?.(value) ?? value }); - }); - }); - - root.walkAtRules(atRule => { - if (atRule.name === 'solid' && atRule.params.trim() === 'variables') { - atRule.before(rootRule); - atRule.remove(); - } - }); - } - }; -} - -export default Object.assign(tokens, { postcss: true }); diff --git a/packages/components/src/components/accordion-group/accordion-group.ts b/packages/components/src/components/accordion-group/accordion-group.ts index 205c0e887a..121facdd1a 100644 --- a/packages/components/src/components/accordion-group/accordion-group.ts +++ b/packages/components/src/components/accordion-group/accordion-group.ts @@ -65,7 +65,7 @@ export default class SdAccordionGroup extends SolidElement { } ::slotted(sd-accordion:not(:first-of-type)) { - margin-top: -1px; + margin-top: calc(-1 * var(--sd-accordion-border-width)) !important; } ` ]; diff --git a/packages/components/src/components/accordion/accordion.ts b/packages/components/src/components/accordion/accordion.ts index ced0915b64..7fe7ac7d73 100644 --- a/packages/components/src/components/accordion/accordion.ts +++ b/packages/components/src/components/accordion/accordion.ts @@ -39,6 +39,13 @@ import SolidElement from '../../internal/solid-element'; * * @animation accordion.show - The animation to use when showing accordion. You can use `height: auto` with this animation. * @animation accordion.hide - The animation to use when hiding accordion. You can use `height: auto` with this animation. + * + * @cssproperty --sd-accordion-border-width - The accordion border width. + * @cssproperty --sd-accordion-color-background - The accordion background color. + * @cssproperty --sd-accordion-color-text - The accordion color text. + * @cssproperty --sd-accordion-padding-block - The accordion vertical padding value. + * @cssproperty --sd-accordion__chevron-color-text - The accordion chevron color. + * @cssproperty --sd-accordion__indicator-color - The accordion indicator color. */ @customElement('sd-accordion') export default class SdAccordion extends SolidElement { @@ -181,12 +188,12 @@ export default class SdAccordion extends SolidElement { render() { return html` -
+
${this.summary} @@ -233,6 +240,14 @@ export default class SdAccordion extends SolidElement { [part='header']::-webkit-details-marker { @apply hidden; } + + [part='base'] { + border-block-width: var(--sd-accordion-border-width); + } + + [part='summary-icon'] { + color: var(--sd-accordion__chevron-color-text); + } ` ]; } diff --git a/packages/components/src/components/audio/audio.ts b/packages/components/src/components/audio/audio.ts index da968cde4a..6ebd997986 100644 --- a/packages/components/src/components/audio/audio.ts +++ b/packages/components/src/components/audio/audio.ts @@ -293,7 +293,7 @@ export default class SdAudio extends SolidElement { // extracts the numbers from the rgb string const result = rgbString.match(/\d+/g); - if (result && result.length === 3) { + if (result?.length === 3) { const r = parseInt(result[0]); const g = parseInt(result[1]); const b = parseInt(result[2]); @@ -310,19 +310,21 @@ export default class SdAudio extends SolidElement { return null; } + onThemeChange(): void { + this.clear(); + setTimeout(this.initAnimation.bind(this), this.token('--sd-duration-fast', 150)); + } + private initAnimation() { - this.context = this.canvas.getContext('2d')!; + const context = this.canvas?.getContext('2d'); + if (!context) return; + this.context = context; const button = this.audioPlayerContainer.querySelector('.playback-speed')!; const computedStyles = window.getComputedStyle(button); const color = computedStyles.color; - let computedColor: string; - if (this.inverted) { - computedColor = `#FFFFFF33`; - } else { - computedColor = this.rgbToHex(color) + '33'; - } + const computedColor = this.inverted ? `#FFFFFF33` : this.rgbToHex(color) + '33'; this.waveList = [ new Wave({ @@ -482,10 +484,12 @@ export default class SdAudio extends SolidElement { )} part="timestamps" > -
+
${this.currentTime}
-
${this.duration}
+
+ ${this.duration} +
`; return html` @@ -505,7 +509,7 @@ export default class SdAudio extends SolidElement { + `; } @@ -549,7 +554,9 @@ export default class SdAudio extends SolidElement { } :host([inverted]) sd-range::part(thumb) { - @apply bg-white outline-white; + @apply outline-white; + + background-color: rgba(var(--sd-color-border-white, rgba(var(--sd-color-white)))); } :host([animated]) sd-range::part(track) { @@ -557,11 +564,11 @@ export default class SdAudio extends SolidElement { } :host([inverted]:not([animated])) sd-range::part(track) { - @apply bg-primary-400; + background-color: rgba(var(--sd-color-border-primary-400, rgba(var(--sd-color-primary-400)))); } :host([inverted]:not([animated])) sd-range::part(active-track) { - @apply bg-white; + background-color: rgba(var(--sd-color-border-white, rgba(var(--sd-color-white)))); } ` ]; diff --git a/packages/components/src/components/badge/badge.ts b/packages/components/src/components/badge/badge.ts index 7ac2e68511..85e569d260 100644 --- a/packages/components/src/components/badge/badge.ts +++ b/packages/components/src/components/badge/badge.ts @@ -14,6 +14,17 @@ import SolidElement from '../../internal/solid-element'; * * @csspart base - The badge's base wrapper. * @csspart content - The badge's main content. + * + * @cssproperty --sd-badge--blue--inverted-color-background - The background color for the blue badge in its inverted state. + * @cssproperty --sd-badge--blue--inverted-color-text - The text color for the blue badge in its inverted state. + * @cssproperty --sd-badge--green-color--inverted-background - The background color for the green badge in its inverted state. + * @cssproperty --sd-badge--green-color--inverted-text - The text color for the green badge in its inverted state. + * @cssproperty --sd-badge--inverted-color-border - The border color used in inverted state. + * @cssproperty --sd-badge--green-color-background - The background color for the green badge. + * @cssproperty --sd-badge--red--inverted-background - The background color for the red badge in its inverted state. + * @cssproperty --sd-badge--red--inverted-text - The text color for the red badge in its inverted state. + * @cssproperty --sd-badge--red-color-background - The background color for the red badge in its standard state. + * */ @customElement('sd-badge') export default class SdBadge extends SolidElement { @@ -37,9 +48,13 @@ export default class SdBadge extends SolidElement { /* variants */ blue: !this.inverted ? 'text-white bg-primary-500 border-white' - : 'text-primary bg-primary-100 border-primary', - green: !this.inverted ? 'text-white bg-success border-white' : 'text-white bg-success border-primary', - red: !this.inverted ? 'text-white bg-error border-white' : 'text-white bg-error border-primary' + : 'sd-badge--blue--inverted-color-text sd-badge--blue--inverted-color-background sd-badge--inverted-color-border', + green: !this.inverted + ? 'text-white sd-badge--green-color-background border-white' + : 'sd-badge--green-color--inverted-text sd-badge--green-color--inverted-background sd-badge--inverted-color-border', + red: !this.inverted + ? 'text-white sd-badge--red-color-background border-white' + : 'sd-badge--red--inverted-text sd-badge--red--inverted-background sd-badge--inverted-color-border' }[this.variant] )} > diff --git a/packages/components/src/components/brandshape/brandshape.ts b/packages/components/src/components/brandshape/brandshape.ts index f14190e2c0..2fd0aee7c3 100644 --- a/packages/components/src/components/brandshape/brandshape.ts +++ b/packages/components/src/components/brandshape/brandshape.ts @@ -22,6 +22,9 @@ type Breakpoints = 0 | 414 | 640; * @csspart shape-middle - Middle shape. * @csspart shape-bottom - Bottom shape. * @csspart stylized-container - Container for border and image variant. + * + * @cssproperty --sd-brandshape--neutral-100-color-background - The background color using the neutral‑100 variant. + * @cssproperty --sd-brandshape--white-color-background - The background color using the white variant. */ @customElement('sd-brandshape') @@ -206,20 +209,7 @@ export default class SdBrandshape extends SolidElement { const isStylizedVariant = this.variant.startsWith('border-') || this.variant === 'image'; return html` -
+
${isStylizedVariant ? this.renderStylizedVariant() : ''} ${this.renderShapes()}
`; @@ -301,11 +291,11 @@ export default class SdBrandshape extends SolidElement { /* Stylized border */ :host([variant='border-primary']) { - --internal-border-color: rgb(var(--sd-color-primary, 0 53 142)); + --internal-border-color: rgba(var(--sd-color-border-primary, rgba(var(--sd-color-primary)))); } :host([variant='border-white']) { - --internal-border-color: var(--sd-color-white, white); + --internal-border-color: rgba(var(--sd-color-border-white, rgba(var(--sd-color-white)))); } :host([variant^='border-']) [part='stylized-container']::before { @@ -313,6 +303,24 @@ export default class SdBrandshape extends SolidElement { content: ''; border-color: var(--internal-border-color, black); } + + /** + * Dev-note: In some components, css properties need to be assigned + * to specific variables so we keep consistency as in Figma. + * + * For more details, see the 'Consistency with Figma' section in the **CONTRIBUTING.md**. + */ + :host([variant='neutral-100']) [part='base'] { + fill: rgba(var(--sd-brandshape--neutral-100-color-background, rgba(var(--sd-color-neutral-100)))); + } + + :host([variant='white']) [part='base'] { + fill: rgba(var(--sd-color-background-white, rgba(var(--sd-color-white)))); + } + + :host([variant='primary']) [part='base'] { + fill: rgba(var(--sd-color-background-primary, rgba(var(--sd-color-primary)))); + } ` ]; } diff --git a/packages/components/src/components/breadcrumb-item/breadcrumb-item.ts b/packages/components/src/components/breadcrumb-item/breadcrumb-item.ts index 5e360b12a4..af5cdd06b4 100644 --- a/packages/components/src/components/breadcrumb-item/breadcrumb-item.ts +++ b/packages/components/src/components/breadcrumb-item/breadcrumb-item.ts @@ -31,7 +31,7 @@ export default class SdBreadcrumbItem extends SolidElement { /** Tells the browser where to open the link. Only used when `href` is present. */ @property({ type: String, reflect: true }) target: '_blank' | '_parent' | '_self' | '_top'; - /** When set, the attribute `aria-current="page"` will be applied */ + /** When set, the attribute `aria-current="page"` will be applied. */ @property({ type: Boolean, reflect: true }) current = false; @watch('current') @@ -79,10 +79,6 @@ export default class SdBreadcrumbItem extends SolidElement { @apply mr-0 inline-flex; } - sd-link sd-icon { - @apply m-0; - } - :host([current]) sd-link::part(base) { @apply text-neutral-700; } diff --git a/packages/components/src/components/breadcrumb/breadcrumb.test.ts b/packages/components/src/components/breadcrumb/breadcrumb.test.ts index abc3ef20cb..2d49b0f824 100644 --- a/packages/components/src/components/breadcrumb/breadcrumb.test.ts +++ b/packages/components/src/components/breadcrumb/breadcrumb.test.ts @@ -21,19 +21,26 @@ describe('', () => { }); it('should truncate all items except last and second to last', async () => { + // DEV-NOTE: Ignore resize observer loop error. This is happening due to setting the style="width: 10px;" on the breadcrumb. + window.onerror = (message: string) => { + if (message.includes('ResizeObserver loop')) return true; + return false; + }; + await setViewport({ width: 1025, height: 200 }); const el = await fixture(html` Breadcrumb - Breadcrumb - Breadcrumb + + `); + const items = el.querySelectorAll('sd-breadcrumb-item'); + await el.updateComplete; await aTimeout(100); - const items = el.querySelectorAll('sd-breadcrumb-item'); expect(items.item(0).hasAttribute('hidden')).to.be.true; expect(items.item(1).hasAttribute('hidden')).to.be.false; expect(items.item(2).hasAttribute('hidden')).to.be.false; diff --git a/packages/components/src/components/breadcrumb/breadcrumb.ts b/packages/components/src/components/breadcrumb/breadcrumb.ts index 5809516e11..f1e5654316 100644 --- a/packages/components/src/components/breadcrumb/breadcrumb.ts +++ b/packages/components/src/components/breadcrumb/breadcrumb.ts @@ -23,6 +23,7 @@ import SolidElement from '../../internal/solid-element'; * @csspart truncated - The truncated wrapper. * @csspart truncated-dropdown - The truncated dropdown containing the truncated breadcrumbs. * + * @cssproperty --sd-breadcrumb__separator-color - The color of the breadcrumb separators. */ @customElement('sd-breadcrumb') export default class SdBreadcrumb extends SolidElement { @@ -156,13 +157,17 @@ export default class SdBreadcrumb extends SolidElement { @apply block relative; } - sd-dropdown, - ::slotted(sd-breadcrumb-item:not(:last-of-type)) { - @apply after:hidden lg:after:inline-block after:w-1 after:h-1 after:mx-2 after:rounded-full after:bg-neutral-400; + sd-dropdown::after, + ::slotted(sd-breadcrumb-item:not(:last-of-type))::after { + @apply content-[''] hidden lg:inline-block w-1 h-1 mx-2 rounded-full sd-breadcrumb__separator-color; } ::slotted(sd-breadcrumb-item:nth-last-child(2)) { - @apply flex lg:after:bg-accent; + @apply flex; + } + + ::slotted(sd-breadcrumb-item:nth-last-child(2))::after { + @apply lg:bg-accent; } sd-dropdown, diff --git a/packages/components/src/components/button/button.ts b/packages/components/src/components/button/button.ts index d3a99c564b..3b14033785 100644 --- a/packages/components/src/components/button/button.ts +++ b/packages/components/src/components/button/button.ts @@ -35,6 +35,49 @@ import type { SolidFormControl } from '../../internal/solid-element'; * @csspart icon-right - The container that wraps the right icon area. * @csspart motion-wrapper - The container that wraps the motion animation. * + * @cssproperty --sd-button--inverted--disabled-color-background - The background color for inverted buttons in disabled state. + * @cssproperty --sd-button--inverted--disabled-color-border - The border color for inverted buttons in disabled state. + * @cssproperty --sd-button--inverted--disabled-color-text - The text color for inverted buttons in disabled state. + * @cssproperty --sd-button--inverted--active-color-background - The background color for inverted buttons in active state. + * @cssproperty --sd-button--primary--active-color-text - The text color for primary buttons in active state. + * @cssproperty --sd-button--primary--default-color-background - The background color for primary buttons in default state. + * @cssproperty --sd-button--primary--default-color-text - The text color for primary buttons in default state. + * @cssproperty --sd-button--primary--hover-color-background - The background color for primary buttons in hover state. + * @cssproperty --sd-button--primary--inverted--active-color-text - The text color for inverted primary buttons in active state. + * @cssproperty --sd-button--primary--inverted--default-color-background - The background color for inverted primary buttons in default state. + * @cssproperty --sd-button--primary--inverted--default-color-text - The text color for inverted primary buttons in default state. + * @cssproperty --sd-button--primary--inverted--hover-color-background - The background color for inverted primary buttons in hover state. + * @cssproperty --sd-button--primary--inverted--hover-color-text - The text color for inverted primary buttons in hover state. + * @cssproperty --sd-button--secondary--active-color-background - The background color for secondary buttons in active state. + * @cssproperty --sd-button--secondary--hover-color-background - The background color for secondary buttons in hover state. + * @cssproperty --sd-button--secondary--inverted--active-color-background - The background color for inverted secondary buttons in active state. + * @cssproperty --sd-button--secondary--inverted--hover-color-text - The text color for inverted secondary buttons in hover state. + * @cssproperty --sd-button--secondary--inverted--color-border - The border color for inverted secondary buttons. + * @cssproperty --sd-button--secondary--disabled-color-text - The text color for secondary buttons in disabled state. + * @cssproperty --sd-button--tertiary--disabled-color-text - The text color for tertiary buttons in disabled state. + * @cssproperty --sd-button--tertiary--active-color-background - The background color for tertiary buttons in active state. + * @cssproperty --sd-button--tertiary--hover-color-background - The background color for tertiary buttons in hover state. + * @cssproperty --sd-button--tertiary--inverted--hover-color-background - The background color for inverted tertiary buttons in hover state. + * @cssproperty --sd-button--tertiary--inverted--active-color-background - The background color for inverted tertiary buttons in active state. + * @cssproperty --sd-button--secondary--default-color-text - The text color for secondary buttons in default state. + * @cssproperty --sd-button--tertiary--inverted--hover-color-text - The text color for inverted tertiary buttons in hover state. + * @cssproperty --sd-button--tertiary--default-color-text - The text color for tertiary buttons in default state. + * @cssproperty --sd-button--cta--inverted--default-color-background - The background color for inverted CTA buttons in default state. + * @cssproperty --sd-button--cta--inverted--default-color-text - The text color for inverted CTA buttons in default state. + * @cssproperty --sd-button--cta--inverted--active-color-text - The text color for inverted CTA buttons in active state. + * @cssproperty --sd-button--cta--inverted--hover-color-text - The text color for inverted CTA buttons in hover state. + * @cssproperty --sd-button--cta--inverted--hover-color-background - The background color for inverted CTA buttons in hover state. + * @cssproperty --sd-button--cta--inverted--active-color-background - The background color for inverted CTA buttons in active state. + * @cssproperty --sd-button--size-sm-font-size - The small button border radius. + * @cssproperty --sd-button--size-md-font-size - The medium button text font size. + * @cssproperty --sd-button--size-lg-font-size - The large button text font size. + * @cssproperty --sd-button--size-sm-border-radius - The small button border radius. + * @cssproperty --sd-button--size-md-border-radius - The medium button border radius. + * @cssproperty --sd-button--size-lg-border-radius - The large button border radius. + * @cssproperty --sd-button--size-sm-padding-block - The small button vertical padding value. + * @cssproperty --sd-button--size-md-padding-block - The medium button vertical padding value. + * @cssproperty --sd-button--size-lg-padding-block - The large button vertical padding value. + * @cssproperty --sd-button-font-weight - The text font weight for buttons. */ @customElement('sd-button') export default class SdButton extends SolidElement implements SolidFormControl { @@ -268,7 +311,7 @@ export default class SdButton extends SolidElement implements SolidFormControl { class=${cx( `group relative z-10 font-md no-underline w-full align-middle inline-flex items-stretch justify-center - transition-colors duration-fast ease-in-out rounded-default + transition-colors duration-fast ease-in-out select-none cursor-[inherit]`, !this.inverted ? 'focus-visible:focus-outline' : 'focus-visible:focus-outline-inverted', this.loading && 'relative cursor-wait', @@ -279,49 +322,53 @@ export default class SdButton extends SolidElement implements SolidFormControl { * */ { /* sizes, fonts */ - sm: `text-sm varspacing-8 ${hasBorder ? 'py-[0.281rem] px-[0.938rem]' : 'py-[0.344rem] px-4'}`, - md: `text-base varspacing-10 ${hasBorder ? 'py-[0.438rem] px-[0.938rem]' : 'py-2 px-4'}`, - lg: `text-base varspacing-12 ${hasBorder ? 'py-[0.688rem] px-[0.938rem]' : 'py-3 px-4'}` + sm: `sd-button--size-sm-font-size sd-button-font-weight sd-button--size-sm-border-radius varspacing-8 ${hasBorder ? 'py-[0.281rem] px-[0.938rem]' : 'sd-button--size-sm-padding-block px-4'}`, + md: `sd-button--size-md-font-size sd-button-font-weight sd-button--size-md-border-radius varspacing-10 ${hasBorder ? 'py-[0.438rem] px-[0.938rem]' : 'sd-button--size-md-padding-block px-4'}`, + lg: `sd-button--size-lg-font-size sd-button-font-weight sd-button--size-lg-border-radius varspacing-12 ${hasBorder ? 'py-[0.688rem] px-[0.938rem]' : 'sd-button--size-lg-padding-block px-4'}` }[this.size], { /* variants */ primary: !this.inverted - ? `text-white ${ + ? `${ this.visuallyDisabled - ? 'bg-neutral-500 border-neutral-500 hover:bg-neutral-500' - : 'bg-primary border-transparent hover:text-primary-100 active:text-primary-200' + ? 'bg-neutral-500 border-neutral-500 hover:bg-neutral-500 text-white' + : 'sd-button--primary--default-color-background border-transparent sd-button--primary--default-color-text hover:text-primary-100 active:sd-button--primary--active-color-text' } - disabled:bg-neutral-500` + disabled:bg-neutral-500 disabled:text-white` : `${ this.visuallyDisabled ? 'bg-neutral-500 text-white border-neutral-500 hover:bg-neutral-500 active:bg-neutral-500' - : 'text-primary bg-white border-white hover:text-primary-500 active:text-primary-800' + : 'sd-button--primary--inverted--default-color-text sd-button--primary--inverted--default-color-background border-white hover:sd-button--primary--inverted--hover-color-text active:sd-button--primary--inverted--active-color-text active:sd-button--primary--inverted--active-color-background' } - disabled:bg-neutral-600 disabled:text-white disabled:border-neutral-600`, + disabled:sd-button--inverted--disabled-color-background disabled:sd-button--inverted--disabled-color-border disabled:text-white`, secondary: !this.inverted ? `border ${ this.visuallyDisabled - ? 'text-neutral-500 border-neutral-500 hover:text-neutral-500 hover:border-neutral-500 active:text-neutral-500 active:border-neutral-500' - : 'text-primary border-primary hover:text-primary-500 hover:border-primary-500 active:text-primary-800 active:border-primary-800' + ? 'sd-button--secondary--disabled-color-text border-neutral-500 hover:text-neutral-500 hover:border-neutral-500 active:text-neutral-500 active:border-neutral-500' + : 'sd-button--secondary--default-color-text border-primary hover:text-primary-500 hover:border-primary-500 active:text-primary-800 active:border-primary-800' } - disabled:text-neutral-500 disabled:border-neutral-500` + disabled:sd-button--secondary--disabled-color-text disabled:border-neutral-500` : `border ${ this.visuallyDisabled ? 'text-neutral-600 border-neutral-600 hover:text-neutral-600 hover:border-neutral-600 active:text-neutral-600 active:border-neutral-600' - : 'text-white border-white hover:text-primary-100 hover:border-primary-100 active:text-primary-200' + : 'text-white sd-button--secondary--inverted--color-border hover:sd-button--secondary--inverted--hover-color-text hover:border-primary-100 active:text-primary-200' } - disabled:text-neutral-600 disabled:border-neutral-600`, + disabled:sd-button--inverted--disabled-color-border disabled:sd-button--inverted--disabled-color-text`, tertiary: !this.inverted ? `border-transparent ${ this.visuallyDisabled - ? 'text-neutral-500 hover:text-neutral-500 active:text-neutral-500' - : 'text-primary hover:text-primary-500 active:text-primary-800' + ? 'sd-button--tertiary--disabled-color-text hover:text-neutral-500 active:text-neutral-500' + : 'sd-button--tertiary--default-color-text hover:text-primary-500 active:text-primary-800' } - disabled:text-neutral-500` - : `border-transparent ${this.visuallyDisabled ? 'text-neutral-600 hover:text-neutral-600 active:text-neutral-600' : 'text-white hover:text-primary-100 active:text-primary-200'} - disabled:text-neutral-600`, - cta: `text-white ${this.visuallyDisabled ? 'bg-neutral-500 border-neutral-500 hover:bg-neutral-500 active:bg-neutral-500' : 'bg-accent-500 border-transparent'} - ${!this.inverted ? 'disabled:bg-neutral-500 disabled:border-neutral-500' : 'disabled:bg-neutral-600 disabled:border-neutral-600'} disabled:text-white` + disabled:sd-button--tertiary--disabled-color-text` + : `border-transparent ${ + this.visuallyDisabled + ? 'text-neutral-600 hover:text-neutral-600 active:text-neutral-600' + : 'text-white hover:sd-button--tertiary--inverted--hover-color-text hover:sd-button--tertiary--inverted--hover-color-background active:text-primary-200' + } + disabled:sd-button--inverted--disabled-color-text`, + cta: `${this.visuallyDisabled ? 'bg-neutral-500 border-neutral-500 hover:bg-neutral-500 active:bg-neutral-500' : 'bg-accent border-transparent'} + ${!this.inverted ? 'text-white disabled:bg-neutral-500 disabled:border-neutral-500 disabled:text-white' : 'sd-button--cta--inverted--default-color-background sd-button--cta--inverted--default-color-text hover:sd-button--cta--inverted--hover-color-text active:sd-button--cta--inverted--active-color-text disabled:sd-button--inverted--disabled-color-background disabled:sd-button--inverted--disabled-color-border disabled:text-white'}` }[this.variant] )} ?disabled=${ifDefined(isLink ? undefined : this.disabled)} @@ -343,38 +390,48 @@ export default class SdButton extends SolidElement implements SolidFormControl { @click=${this.handleClick} >
@@ -436,10 +493,9 @@ export default class SdButton extends SolidElement implements SolidFormControl { } /* - * Badges: - * Slotted badges are positioned absolutely in the top right corner of the button. - */ - + * Badges: + * Slotted badges are positioned absolutely in the top right corner of the button. + */ ::slotted(sd-badge) { @apply absolute top-0 right-0 !translate-x-1/2 !-translate-y-1/2 pointer-events-none; } @@ -447,7 +503,6 @@ export default class SdButton extends SolidElement implements SolidFormControl { /** * sd-icons should automatically resize correctly based on the button size. */ - ::slotted(sd-icon), sd-loader { font-size: calc(var(--tw-varspacing) / 2); diff --git a/packages/components/src/components/carousel/carousel.ts b/packages/components/src/components/carousel/carousel.ts index 8f4143091a..80cd2f89df 100644 --- a/packages/components/src/components/carousel/carousel.ts +++ b/packages/components/src/components/carousel/carousel.ts @@ -48,6 +48,13 @@ import SolidElement from '../../internal/solid-element.js'; * @cssproperty --slide-gap - The space between each slide. * @cssproperty --scroll-hint - The amount of padding to apply to the scroll area, allowing adjacent slides to become * partially visible as a scroll hint. + * @cssproperty --sd-carousel__pager-dot-border-width - The border width of the pager dots in the carousel. + * @cssproperty --sd-carousel__pager-dot--inverted-background - The background for the pager dots in the inverted carousel when active. + * @cssproperty --sd-carousel__pager-dot--inverted--hovered-background - The background for the pager dots in the inverted carousel when hovered. + * @cssproperty --sd-carousel__pager-dot--inverted-border - The border color for the pager dots in the inverted carousel. + * @cssproperty --sd-carousel__pager-dot-background - The background for the pager dots when active. + * @cssproperty --sd-carousel--active-color-border - The border color for the active pagination item. + * @cssproperty --sd-carousel--active--inverted-color-border - The border color for the active pagination item in inverted carousel. */ @customElement('sd-carousel') export default class SdCarousel extends SolidElement { @@ -691,10 +698,16 @@ export default class SdCarousel extends SolidElement { > @@ -709,7 +722,12 @@ export default class SdCarousel extends SolidElement { > ${currentPage} ` element. * @csspart indeterminate-icon - The indeterminate icon, an `` element. * @csspart label - The container that wraps the checkbox's label. + * + * @cssproperty --sd-checkbox-border-width - The border width of the checkbox. + * @cssproperty --sd-form-control-color-border - The color border for form controls. */ @customElement('sd-checkbox') export default class SdCheckbox extends SolidElement implements SolidFormControl { @@ -246,7 +249,7 @@ export default class SdCheckbox extends SolidElement implements SolidFormControl ? ' control--indeterminate' : ''}" class=${cx( - 'relative flex flex-shrink-0 items-center justify-center border rounded-sm h-4 w-4', + 'relative flex flex-shrink-0 items-center justify-center border sd-checkbox-border-width rounded-sm h-4 w-4', 'transition-colors ease-in-out duration-medium group-hover:duration-fast', 'peer-focus-visible:outline peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-primary', { @@ -263,13 +266,13 @@ export default class SdCheckbox extends SolidElement implements SolidFormControl invalid: 'border-error group-hover:bg-neutral-200', filled: 'border-accent hover:border-accent-550 group-hover:border-accent-550 bg-accent group-hover:bg-accent-550', - default: 'border-neutral-800 hover:bg-neutral-200 group-hover:bg-neutral-200 bg-white' + default: 'form-control-color-border hover:bg-neutral-200 group-hover:bg-neutral-200 bg-white' }[checkboxState] )} >
diff --git a/packages/components/src/components/combobox/combobox.ts b/packages/components/src/components/combobox/combobox.ts index fbeee41e5d..a992ed0946 100644 --- a/packages/components/src/components/combobox/combobox.ts +++ b/packages/components/src/components/combobox/combobox.ts @@ -74,6 +74,8 @@ import type SdPopup from '../popup/popup'; * @csspart expand-icon - The container that wraps the expand icon. * * @cssproperty --tag-max-width - Set the maximum width of the tags and to show an ellipsis. Defaults to "15ch" + * @cssproperty --sd-form-control--invalid-color-background - The background color for form controls in invalid state. + * @cssproperty --sd-form-control-color-text - The text color for form controls. */ @customElement('sd-combobox') @@ -202,6 +204,9 @@ export default class SdCombobox extends SolidElement implements SolidFormControl /** The combobox's required attribute. */ @property({ type: Boolean, reflect: true }) required = false; + /** Enables the floating label behavior for the input. */ + @property({ attribute: 'floating-label', type: Boolean, reflect: true }) floatingLabel = false; + /** * The type of input. Works the same as a native `` element, but only a subset of types are supported. Defaults * to `text`. @@ -1154,6 +1159,9 @@ export default class SdCombobox extends SolidElement implements SolidFormControl const hasLabel = this.label ? true : !!hasLabelSlot; const hasHelpText = this.helpText ? true : !!hasHelpTextSlot; const hasClearIcon = this.clearable && !this.disabled && !this.visuallyDisabled; + const hasIconLeft = slots['left']; + const hasValue = this.value !== null && String(this.value).length > 0; + const isFloatingLabelActive = this.floatingLabel && hasLabel && (this.hasFocus || hasValue); // Hierarchy of input states: const selectState = this.disabled @@ -1182,7 +1190,21 @@ export default class SdCombobox extends SolidElement implements SolidFormControl md: 'text-lg', lg: 'text-xl' }[this.size]; - + const verticalPadding = + this.size === 'lg' + ? !this.floatingLabel + ? 'py-2' + : isFloatingLabelActive + ? 'py-3' + : 'py-4' + : !this.floatingLabel + ? 'py-1' + : isFloatingLabelActive + ? 'py-2' + : 'py-3'; + const floatingLabelHorizontalAlignmentWithIconLeft = { sm: 'left-[36px]', md: 'left-[44px]', lg: 'left-12' }[ + this.size + ]; return html`
- - + ${hasLabel && !this.floatingLabel + ? html`
+ +
` + : null} ${this.deletedTagLabel}
+ ${hasLabel && this.floatingLabel + ? html` + + ` + : null} +
` : ''} ${this.multiple && this.useTags && this.tags.length > 0 - ? html`
${this.tags}
` + ? html`
+ ${this.tags} +
` : null} this.focus()} @invalid=${this.handleInvalid} /> - ${hasClearIcon ? html`
-
- ${this.helpText} -
+ ${this.helpText} +
${this.formControlController.renderInvalidMessage()} `; diff --git a/packages/components/src/components/datepicker/datepicker.test.ts b/packages/components/src/components/datepicker/datepicker.test.ts index 447e91def5..66464bd455 100644 --- a/packages/components/src/components/datepicker/datepicker.test.ts +++ b/packages/components/src/components/datepicker/datepicker.test.ts @@ -61,7 +61,7 @@ describe('', () => { }); it('changes month/year labels when locale changes', async () => { - const el = await fixture(html``); + const el = await fixture(html``); el.show(); await el.updateComplete; @@ -147,7 +147,7 @@ describe('', () => { }); it('formats input as DD.MM.YYYY from value after interaction', async () => { - const el = await fixture(html``); + const el = await fixture(html``); const input = el.shadowRoot!.querySelector('#input')!; input.focus(); @@ -236,19 +236,35 @@ describe('', () => { describe('disabled dates', () => { it('parses disabled-dates JSON string', async () => { - const dates = '2025.11.04,2025.11.12'; + const dates = '2025-11-04,2025-11-12'; const el = await fixture(html``); - expect(el['disabledDatesSet'].has('2025.11.04')).to.be.true; - expect(el['disabledDatesSet'].has('2025.11.12')).to.be.true; + expect(el['disabledDatesSet'].has('2025-11-04')).to.be.true; + expect(el['disabledDatesSet'].has('2025-11-12')).to.be.true; }); it('parses disabled-dates string with spaces', async () => { const el = await fixture( - html`` + html`` ); - expect(el['disabledDatesSet'].has('2025.11.04')).to.be.true; - expect(el['disabledDatesSet'].has('2025.11.12')).to.be.true; + expect(el['disabledDatesSet'].has('2025-11-04')).to.be.true; + expect(el['disabledDatesSet'].has('2025-11-12')).to.be.true; + }); + + it('parses hyphen-separated dates', async () => { + const el = await fixture( + html`` + ); + expect(el['disabledDatesSet'].has('2025-11-11')).to.be.true; + expect(el['disabledDatesSet'].has('2025-11-19')).to.be.true; + }); + + it('parses slash-separated dates', async () => { + const el = await fixture( + html`` + ); + expect(el['disabledDatesSet'].has('2025-11-20')).to.be.true; + expect(el['disabledDatesSet'].has('2025-11-24')).to.be.true; }); }); @@ -337,4 +353,37 @@ describe('', () => { expect(el['currentPlacement']).to.equal('bottom'); }); }); + + describe('required attribute', () => { + it('should make the input a required field when the required attribute is set', async () => { + const el = await fixture(html` `); + const input = el.shadowRoot!.querySelector('#input')!; + + expect(input.checkValidity()).to.be.false; + }); + }); + + describe('min and max attributes', () => { + it('should mark all days before min and after max with disabled attribute', async () => { + const el = await fixture( + html`` + ); + + el.show(); + await el.updateComplete; + + const dayButtons = Array.from(el.shadowRoot!.querySelectorAll('button.day')); + const enabledDays = dayButtons.filter(btn => !btn.classList.contains('disabled')); + + expect(enabledDays.length).to.equal(11); + const input = el.shadowRoot!.querySelector('#input')!; + input.value = '25.12.2025'; + input.dispatchEvent(new Event('input')); + input.dispatchEvent(new Event('blur')); + await el.updateComplete; + + expect(el.checkValidity()).to.be.false; + expect(input.getAttribute('aria-invalid')).to.equal('true'); + }); + }); }); diff --git a/packages/components/src/components/datepicker/datepicker.ts b/packages/components/src/components/datepicker/datepicker.ts index 47a7906f32..c50e977b84 100644 --- a/packages/components/src/components/datepicker/datepicker.ts +++ b/packages/components/src/components/datepicker/datepicker.ts @@ -54,7 +54,92 @@ import type { SolidFormControl } from '../../internal/solid-element'; * @csspart valid-icon - The icon shown when the input is valid. * @csspart form-control-help-text - The help text, displayed below the input. * + * @cssproperty --sd-form-control-color-text - The text color for form controls. */ + +const isoDateConverter = { + fromAttribute(value: string | null): string | null { + if (!value) return null; + + // normalize all separators to hyphens + const cleaned = value.trim().replace(/[./]/g, '-'); + + // acccept YYYY-MM-DD only + const match = cleaned.match(/^(\d{4})-(\d{2})-(\d{2})$/); + if (!match) return null; + + const iso = `${match[1]}-${match[2]}-${match[3]}`; + + // validate date + const d = new Date(+match[1], +match[2] - 1, +match[3]); + if (d.getFullYear() !== +match[1] || d.getMonth() !== +match[2] - 1 || d.getDate() !== +match[3]) { + return null; + } + + return iso; + }, + + toAttribute(value: string | null): string { + return value ?? ''; + } +}; + +const disabledDatesConverter = { + fromAttribute(value: string | null): string[] { + if (!value) return []; + + let rawList: string[] = []; + + const trimmed = value.trim(); + + // arrays + if (trimmed.startsWith('[')) { + try { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const parsed = JSON.parse(trimmed); + if (Array.isArray(parsed)) { + rawList = parsed.map(String); + } + } catch { + return []; + } + } else { + // space separated + rawList = trimmed + .split(/[\s,]+/) + .map(v => v.trim()) + .filter(Boolean); + } + + const result: string[] = []; + + for (const raw of rawList) { + // replace all separators with dots + const cleaned = raw.replace(/[-/]/g, '.'); + const parts = cleaned.split('.'); + + if (parts.length !== 3) continue; + const [yyyy, mm, dd] = parts.map(Number); + + if (!yyyy || !mm || !dd) continue; + + // validate date + const date = new Date(yyyy, mm - 1, dd); + if (date.getFullYear() !== yyyy || date.getMonth() !== mm - 1 || date.getDate() !== dd) continue; + + const iso = `${yyyy}-${String(mm).padStart(2, '0')}-${String(dd).padStart(2, '0')}`; + + result.push(iso); + } + + return result; + }, + + toAttribute(value: string[] | null): string { + return value ? value.join(',') : ''; + } +}; + @customElement('sd-datepicker') export default class SdDatepicker extends SolidElement implements SolidFormControl { /** Localize controller used to fetch localized terms/labels. */ @@ -70,25 +155,27 @@ export default class SdDatepicker extends SolidElement implements SolidFormContr @property({ type: String, reflect: true }) locale = 'en-US'; /** Selected date in local ISO format (YYYY-MM-DD) when not in range mode. */ - @property({ type: String }) value: string | null = null; + @property({ type: String, converter: isoDateConverter, reflect: true }) value: string | null = null; /** Enables date range selection when true. */ @property({ type: Boolean, reflect: true }) range = false; /** Range start date in local ISO format (YYYY-MM-DD). */ - @property({ type: String }) rangeStart: string | null = null; + @property({ attribute: 'range-start', converter: isoDateConverter, reflect: true }) rangeStart: string | null = null; /** Range end date in local ISO format (YYYY-MM-DD). */ - @property({ type: String }) rangeEnd: string | null = null; + @property({ attribute: 'range-end', converter: isoDateConverter, reflect: true }) rangeEnd: string | null = null; /** Allows selecting the same start and end date when true. */ @property({ type: Boolean }) allowSameDayRange = false; /** Minimum selectable date in local ISO format (YYYY-MM-DD). */ - @property({ type: String }) min: string | number | Date | undefined = undefined; + @property({ type: String, converter: isoDateConverter, reflect: true }) min: string | number | Date | undefined = + undefined; /** Maximum selectable date in local ISO format (YYYY-MM-DD). */ - @property({ type: String }) max: string | number | Date | undefined = undefined; + @property({ type: String, converter: isoDateConverter, reflect: true }) max: string | number | Date | undefined = + undefined; /** First day of the week (0=Sun .. 6=Sat). If null, defaults to 1 (Monday). */ @property({ type: Number }) firstDayOfWeek: number | null = null; @@ -97,7 +184,7 @@ export default class SdDatepicker extends SolidElement implements SolidFormContr @property({ type: Boolean, reflect: true, attribute: 'disabled-weekends' }) disabledWeekends = false; /** List of disabled dates as local ISO strings. Accepts array or CSV/JSON string. */ - @property({ attribute: 'disabled-dates' }) disabledDates: string[] | string = []; + @property({ attribute: 'disabled-dates', converter: disabledDatesConverter }) disabledDates: string[] | string = []; /** Custom predicate that can disable specific dates at runtime. */ @property({ attribute: false }) isDateDisabled: ((d: Date) => boolean) | null = null; @@ -114,9 +201,15 @@ export default class SdDatepicker extends SolidElement implements SolidFormContr /** Help text shown below the input. Can be overridden with slot="help-text". */ @property({ type: String, attribute: 'help-text', reflect: true }) helpText = ''; + /** Enables the floating label behavior for the input. */ + @property({ attribute: 'floating-label', type: Boolean, reflect: true }) floatingLabel = false; + /** Disables the control entirely when true. */ @property({ type: Boolean, reflect: true }) disabled = false; + /** Makes the input a required field. */ + @property({ type: Boolean, reflect: true }) required = false; + /** Makes the control non-interactive visually (like disabled) without disabling it functionally. */ @property({ type: Boolean, attribute: 'visually-disabled' }) visuallyDisabled = false; @@ -129,6 +222,7 @@ export default class SdDatepicker extends SolidElement implements SolidFormContr /** Preferred placement of the flyout relative to the input (top|bottom). */ @property({ type: String, reflect: true }) placement: 'top' | 'bottom' = 'bottom'; + /** Placeholder text for the input when no date is selected. */ @property({ type: String, reflect: true }) placeholder: string = ''; /** The name of the datepicker, submitted as a name/value pair with form data. */ @@ -365,8 +459,8 @@ export default class SdDatepicker extends SolidElement implements SolidFormContr } private inMinMax(d: Date): boolean { - const min = this.parseISO(this.min !== null ? String(this.min) : null); - const max = this.parseISO(this.max !== null ? String(this.max) : null); + const min = this.min === null ? null : this.parseISO(String(this.min)); + const max = this.max === null ? null : this.parseISO(String(this.max)); if (min && d < min) return false; if (max && d > max) return false; @@ -376,7 +470,10 @@ export default class SdDatepicker extends SolidElement implements SolidFormContr /** Returns true if the date matches any date in disabledDatesSet. */ private isInDisabledDates(d: Date): boolean { if (!this.disabledDatesSet || this.disabledDatesSet.size === 0) return false; - const iso = DateUtils.toLocalISODate(DateUtils.startOfDayLocal(d)); + const yyyy = d.getFullYear(); + const mm = String(d.getMonth() + 1).padStart(2, '0'); + const dd = String(d.getDate()).padStart(2, '0'); + const iso = `${yyyy}-${mm}-${dd}`; return this.disabledDatesSet.has(iso); } @@ -476,7 +573,11 @@ export default class SdDatepicker extends SolidElement implements SolidFormContr /** UI formatting: internal ISO → DD.MM.YYYY */ private isoToDmy(iso: string | null): string { if (!iso) return ''; - const d = DateUtils.parseLocalISO(iso); + let d = DateUtils.parseLocalISO(iso); + if (!d) { + // try replacing hyphens with dots (old behavior) + d = DateUtils.parseLocalISO(iso.replace(/-/g, '.')); + } if (!d) return ''; const dd = String(d.getDate()).padStart(2, '0'); const mm = String(d.getMonth() + 1).padStart(2, '0'); @@ -647,6 +748,8 @@ export default class SdDatepicker extends SolidElement implements SolidFormContr // Single const singleIso = parsed.single ?? null; if (!inBoundsIso(singleIso)) { + this.input.setCustomValidity(this.localize.term('datePickerRange')); + this.formControlController.setValidity(false); this.showInvalidStyle = true; this.showValidStyle = false; return false; @@ -1635,7 +1738,7 @@ export default class SdDatepicker extends SolidElement implements SolidFormContr > ${week.map((day, colIndex) => { const inMonth = day.getMonth() === this.viewMonth.getMonth(); - const disabled = this.isDisabled(day); + const disabled = this.isDisabled(day) || !this.inMinMax(day); const isFocused = DateUtils.isSameDay(day, this.focusedDate); const isToday = DateUtils.isSameDay(day, this.today); @@ -1685,7 +1788,7 @@ export default class SdDatepicker extends SolidElement implements SolidFormContr : isWeekendDay ? 'out-month weekend-day text-neutral-700' : 'out-month text-neutral-700' - : this.isInDisabledDates(day) + : this.isInDisabledDates(day) || !this.inMinMax(day) ? 'out-month text-neutral-500' : this.disabledWeekends && isWeekendDay ? 'weekend-day text-neutral-500' @@ -1704,7 +1807,7 @@ export default class SdDatepicker extends SolidElement implements SolidFormContr isToday && !isSelectedSingle && !isRangeStart && !isRangeEnd && isFocused ? 'today border-[1px] border-primary font-bold' : '', - disabled ? 'disabled cursor-not-allowed hover:bg-transparent' : '', + disabled ? 'disabled cursor-not-allowed hover:bg-transparent' : 'cursor-pointer', isFocused && !isToday ? 'focused outline outline-2 outline-primary' : '' )} role="gridcell" @@ -1749,6 +1852,16 @@ export default class SdDatepicker extends SolidElement implements SolidFormContr const hasLabel = this.label ? true : !!slots['label']; const hasHelpText = this.helpText ? true : !!slots['helpText']; const hasTooltip = !!slots['tooltip']; + const hasValue = + (this.value !== null && String(this.value).length > 0) || + (this.range && this.rangeStart !== null) || + this.rangeEnd !== null; + const isFloatingLabelActive = + this.floatingLabel && + hasLabel && + (this.hasFocus || this.open || hasValue) && + !this.disabled && + !this.visuallyDisabled; const iconColor = this.disabled || this.visuallyDisabled ? 'text-neutral-500' : 'text-primary'; const iconMarginLeft = { sm: 'ml-1', md: 'ml-2', lg: 'ml-2' }[this.size]; @@ -1794,12 +1907,12 @@ export default class SdDatepicker extends SolidElement implements SolidFormContr (this.disabled || this.visuallyDisabled) && 'cursor-not-allowed' )} > - ${hasLabel || hasTooltip + ${(hasLabel && !this.floatingLabel) || hasTooltip ? html`
+ > + ${hasLabel && this.floatingLabel + ? html` + + ` + : null} +
this.requestClose('overlay')} tabindex="-1" >
@@ -283,7 +285,7 @@ export default class SdDialog extends SolidElement {