From 553297f720fd198260b23518ec1739a24ffbb940 Mon Sep 17 00:00:00 2001 From: Sheila Sheikh <166654065+sheila-semrush@users.noreply.github.com> Date: Sat, 19 Jul 2025 03:10:52 +0200 Subject: [PATCH 1/2] [button, input, select] header controls draft --- pnpm-lock.yaml | 36 +++++++- semcore/header-controls/.npmignore | 4 + semcore/header-controls/CHANGELOG.md | 9 ++ semcore/header-controls/README.md | 39 +++++++++ semcore/header-controls/package.json | 40 +++++++++ .../src/components/button/Button.tsx | 23 +++++ .../src/components/button/button.shadow.css | 84 +++++++++++++++++++ .../src/components/input/Input.tsx | 19 +++++ .../src/components/input/input.shadow.css | 28 +++++++ .../src/components/select/Select.tsx | 30 +++++++ .../header-controls/src/components/vars.css | 49 +++++++++++ semcore/header-controls/src/index.ts | 4 + .../button-trigger/ButtonTrigger.tsx | 19 +++++ .../button-trigger/buttonTrigger.shadow.css | 19 +++++ semcore/header-controls/tsconfig.json | 4 + semcore/header-controls/vite.config.ts | 33 ++++++++ semcore/ui/package.json | 1 + .../tests/button_tests.stories.tsx | 14 ++++ .../tests/examples/header-controls.tsx | 51 +++++++++++ website/docs/components/button/button-code.md | 2 +- .../style/design-tokens/design-tokens.json | 7 +- 21 files changed, 509 insertions(+), 6 deletions(-) create mode 100644 semcore/header-controls/.npmignore create mode 100644 semcore/header-controls/CHANGELOG.md create mode 100644 semcore/header-controls/README.md create mode 100644 semcore/header-controls/package.json create mode 100644 semcore/header-controls/src/components/button/Button.tsx create mode 100644 semcore/header-controls/src/components/button/button.shadow.css create mode 100644 semcore/header-controls/src/components/input/Input.tsx create mode 100644 semcore/header-controls/src/components/input/input.shadow.css create mode 100644 semcore/header-controls/src/components/select/Select.tsx create mode 100644 semcore/header-controls/src/components/vars.css create mode 100644 semcore/header-controls/src/index.ts create mode 100644 semcore/header-controls/src/inner-components/button-trigger/ButtonTrigger.tsx create mode 100644 semcore/header-controls/src/inner-components/button-trigger/buttonTrigger.shadow.css create mode 100644 semcore/header-controls/tsconfig.json create mode 100644 semcore/header-controls/vite.config.ts create mode 100644 stories/components/header-controls/tests/button_tests.stories.tsx create mode 100644 stories/components/header-controls/tests/examples/header-controls.tsx diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cf5518580d..3c8cbddd33 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1358,6 +1358,31 @@ importers: specifier: ^16.0.0 version: 16.0.0(@semcore/core@semcore+core) + semcore/header-controls: + dependencies: + '@semcore/base-trigger': + specifier: ^16.0.0 + version: link:../base-trigger + '@semcore/button': + specifier: ^16.0.0 + version: link:../button + '@semcore/input': + specifier: ^16.0.0 + version: link:../input + '@semcore/select': + specifier: ^16.0.0 + version: link:../select + '@semcore/typography': + specifier: ^16.0.0 + version: link:../typography + devDependencies: + '@semcore/base-components': + specifier: workspace:* + version: link:../base-components + '@semcore/testing-utils': + specifier: workspace:* + version: link:../../tools/testing-utils + semcore/i18n-unplugin: dependencies: '@semcore/core': @@ -2402,6 +2427,9 @@ importers: '@semcore/grid': specifier: 16.0.0 version: 16.0.0(@semcore/base-components@16.0.0(@semcore/core@16.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3))) + '@semcore/header-controls': + specifier: 16.0.0 + version: link:../header-controls '@semcore/i18n-unplugin': specifier: 16.0.0 version: 16.0.0(@semcore/core@16.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.8.3)) @@ -3011,7 +3039,7 @@ importers: version: 0.14.29 vitest-axe: specifier: 0.1.0 - version: 0.1.0(vitest@3.0.9(@types/debug@4.1.12)(@types/node@22.15.30)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(happy-dom@9.20.3)(jsdom@22.1.0)(less@3.13.1)(msw@2.9.0(@types/node@22.15.30)(typescript@5.8.3))(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0)) + version: 0.1.0(vitest@3.0.9(@types/debug@4.1.12)(@types/node@22.15.30)(@vitest/browser@3.0.6(@types/node@18.16.15)(playwright@1.48.0)(typescript@5.8.3)(vite@6.3.5(@types/node@18.16.15)(less@3.13.1)(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0))(vitest@3.0.9)(webdriverio@8.24.3(typescript@5.8.3)))(@vitest/ui@3.0.6(vitest@3.0.9))(happy-dom@9.20.3)(jsdom@22.1.0)(less@3.13.1)(msw@2.9.0(@types/node@22.15.30)(typescript@5.8.3))(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0)) website: dependencies: @@ -28700,7 +28728,7 @@ snapshots: - typescript - universal-cookie - vitest-axe@0.1.0(vitest@3.0.9(@types/debug@4.1.12)(@types/node@22.15.30)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(happy-dom@9.20.3)(jsdom@22.1.0)(less@3.13.1)(msw@2.9.0(@types/node@22.15.30)(typescript@5.8.3))(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0)): + vitest-axe@0.1.0(vitest@3.0.9(@types/debug@4.1.12)(@types/node@22.15.30)(@vitest/browser@3.0.6(@types/node@18.16.15)(playwright@1.48.0)(typescript@5.8.3)(vite@6.3.5(@types/node@18.16.15)(less@3.13.1)(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0))(vitest@3.0.9)(webdriverio@8.24.3(typescript@5.8.3)))(@vitest/ui@3.0.6(vitest@3.0.9))(happy-dom@9.20.3)(jsdom@22.1.0)(less@3.13.1)(msw@2.9.0(@types/node@22.15.30)(typescript@5.8.3))(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0)): dependencies: aria-query: 5.3.2 axe-core: 4.9.1 @@ -28708,7 +28736,7 @@ snapshots: dom-accessibility-api: 0.5.16 lodash-es: 4.17.21 redent: 3.0.0 - vitest: 3.0.9(@types/debug@4.1.12)(@types/node@22.15.30)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(happy-dom@9.20.3)(jsdom@22.1.0)(less@3.13.1)(msw@2.9.0(@types/node@22.15.30)(typescript@5.8.3))(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0) + vitest: 3.0.9(@types/debug@4.1.12)(@types/node@22.15.30)(@vitest/browser@3.0.6(@types/node@18.16.15)(playwright@1.48.0)(typescript@5.8.3)(vite@6.3.5(@types/node@18.16.15)(less@3.13.1)(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0))(vitest@3.0.9)(webdriverio@8.24.3(typescript@5.8.3)))(@vitest/ui@3.0.6(vitest@3.0.9))(happy-dom@9.20.3)(jsdom@22.1.0)(less@3.13.1)(msw@2.9.0(@types/node@22.15.30)(typescript@5.8.3))(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0) vitest@3.0.9(@types/debug@4.1.12)(@types/node@18.16.15)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(happy-dom@9.20.3)(jsdom@22.1.0)(less@3.13.1)(msw@2.9.0(@types/node@18.16.15)(typescript@5.8.3))(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0): dependencies: @@ -28753,7 +28781,7 @@ snapshots: - tsx - yaml - vitest@3.0.9(@types/debug@4.1.12)(@types/node@22.15.30)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(happy-dom@9.20.3)(jsdom@22.1.0)(less@3.13.1)(msw@2.9.0(@types/node@22.15.30)(typescript@5.8.3))(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0): + vitest@3.0.9(@types/debug@4.1.12)(@types/node@22.15.30)(@vitest/browser@3.0.6(@types/node@18.16.15)(playwright@1.48.0)(typescript@5.8.3)(vite@6.3.5(@types/node@18.16.15)(less@3.13.1)(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0))(vitest@3.0.9)(webdriverio@8.24.3(typescript@5.8.3)))(@vitest/ui@3.0.6(vitest@3.0.9))(happy-dom@9.20.3)(jsdom@22.1.0)(less@3.13.1)(msw@2.9.0(@types/node@22.15.30)(typescript@5.8.3))(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0): dependencies: '@vitest/expect': 3.0.9 '@vitest/mocker': 3.0.9(msw@2.9.0(@types/node@22.15.30)(typescript@5.8.3))(vite@6.3.5(@types/node@22.15.30)(less@3.13.1)(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0)) diff --git a/semcore/header-controls/.npmignore b/semcore/header-controls/.npmignore new file mode 100644 index 0000000000..229b5c941a --- /dev/null +++ b/semcore/header-controls/.npmignore @@ -0,0 +1,4 @@ +node_modules +__tests__ +src +tsconfig.json \ No newline at end of file diff --git a/semcore/header-controls/CHANGELOG.md b/semcore/header-controls/CHANGELOG.md new file mode 100644 index 0000000000..f514ba3967 --- /dev/null +++ b/semcore/header-controls/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +CHANGELOG.md standards are inspired by [keepachangelog.com](https://keepachangelog.com/en/1.0.0/). + +## [16.0.0] - 2025-07-18 + +### Added + +- Initial release. diff --git a/semcore/header-controls/README.md b/semcore/header-controls/README.md new file mode 100644 index 0000000000..dab6ccf80f --- /dev/null +++ b/semcore/header-controls/README.md @@ -0,0 +1,39 @@ +# @semcore/header-controls + +[![version](https://img.shields.io/npm/v/@semcore/core.svg)](https://www.npmjs.com/@semcore/header-controls) +[![downloads](https://img.shields.io/npm/dt/@semcore/core.svg)](https://www.npmjs.com/package/@semcore/header-controls) +[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/semrush/intergalactic/blob/master/LICENSE) + +> This component is part of the Intergalactic Design System + +[//]: # '### 📖 [Component documentation](https://developer.semrush.com/intergalactic/components/core/)' + +### 🏠 [Design system](https://developer.semrush.com/intergalactic/) + +## Install + +```sh +npm install @semcore/header-controls +``` + + + +## 👤 Author + +[UI-kit team](https://github.com/semrush/intergalactic/blob/master/MAINTAINERS) +and [others ❤️](https://github.com/semrush/intergalactic/graphs/contributors) + +## 🤝 Contributing + +Contributions, issues and feature requests are welcome! + +Feel free to check [issues page](https://github.com/semrush/intergalactic/issues). You can also take a look at +the [contributing guide](https://github.com/semrush/intergalactic/blob/master/CONTRIBUTING.md). + +## Show your support + +Give a ⭐️ if this project helped you! + +## 📝 License + +This project is [MIT](https://github.com/semrush/intergalactic/blob/master/LICENSE) licensed. diff --git a/semcore/header-controls/package.json b/semcore/header-controls/package.json new file mode 100644 index 0000000000..6fe5a14e1c --- /dev/null +++ b/semcore/header-controls/package.json @@ -0,0 +1,40 @@ +{ + "name": "@semcore/header-controls", + "description": "Semrush toolkit for global header", + "version": "16.0.1", + "main": "lib/cjs/index.js", + "module": "lib/esm/index.mjs", + "typings": "lib/types/index.d.ts", + "sideEffects": false, + "author": "UI-kit team ", + "license": "MIT", + "scripts": { + "build": "pnpm semcore-builder && pnpm vite build" + }, + "exports": { + ".": { + "require": "./lib/cjs/index.js", + "import": "./lib/esm/index.mjs", + "types": "./lib/types/index.d.ts" + } + }, + "dependencies": { + "@semcore/base-trigger": "^16.0.0", + "@semcore/button": "^16.0.0", + "@semcore/input": "^16.0.0", + "@semcore/select": "^16.0.0", + "@semcore/typography": "^16.0.0" + }, + "peerDependencies": { + "@semcore/base-components": "^16.0.0" + }, + "repository": { + "type": "git", + "url": "https://github.com/semrush/intergalactic.git", + "directory": "semcore/header-controls" + }, + "devDependencies": { + "@semcore/base-components": "workspace:*", + "@semcore/testing-utils": "workspace:*" + } +} diff --git a/semcore/header-controls/src/components/button/Button.tsx b/semcore/header-controls/src/components/button/Button.tsx new file mode 100644 index 0000000000..89fd195a4d --- /dev/null +++ b/semcore/header-controls/src/components/button/Button.tsx @@ -0,0 +1,23 @@ +import Button from '@semcore/button'; +import { createComponent, Root, sstyled, Component } from '@semcore/core'; +import React from 'react'; + +import style from './button.shadow.css'; + +class HeaderButtonRoot extends Component { + static displayName = 'HeaderButton'; + static style = style; + + static defaultProps = { + theme: 'invert', + }; + + render() { + const SHeaderButton = Root; + return sstyled(this.asProps.styles)( + , + ); + } +} + +export const HeaderButton = createComponent(HeaderButtonRoot) as typeof Button; diff --git a/semcore/header-controls/src/components/button/button.shadow.css b/semcore/header-controls/src/components/button/button.shadow.css new file mode 100644 index 0000000000..c768d2e54c --- /dev/null +++ b/semcore/header-controls/src/components/button/button.shadow.css @@ -0,0 +1,84 @@ +@import '../vars.css'; + +SHeaderButton[size='m'] { + /* disable-tokens-validator */ + height: var(--intergalactic-header-control-m, 32px); + /* disable-tokens-validator */ + min-width: var(--intergalactic-header-control-m, 32px); + /* we should have min-width in the default button styles, instead of the only-child margin calculations */ +} + +SAddon { + &:not(:only-child):first-child { + margin-left: var(--intergalactic-spacing-3x, 12px); + } + + &:not(:only-child):last-child { + margin-right: var(--intergalactic-spacing-3x, 12px); + } +} + +SText { + margin-left: var(--intergalactic-spacing-2x, 8px); + margin-right: var(--intergalactic-spacing-2x, 8px); + + &:first-child { + margin-left: var(--intergalactic-spacing-3x, 12px); + } + &:last-child { + margin-right: var(--intergalactic-spacing-3x, 12px); + } +} + +SHeaderButton[neighborLocation='both'], +SHeaderButton[neighborLocation='left'] { + &:after { + /* disable-tokens-validator */ + background-color: var(--intergalactic-border-primary-header); + } +} + +SHeaderButton[theme='secondary-invert'] { + /* disable-tokens-validator */ + background-color: var(--intergalactic-control-secondary-header); + /* disable-tokens-validator */ + border-color: var(--intergalactic-border-primary-header); + + &:hover { + /* disable-tokens-validator */ + background-color: var(--intergalactic-control-secondary-header-hover); + } + + &:active { + /* disable-tokens-validator */ + background-color: var(--intergalactic-control-secondary-header-active); + } + + &[neighborLocation='both'], + &[neighborLocation='left'] { + &:after { + /* disable-tokens-validator */ + background-color: var(--intergalactic-border-secondary-header); + } + } + + :not(SButton) + &[neighborLocation='left'], + :not(SButton) + &[neighborLocation='both'] { + /* disable-tokens-validator */ + border-left-color: var(--intergalactic-border-secondary-header); + } +} + +SHeaderButton[theme='tertiary-invert'] { + &:not(:hover, :active) { + color: var(--intergalactic-text-secondary-invert, rgba(255, 255, 255, 0.8)); + } + &:hover { + /* disable-tokens-validator */ + background-color: var(--intergalactic-control-tertiary-header-hover); + } + &:active { + /* disable-tokens-validator */ + background-color: var(--intergalactic-control-tertiary-header-active); + } +} diff --git a/semcore/header-controls/src/components/input/Input.tsx b/semcore/header-controls/src/components/input/Input.tsx new file mode 100644 index 0000000000..8615371c8a --- /dev/null +++ b/semcore/header-controls/src/components/input/Input.tsx @@ -0,0 +1,19 @@ +import { Component, createComponent, Root, sstyled } from '@semcore/core'; +import Input from '@semcore/input'; +import React from 'react'; + +import style from './input.shadow.css'; + +class HeaderInputRoot extends Component { + static displayName = 'HeaderInput'; + static style = style; + + render() { + const SHeaderInput = Root; + return sstyled(this.asProps.styles)( + , + ); + } +} + +export const HeaderInput = createComponent(HeaderInputRoot) as typeof Input; diff --git a/semcore/header-controls/src/components/input/input.shadow.css b/semcore/header-controls/src/components/input/input.shadow.css new file mode 100644 index 0000000000..3802282271 --- /dev/null +++ b/semcore/header-controls/src/components/input/input.shadow.css @@ -0,0 +1,28 @@ +@import '../vars.css'; + +SHeaderInput[size='m'] { + /* disable-tokens-validator */ + height: var(--intergalactic-header-control-m); +} + +SHeaderInput:not(:has(SValue:focus)) { + &:not(:hover) SOutline { + /* disable-tokens-validator */ + background: var(--intergalactic-control-secondary-header); + } + &:hover SOutline { + /* disable-tokens-validator */ + background: var(--intergalactic-control-secondary-header-hover); + } + &[state='normal'] SOutline { + /* disable-tokens-validator */ + border-color: var(--intergalactic-border-primary-header); + } +} + +SValue:not(:focus) { + &::placeholder { + /* disable-tokens-validator */ + color: var(--intergalactic-text-placeholder-header); + } +} \ No newline at end of file diff --git a/semcore/header-controls/src/components/select/Select.tsx b/semcore/header-controls/src/components/select/Select.tsx new file mode 100644 index 0000000000..77b5d64771 --- /dev/null +++ b/semcore/header-controls/src/components/select/Select.tsx @@ -0,0 +1,30 @@ +import type { IRootComponentProps } from '@semcore/core'; +import { createComponent, Root, Component } from '@semcore/core'; +import Select from '@semcore/select'; +import React from 'react'; + +import { HeaderButtonTrigger } from '../../inner-components/button-trigger/ButtonTrigger'; + +class HeaderSelectRoot extends Component { + static displayName = 'HeaderSelect'; + + render() { + return ( + + ); + } +} + +function Trigger(props: IRootComponentProps) { + return ( + + ); +} + +export const HeaderSelect = createComponent(HeaderSelectRoot, { + Trigger, + Popper: Select.Popper, + Menu: Select.Menu, + Option: Select.Option, + List: Select.List, +}) as typeof Select; diff --git a/semcore/header-controls/src/components/vars.css b/semcore/header-controls/src/components/vars.css new file mode 100644 index 0000000000..48efbc9373 --- /dev/null +++ b/semcore/header-controls/src/components/vars.css @@ -0,0 +1,49 @@ +SHeaderButton, SHeaderInput, SHeaderButtonTrigger { + /* ====== REMOVE ALL COMMENTS AFTER REVIEW ====== */ + + /* I decided to add new semantic tokens locally for convenience, + you can either add them to the token list, or remove them and instead + define the corresponding CSS properties with raw values */ + + --intergalactic-header-control-m: var(--intergalactic-spacing-8x, 32px); + --intergalactic-border-primary-header: transparent; + --intergalactic-border-secondary-header: rgba(255, 255, 255, 0.15); /* white 0.15 */ + --intergalactic-control-secondary-header: #4D407E; /* violet-dusty-600 */ + --intergalactic-control-secondary-header-hover: #6D619F; /* violet-dusty-500 */ + /* disable-tokens-validator */ + --intergalactic-control-secondary-header-active: hsl(from var(--intergalactic-control-secondary-header-hover) h s calc(l * 1.15)); + /* relative color support is around 80% on desktop globally, but we probably can + skip adding a fallback because the active state is not that critical */ + --intergalactic-control-tertiary-header-hover: #4D407E; /* violet-dusty-600 */ + --intergalactic-control-tertiary-header-active: #6D619F; /* violet-dusty-500 */ + --intergalactic-text-placeholder-header: rgba(255, 255, 255, 0.8); + + /* + --violet-dusty-400: #9083C5; + --violet-dusty-500: #6D619F; + --violet-dusty-600: #4D407E; + */ +} + + +/* ====================== NOTES ====================== */ + +/* 1. Issues with theme processing + + - if we redefine imported tokens locally, fallbacks stay the same (i.e. if import fails, styles will break) + - we don't process base tokens + - we don't process local tokens (defined in this file) + */ + + +/* 2. Alternative for active state (instead of relative color) + support is much better - 97%, but requires changing border and border-radius */ + +/* border: none; + SInner { + border-radius: inherit; + } + &[theme='secondary-invert']:active SInner { + backdrop-filter: brightness(1.25) saturate(0.8); + } */ + diff --git a/semcore/header-controls/src/index.ts b/semcore/header-controls/src/index.ts new file mode 100644 index 0000000000..f94e904878 --- /dev/null +++ b/semcore/header-controls/src/index.ts @@ -0,0 +1,4 @@ +export * from './components/button/Button'; +export * from './components/input/Input'; +export * from './components/select/Select'; +export * from './inner-components/button-trigger/ButtonTrigger'; // for testing, remove later diff --git a/semcore/header-controls/src/inner-components/button-trigger/ButtonTrigger.tsx b/semcore/header-controls/src/inner-components/button-trigger/ButtonTrigger.tsx new file mode 100644 index 0000000000..4d0e44def8 --- /dev/null +++ b/semcore/header-controls/src/inner-components/button-trigger/ButtonTrigger.tsx @@ -0,0 +1,19 @@ +import { ButtonTrigger } from '@semcore/base-trigger'; +import { createComponent, Root, sstyled, Component } from '@semcore/core'; +import React from 'react'; + +import style from './buttonTrigger.shadow.css'; + +class HeaderButtonTriggerRoot extends Component { + static displayName = 'HeaderButtonTrigger'; + static style = style; + + render() { + const SHeaderButtonTrigger = Root; + return sstyled(this.asProps.styles)( + , + ); + } +} + +export const HeaderButtonTrigger = createComponent(HeaderButtonTriggerRoot) as typeof ButtonTrigger; diff --git a/semcore/header-controls/src/inner-components/button-trigger/buttonTrigger.shadow.css b/semcore/header-controls/src/inner-components/button-trigger/buttonTrigger.shadow.css new file mode 100644 index 0000000000..ce139fc2ac --- /dev/null +++ b/semcore/header-controls/src/inner-components/button-trigger/buttonTrigger.shadow.css @@ -0,0 +1,19 @@ +@import '../../components/vars.css'; + +SHeaderButtonTrigger { + + /* disable-tokens-validator */ + background-color: var(--intergalactic-control-secondary-header); + /* disable-tokens-validator */ + border-color: var(--intergalactic-border-primary-header); + color: var(--intergalactic-text-primary-invert, #ffffff); + &:hover { + /* disable-tokens-validator */ + background-color: var(--intergalactic-control-secondary-header-hover); + } +} + +SHeaderButtonTrigger[size='m'] { + /* disable-tokens-validator */ + height: var(--intergalactic-header-control-m); +} \ No newline at end of file diff --git a/semcore/header-controls/tsconfig.json b/semcore/header-controls/tsconfig.json new file mode 100644 index 0000000000..596e2cf729 --- /dev/null +++ b/semcore/header-controls/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../../tsconfig.json", + "include": ["src"] +} diff --git a/semcore/header-controls/vite.config.ts b/semcore/header-controls/vite.config.ts new file mode 100644 index 0000000000..b6d956ee9a --- /dev/null +++ b/semcore/header-controls/vite.config.ts @@ -0,0 +1,33 @@ +import copy from 'rollup-plugin-copy'; +import { defineConfig, mergeConfig } from 'vite'; + +import viteConfig from '../../commonVite.config'; + +export default mergeConfig( + viteConfig, + defineConfig({ + build: { + lib: { + entry: './src/index.ts', + }, + rollupOptions: { + external: [ + 'react', + 'react-dom', + 'react/jsx-runtime', + /@babel\/runtime\/*/, + /@semcore\/*/, + ], + plugins: [ + // @ts-ignore + copy({ + targets: [ + { src: 'src/theme/**/*.css', dest: 'lib/esm' }, + ], + flatten: false, + }), + ], + }, + }, + }), +); diff --git a/semcore/ui/package.json b/semcore/ui/package.json index ea90e5bf2e..e0e2113e9e 100644 --- a/semcore/ui/package.json +++ b/semcore/ui/package.json @@ -46,6 +46,7 @@ "@semcore/format-text": "16.0.0", "@semcore/fullscreen-modal": "16.0.0", "@semcore/grid": "16.0.0", + "@semcore/header-controls": "16.0.0", "@semcore/i18n-unplugin": "16.0.0", "@semcore/icon": "16.0.0", "@semcore/illustration": "16.0.0", diff --git a/stories/components/header-controls/tests/button_tests.stories.tsx b/stories/components/header-controls/tests/button_tests.stories.tsx new file mode 100644 index 0000000000..912a41725c --- /dev/null +++ b/stories/components/header-controls/tests/button_tests.stories.tsx @@ -0,0 +1,14 @@ +import type { Meta, StoryObj } from '@storybook/react-vite'; + +import HeaderControlsExample from './examples/header-controls'; + +const meta: Meta = { + title: 'Components/Header controls/Tests', +}; + +export default meta; +type Story = StoryObj; + +export const HeaderControls: Story = { + render: HeaderControlsExample, +}; diff --git a/stories/components/header-controls/tests/examples/header-controls.tsx b/stories/components/header-controls/tests/examples/header-controls.tsx new file mode 100644 index 0000000000..25a7c1e13c --- /dev/null +++ b/stories/components/header-controls/tests/examples/header-controls.tsx @@ -0,0 +1,51 @@ +import { Flex } from '@semcore/base-components'; +import Button from '@semcore/button'; +import { HeaderButton, HeaderInput, HeaderButtonTrigger } from '@semcore/header-controls'; +import Chevron from '@semcore/icon/ChevronDown/m'; +import Search from '@semcore/icon/Search/m'; +import Input from '@semcore/input'; +import React from 'react'; + +const Demo = () => { + return ( + + + Log in + + + + + + + Log in + + + + Sign up + + +
+ Search + +
+
+ Search + +
+ More + Pricing +
+ + +
+ asdf +
+ ); +}; + +export default Demo; diff --git a/website/docs/components/button/button-code.md b/website/docs/components/button/button-code.md index 5c64f447d7..62dda289f9 100644 --- a/website/docs/components/button/button-code.md +++ b/website/docs/components/button/button-code.md @@ -13,7 +13,7 @@ Addons can be added: ::: sandbox ::: diff --git a/website/docs/style/design-tokens/design-tokens.json b/website/docs/style/design-tokens/design-tokens.json index 3ea3c3f1d5..dca5355ea5 100644 --- a/website/docs/style/design-tokens/design-tokens.json +++ b/website/docs/style/design-tokens/design-tokens.json @@ -497,6 +497,7 @@ "date-picker", "dot", "feature-highlight", + "header-controls", "notice-bubble", "notice-global", "tag", @@ -510,7 +511,9 @@ "rawValue": "{gray.white}, 0.8", "computedValue": "rgba(255, 255, 255, 0.8)", "description": "Inverted version of the secondary text.", - "components": [] + "components": [ + "header-controls" + ] }, { "name": "--intergalactic-text-link", @@ -2740,6 +2743,7 @@ "feedback-form", "format-text", "fullscreen-modal", + "header-controls", "input", "input-tags", "modal", @@ -2785,6 +2789,7 @@ "feedback-form", "format-text", "fullscreen-modal", + "header-controls", "input", "modal", "notice", From d1ab63b3f13ff14830d4c656ff7fef41511f6ef0 Mon Sep 17 00:00:00 2001 From: Sheila Sheikh <166654065+sheila-semrush@users.noreply.github.com> Date: Mon, 25 Aug 2025 20:13:22 +0200 Subject: [PATCH 2/2] [header-controls, core] added header tokens, added some control styles --- pnpm-lock.yaml | 8 +- semcore/core/src/theme/light.json | 35 +++++++- semcore/core/src/theme/themes/auto.css | 9 +- semcore/core/src/theme/themes/default.css | 9 +- semcore/core/src/theme/themes/default.ts | 9 +- semcore/core/src/theme/themes/light.css | 9 +- semcore/core/src/theme/themes/light.ts | 9 +- semcore/core/src/theme/utils.ts | 2 +- .../src/components/button-link/ButtonLink.tsx | 19 ++++ .../button-link/buttonLink.shadow.css | 14 +++ .../src/components/button/button.shadow.css | 47 +++++----- .../src/components/input/input.shadow.css | 49 +++++++--- semcore/header-controls/src/index.ts | 1 + .../button-trigger/buttonTrigger.shadow.css | 34 ++++--- .../tests/examples/header-controls.tsx | 90 ++++++++++++++++--- .../style/design-tokens/design-tokens.json | 66 ++++++++++++-- 16 files changed, 327 insertions(+), 83 deletions(-) create mode 100644 semcore/header-controls/src/components/button-link/ButtonLink.tsx create mode 100644 semcore/header-controls/src/components/button-link/buttonLink.shadow.css diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bd71c1f848..f4db4a6727 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3045,7 +3045,7 @@ importers: version: 0.14.29 vitest-axe: specifier: 0.1.0 - version: 0.1.0(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.30)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(happy-dom@9.20.3)(jsdom@22.1.0)(less@3.13.1)(msw@2.9.0(@types/node@22.15.30)(typescript@5.8.3))(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0)) + version: 0.1.0(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.30)(@vitest/browser@3.0.6(@types/node@18.16.15)(playwright@1.48.0)(typescript@5.8.3)(vite@6.3.5(@types/node@18.16.15)(less@3.13.1)(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0))(vitest@3.0.9)(webdriverio@8.24.3(typescript@5.8.3)))(@vitest/ui@3.0.6(vitest@3.0.9))(happy-dom@9.20.3)(jsdom@22.1.0)(less@3.13.1)(msw@2.9.0(@types/node@22.15.30)(typescript@5.8.3))(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0)) website: dependencies: @@ -28873,7 +28873,7 @@ snapshots: - typescript - universal-cookie - vitest-axe@0.1.0(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.30)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(happy-dom@9.20.3)(jsdom@22.1.0)(less@3.13.1)(msw@2.9.0(@types/node@22.15.30)(typescript@5.8.3))(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0)): + vitest-axe@0.1.0(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.30)(@vitest/browser@3.0.6(@types/node@18.16.15)(playwright@1.48.0)(typescript@5.8.3)(vite@6.3.5(@types/node@18.16.15)(less@3.13.1)(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0))(vitest@3.0.9)(webdriverio@8.24.3(typescript@5.8.3)))(@vitest/ui@3.0.6(vitest@3.0.9))(happy-dom@9.20.3)(jsdom@22.1.0)(less@3.13.1)(msw@2.9.0(@types/node@22.15.30)(typescript@5.8.3))(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0)): dependencies: aria-query: 5.3.2 axe-core: 4.9.1 @@ -28881,7 +28881,7 @@ snapshots: dom-accessibility-api: 0.5.16 lodash-es: 4.17.21 redent: 3.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.30)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(happy-dom@9.20.3)(jsdom@22.1.0)(less@3.13.1)(msw@2.9.0(@types/node@22.15.30)(typescript@5.8.3))(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.15.30)(@vitest/browser@3.0.6(@types/node@18.16.15)(playwright@1.48.0)(typescript@5.8.3)(vite@6.3.5(@types/node@18.16.15)(less@3.13.1)(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0))(vitest@3.0.9)(webdriverio@8.24.3(typescript@5.8.3)))(@vitest/ui@3.0.6(vitest@3.0.9))(happy-dom@9.20.3)(jsdom@22.1.0)(less@3.13.1)(msw@2.9.0(@types/node@22.15.30)(typescript@5.8.3))(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0) vitest@3.0.9(@types/debug@4.1.12)(@types/node@18.16.15)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(happy-dom@9.20.3)(jsdom@22.1.0)(less@3.13.1)(msw@2.9.0(@types/node@18.16.15)(typescript@5.8.3))(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0): dependencies: @@ -28926,7 +28926,7 @@ snapshots: - tsx - yaml - vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.30)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(happy-dom@9.20.3)(jsdom@22.1.0)(less@3.13.1)(msw@2.9.0(@types/node@22.15.30)(typescript@5.8.3))(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.15.30)(@vitest/browser@3.0.6(@types/node@18.16.15)(playwright@1.48.0)(typescript@5.8.3)(vite@6.3.5(@types/node@18.16.15)(less@3.13.1)(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0))(vitest@3.0.9)(webdriverio@8.24.3(typescript@5.8.3)))(@vitest/ui@3.0.6(vitest@3.0.9))(happy-dom@9.20.3)(jsdom@22.1.0)(less@3.13.1)(msw@2.9.0(@types/node@22.15.30)(typescript@5.8.3))(sass@1.89.1)(terser@5.41.0)(yaml@2.8.0): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 diff --git a/semcore/core/src/theme/light.json b/semcore/core/src/theme/light.json index d2403f043c..29ae7082e7 100644 --- a/semcore/core/src/theme/light.json +++ b/semcore/core/src/theme/light.json @@ -2462,11 +2462,42 @@ }, "border": { "primary": { - "value": "{violet.dusty.700}", + "value": "transparent", "type": "color" }, "secondary": { - "value": "rgba(255,255,255,0.15)", + "value": "rgba({gray.white}, 0.15)", + "type": "color" + } + }, + "control": { + "secondary": { + "value": "{violet.dusty.600}", + "type": "color" + }, + "secondary-hover": { + "value": "{violet.dusty.500}", + "type": "color" + }, + "secondary-active": { + "value": "{violet.dusty.500}", + "type": "color", + "$extensions": { + "studio.tokens": { + "modify": { + "type": "lighten", + "value": "0.15", + "space": "hsl" + } + } + } + }, + "tertiary-hover": { + "value": "{violet.dusty.600}", + "type": "color" + }, + "tertiary-active": { + "value": "{violet.dusty.500}", "type": "color" } } diff --git a/semcore/core/src/theme/themes/auto.css b/semcore/core/src/theme/themes/auto.css index c9faf849d7..40b52fef1d 100644 --- a/semcore/core/src/theme/themes/auto.css +++ b/semcore/core/src/theme/themes/auto.css @@ -828,8 +828,13 @@ /* Background color for the "Start tracking" date on the X-axis of the chart grid. */ --intergalactic-chart-x-axis-accent-data-start-tracking: rgba(0, 159, 129, 0.2); --intergalactic-header-bg: #382E5E; - --intergalactic-header-border-primary: #382E5E; - --intergalactic-header-border-secondary: rgba(255,255,255, 0.15); + --intergalactic-header-border-primary: transparent; + --intergalactic-header-border-secondary: rgba(255, 255, 255, 0.15); + --intergalactic-header-control-secondary: #4D407E; + --intergalactic-header-control-secondary-hover: #6D619F; + --intergalactic-header-control-secondary-active: #8379ad; + --intergalactic-header-control-tertiary-hover: #4D407E; + --intergalactic-header-control-tertiary-active: #6D619F; --intergalactic-sidebar-nav-control-hover: rgba(224, 225, 233, 0.7); --intergalactic-sidebar-nav-control-active: #E2DDFF; --intergalactic-sidebar-nav-control-text-normal: #6D619F; diff --git a/semcore/core/src/theme/themes/default.css b/semcore/core/src/theme/themes/default.css index ff18dd5173..eb41a301b9 100644 --- a/semcore/core/src/theme/themes/default.css +++ b/semcore/core/src/theme/themes/default.css @@ -828,8 +828,13 @@ /* Background color for the "Start tracking" date on the X-axis of the chart grid. */ --intergalactic-chart-x-axis-accent-data-start-tracking: rgba(0, 159, 129, 0.2); --intergalactic-header-bg: #382E5E; - --intergalactic-header-border-primary: #382E5E; - --intergalactic-header-border-secondary: rgba(255,255,255, 0.15); + --intergalactic-header-border-primary: transparent; + --intergalactic-header-border-secondary: rgba(255, 255, 255, 0.15); + --intergalactic-header-control-secondary: #4D407E; + --intergalactic-header-control-secondary-hover: #6D619F; + --intergalactic-header-control-secondary-active: #8379ad; + --intergalactic-header-control-tertiary-hover: #4D407E; + --intergalactic-header-control-tertiary-active: #6D619F; --intergalactic-sidebar-nav-control-hover: rgba(224, 225, 233, 0.7); --intergalactic-sidebar-nav-control-active: #E2DDFF; --intergalactic-sidebar-nav-control-text-normal: #6D619F; diff --git a/semcore/core/src/theme/themes/default.ts b/semcore/core/src/theme/themes/default.ts index 468d51a7dd..ad4972bf30 100644 --- a/semcore/core/src/theme/themes/default.ts +++ b/semcore/core/src/theme/themes/default.ts @@ -459,8 +459,13 @@ export default { '--intergalactic-chart-x-axis-accent-period-active': '#6c6e79', '--intergalactic-chart-x-axis-accent-data-start-tracking': 'rgba(0, 159, 129, 0.2)', '--intergalactic-header-bg': '#382E5E', - '--intergalactic-header-border-primary': '#382E5E', - '--intergalactic-header-border-secondary': 'rgba(255,255,255, 0.15)', + '--intergalactic-header-border-primary': 'transparent', + '--intergalactic-header-border-secondary': 'rgba(255, 255, 255, 0.15)', + '--intergalactic-header-control-secondary': '#4D407E', + '--intergalactic-header-control-secondary-hover': '#6D619F', + '--intergalactic-header-control-secondary-active': '#8379ad', + '--intergalactic-header-control-tertiary-hover': '#4D407E', + '--intergalactic-header-control-tertiary-active': '#6D619F', '--intergalactic-sidebar-nav-control-hover': 'rgba(224, 225, 233, 0.7)', '--intergalactic-sidebar-nav-control-active': '#E2DDFF', '--intergalactic-sidebar-nav-control-text-normal': '#6D619F', diff --git a/semcore/core/src/theme/themes/light.css b/semcore/core/src/theme/themes/light.css index ff18dd5173..eb41a301b9 100644 --- a/semcore/core/src/theme/themes/light.css +++ b/semcore/core/src/theme/themes/light.css @@ -828,8 +828,13 @@ /* Background color for the "Start tracking" date on the X-axis of the chart grid. */ --intergalactic-chart-x-axis-accent-data-start-tracking: rgba(0, 159, 129, 0.2); --intergalactic-header-bg: #382E5E; - --intergalactic-header-border-primary: #382E5E; - --intergalactic-header-border-secondary: rgba(255,255,255, 0.15); + --intergalactic-header-border-primary: transparent; + --intergalactic-header-border-secondary: rgba(255, 255, 255, 0.15); + --intergalactic-header-control-secondary: #4D407E; + --intergalactic-header-control-secondary-hover: #6D619F; + --intergalactic-header-control-secondary-active: #8379ad; + --intergalactic-header-control-tertiary-hover: #4D407E; + --intergalactic-header-control-tertiary-active: #6D619F; --intergalactic-sidebar-nav-control-hover: rgba(224, 225, 233, 0.7); --intergalactic-sidebar-nav-control-active: #E2DDFF; --intergalactic-sidebar-nav-control-text-normal: #6D619F; diff --git a/semcore/core/src/theme/themes/light.ts b/semcore/core/src/theme/themes/light.ts index 468d51a7dd..ad4972bf30 100644 --- a/semcore/core/src/theme/themes/light.ts +++ b/semcore/core/src/theme/themes/light.ts @@ -459,8 +459,13 @@ export default { '--intergalactic-chart-x-axis-accent-period-active': '#6c6e79', '--intergalactic-chart-x-axis-accent-data-start-tracking': 'rgba(0, 159, 129, 0.2)', '--intergalactic-header-bg': '#382E5E', - '--intergalactic-header-border-primary': '#382E5E', - '--intergalactic-header-border-secondary': 'rgba(255,255,255, 0.15)', + '--intergalactic-header-border-primary': 'transparent', + '--intergalactic-header-border-secondary': 'rgba(255, 255, 255, 0.15)', + '--intergalactic-header-control-secondary': '#4D407E', + '--intergalactic-header-control-secondary-hover': '#6D619F', + '--intergalactic-header-control-secondary-active': '#8379ad', + '--intergalactic-header-control-tertiary-hover': '#4D407E', + '--intergalactic-header-control-tertiary-active': '#6D619F', '--intergalactic-sidebar-nav-control-hover': 'rgba(224, 225, 233, 0.7)', '--intergalactic-sidebar-nav-control-active': '#E2DDFF', '--intergalactic-sidebar-nav-control-text-normal': '#6D619F', diff --git a/semcore/core/src/theme/utils.ts b/semcore/core/src/theme/utils.ts index 9765ac64f3..1acbb51465 100644 --- a/semcore/core/src/theme/utils.ts +++ b/semcore/core/src/theme/utils.ts @@ -168,7 +168,7 @@ export const processTokens = (base: TokensInput, tokens: TokensInput, featureHig } return resolvedColor; } - if (color.startsWith('#')) { + if (color.startsWith('#') || color === 'transparent') { return color; } throw new Error(`Unable to process color ${color}`); diff --git a/semcore/header-controls/src/components/button-link/ButtonLink.tsx b/semcore/header-controls/src/components/button-link/ButtonLink.tsx new file mode 100644 index 0000000000..b7c751f9b3 --- /dev/null +++ b/semcore/header-controls/src/components/button-link/ButtonLink.tsx @@ -0,0 +1,19 @@ +import { ButtonLink } from '@semcore/button'; +import { createComponent, Root, sstyled, Component } from '@semcore/core'; +import React from 'react'; + +import style from './buttonLink.shadow.css'; + +class HeaderButtonLinkRoot extends Component { + static displayName = 'HeaderButtonLink'; + static style = style; + + render() { + const SHeaderButtonLink = Root; + return sstyled(this.asProps.styles)( + , + ); + } +} + +export const HeaderButtonLink = createComponent(HeaderButtonLinkRoot) as typeof ButtonLink; diff --git a/semcore/header-controls/src/components/button-link/buttonLink.shadow.css b/semcore/header-controls/src/components/button-link/buttonLink.shadow.css new file mode 100644 index 0000000000..94473dc66a --- /dev/null +++ b/semcore/header-controls/src/components/button-link/buttonLink.shadow.css @@ -0,0 +1,14 @@ +SButton:not([data-group-focused="true"]) { + color: var(--intergalactic-text-secondary-invert, rgba(255, 255, 255, 0.8)); + + &[active], + &:hover, + &:active, + &[enableVisited]:visited:hover { + color: var(--intergalactic-text-primary-invert, #ffffff); + } + + &[enableVisited]:visited { + color: var(--intergalactic-text-secondary-invert, rgba(255, 255, 255, 0.8)); + } +} \ No newline at end of file diff --git a/semcore/header-controls/src/components/button/button.shadow.css b/semcore/header-controls/src/components/button/button.shadow.css index c768d2e54c..84de384e6e 100644 --- a/semcore/header-controls/src/components/button/button.shadow.css +++ b/semcore/header-controls/src/components/button/button.shadow.css @@ -1,14 +1,10 @@ -@import '../vars.css'; - SHeaderButton[size='m'] { - /* disable-tokens-validator */ - height: var(--intergalactic-header-control-m, 32px); - /* disable-tokens-validator */ - min-width: var(--intergalactic-header-control-m, 32px); - /* we should have min-width in the default button styles, instead of the only-child margin calculations */ + height: var(--intergalactic-spacing-8x, 32px); + min-width: var(--intergalactic-spacing-8x, 32px); + /* we should have min-width in the default button styles */ } -SAddon { +SAddon[size='m'] { &:not(:only-child):first-child { margin-left: var(--intergalactic-spacing-3x, 12px); } @@ -33,39 +29,40 @@ SText { SHeaderButton[neighborLocation='both'], SHeaderButton[neighborLocation='left'] { &:after { - /* disable-tokens-validator */ - background-color: var(--intergalactic-border-primary-header); + background-color: var(--intergalactic-header-border-primary, transparent); } } SHeaderButton[theme='secondary-invert'] { - /* disable-tokens-validator */ - background-color: var(--intergalactic-control-secondary-header); - /* disable-tokens-validator */ - border-color: var(--intergalactic-border-primary-header); + background-color: var(--intergalactic-header-control-secondary, #4D407E); + border-color: var(--intergalactic-header-border-primary, transparent); + + &:not(:hover, :active) { + color: var(--intergalactic-text-secondary-invert, rgba(255, 255, 255, 0.8)); + } + + & SText { + color: var(--intergalactic-text-primary-invert, #ffffff); + } &:hover { - /* disable-tokens-validator */ - background-color: var(--intergalactic-control-secondary-header-hover); + background-color: var(--intergalactic-header-control-secondary-hover, #6D619F); } &:active { - /* disable-tokens-validator */ - background-color: var(--intergalactic-control-secondary-header-active); + background-color: var(--intergalactic-header-control-secondary-active, #8379ad); } &[neighborLocation='both'], &[neighborLocation='left'] { &:after { - /* disable-tokens-validator */ - background-color: var(--intergalactic-border-secondary-header); + background-color: var(--intergalactic-header-border-secondary, rgba(255, 255, 255, 0.15)); } } :not(SButton) + &[neighborLocation='left'], :not(SButton) + &[neighborLocation='both'] { - /* disable-tokens-validator */ - border-left-color: var(--intergalactic-border-secondary-header); + border-left-color: var(--intergalactic-header-border-secondary, rgba(255, 255, 255, 0.15)); } } @@ -74,11 +71,9 @@ SHeaderButton[theme='tertiary-invert'] { color: var(--intergalactic-text-secondary-invert, rgba(255, 255, 255, 0.8)); } &:hover { - /* disable-tokens-validator */ - background-color: var(--intergalactic-control-tertiary-header-hover); + background-color: var(--intergalactic-header-control-tertiary-hover, #4D407E); } &:active { - /* disable-tokens-validator */ - background-color: var(--intergalactic-control-tertiary-header-active); + background-color: var(--intergalactic-header-control-tertiary-active, #6D619F); } } diff --git a/semcore/header-controls/src/components/input/input.shadow.css b/semcore/header-controls/src/components/input/input.shadow.css index 3802282271..c6ae5be8b2 100644 --- a/semcore/header-controls/src/components/input/input.shadow.css +++ b/semcore/header-controls/src/components/input/input.shadow.css @@ -1,28 +1,53 @@ -@import '../vars.css'; - SHeaderInput[size='m'] { - /* disable-tokens-validator */ - height: var(--intergalactic-header-control-m); + height: var(--intergalactic-spacing-8x, 32px); } SHeaderInput:not(:has(SValue:focus)) { &:not(:hover) SOutline { - /* disable-tokens-validator */ - background: var(--intergalactic-control-secondary-header); + background: var(--intergalactic-header-control-secondary, #4D407E); } &:hover SOutline { - /* disable-tokens-validator */ - background: var(--intergalactic-control-secondary-header-hover); + background: var(--intergalactic-header-control-secondary-hover, #6D619F); } &[state='normal'] SOutline { - /* disable-tokens-validator */ - border-color: var(--intergalactic-border-primary-header); + border: var(--intergalactic-header-border-primary, transparent); + } + SAddon { + color: var(--intergalactic-text-secondary-invert, rgba(255, 255, 255, 0.8)); + } +} + +SValue[size='m'] { + &:first-child { + padding-left: var(--intergalactic-spacing-3x, 12px); + } + &:last-child { + padding-right: var(--intergalactic-spacing-3x, 12px); } } SValue:not(:focus) { + color: var(--intergalactic-text-primary-invert, #ffffff); + &::placeholder { - /* disable-tokens-validator */ - color: var(--intergalactic-text-placeholder-header); + color: var(--intergalactic-text-secondary-invert, rgba(255, 255, 255, 0.8)); + } +} + +SHeaderInput SAddon { + + /* &:first-child { + padding-right: 0; + padding-left: var(--intergalactic-spacing-3x, 12px); + } */ + + &:nth-last-child(2) { + margin-right: var(--intergalactic-spacing-1x, 4px); + } + + &:has(SAddon) { + /* should be in the common styles */ + padding-left: 0; + padding-right: 0; } } \ No newline at end of file diff --git a/semcore/header-controls/src/index.ts b/semcore/header-controls/src/index.ts index f94e904878..eaa9dd700f 100644 --- a/semcore/header-controls/src/index.ts +++ b/semcore/header-controls/src/index.ts @@ -1,4 +1,5 @@ export * from './components/button/Button'; +export * from './components/button-link/ButtonLink'; export * from './components/input/Input'; export * from './components/select/Select'; export * from './inner-components/button-trigger/ButtonTrigger'; // for testing, remove later diff --git a/semcore/header-controls/src/inner-components/button-trigger/buttonTrigger.shadow.css b/semcore/header-controls/src/inner-components/button-trigger/buttonTrigger.shadow.css index ce139fc2ac..12ba47eea8 100644 --- a/semcore/header-controls/src/inner-components/button-trigger/buttonTrigger.shadow.css +++ b/semcore/header-controls/src/inner-components/button-trigger/buttonTrigger.shadow.css @@ -1,19 +1,31 @@ -@import '../../components/vars.css'; - SHeaderButtonTrigger { - - /* disable-tokens-validator */ - background-color: var(--intergalactic-control-secondary-header); - /* disable-tokens-validator */ - border-color: var(--intergalactic-border-primary-header); + background-color: var(--intergalactic-header-control-secondary, #4D407E); + border-color: var(--intergalactic-header-border-primary, transparent); color: var(--intergalactic-text-primary-invert, #ffffff); &:hover { - /* disable-tokens-validator */ - background-color: var(--intergalactic-control-secondary-header-hover); + background-color: var(--intergalactic-header-control-secondary-hover, #6D619F); + } + &:active { + /* but we have two versions: one that stays purple when active, and another that turns white */ + background-color: var(--intergalactic-header-control-secondary-active, #8379ad); + border-color: var(--intergalactic-header-border-primary, transparent); } } SHeaderButtonTrigger[size='m'] { - /* disable-tokens-validator */ - height: var(--intergalactic-header-control-m); + height: var(--intergalactic-spacing-8x, 32px); + min-width: var(--intergalactic-spacing-8x, 32px); + padding: 0 var(--intergalactic-spacing-3x, 12px); +} + +SHeaderButtonTrigger[neighborLocation='both'], +SHeaderButtonTrigger[neighborLocation='left'] { + border-left-color: var(--intergalactic-header-border-secondary, rgba(255, 255, 255, 0.15)); +} + +SAddon { + color: var(--intergalactic-text-secondary-invert, rgba(255, 255, 255, 0.8)); + SHeaderButtonTrigger:hover &, SHeaderButtonTrigger:active & { + color: var(--intergalactic-icon-primary-invert, #ffffff); + } } \ No newline at end of file diff --git a/stories/components/header-controls/tests/examples/header-controls.tsx b/stories/components/header-controls/tests/examples/header-controls.tsx index 25a7c1e13c..9f1532772c 100644 --- a/stories/components/header-controls/tests/examples/header-controls.tsx +++ b/stories/components/header-controls/tests/examples/header-controls.tsx @@ -1,12 +1,16 @@ import { Flex } from '@semcore/base-components'; -import Button from '@semcore/button'; -import { HeaderButton, HeaderInput, HeaderButtonTrigger } from '@semcore/header-controls'; +import Button, { ButtonLink } from '@semcore/button'; +import { HeaderButton, HeaderInput, HeaderButtonTrigger, HeaderButtonLink } from '@semcore/header-controls'; import Chevron from '@semcore/icon/ChevronDown/m'; +import Close from '@semcore/icon/Close/m'; +import Plus from '@semcore/icon/MathPlus/m'; import Search from '@semcore/icon/Search/m'; import Input from '@semcore/input'; import React from 'react'; const Demo = () => { + const [focused, setFocused] = React.useState(false); + return ( { Sign up + + + Create project + +
- Search - + Menu +
- Search - + Menu +
More - Pricing + + Pricing + +
+ + + + +
+ Root domain +
+ + setFocused(true)} + onBlur={() => setFocused(false)} + /> + + alert('asdf')} + data-group-focused={focused} + /> + + + + Root domain + + +
- - + + + + + + Root domain + +
- asdf + Clear + Large
); }; diff --git a/website/docs/style/design-tokens/design-tokens.json b/website/docs/style/design-tokens/design-tokens.json index 0a38fe0de7..df6cdef1a9 100644 --- a/website/docs/style/design-tokens/design-tokens.json +++ b/website/docs/style/design-tokens/design-tokens.json @@ -1395,7 +1395,8 @@ "computedValue": "#ffffff", "description": "Inverted version of the primary icon.", "components": [ - "carousel" + "carousel", + "header-controls" ] }, { @@ -2743,6 +2744,7 @@ "feature-popover", "format-text", "fullscreen-modal", + "header-controls", "inline-input", "input-tags", "link", @@ -2920,6 +2922,7 @@ "errors", "format-text", "fullscreen-modal", + "header-controls", "notice-bubble", "notice-global", "typography" @@ -4038,16 +4041,65 @@ { "name": "--intergalactic-header-border-primary", "type": "color", - "rawValue": "{violet.dusty.700}", - "computedValue": "#382E5E", - "components": [] + "rawValue": "transparent", + "computedValue": "transparent", + "components": [ + "header-controls" + ] }, { "name": "--intergalactic-header-border-secondary", "type": "color", - "rawValue": "rgba(255,255,255,0.15)", - "computedValue": "rgba(255,255,255, 0.15)", - "components": [] + "rawValue": "rgba({gray.white}, 0.15)", + "computedValue": "rgba(255, 255, 255, 0.15)", + "components": [ + "header-controls" + ] + }, + { + "name": "--intergalactic-header-control-secondary", + "type": "color", + "rawValue": "{violet.dusty.600}", + "computedValue": "#4D407E", + "components": [ + "header-controls" + ] + }, + { + "name": "--intergalactic-header-control-secondary-hover", + "type": "color", + "rawValue": "{violet.dusty.500}", + "computedValue": "#6D619F", + "components": [ + "header-controls" + ] + }, + { + "name": "--intergalactic-header-control-secondary-active", + "type": "color", + "rawValue": "{violet.dusty.500} / lighten(0.15) / hsl", + "computedValue": "#8379ad", + "components": [ + "header-controls" + ] + }, + { + "name": "--intergalactic-header-control-tertiary-hover", + "type": "color", + "rawValue": "{violet.dusty.600}", + "computedValue": "#4D407E", + "components": [ + "header-controls" + ] + }, + { + "name": "--intergalactic-header-control-tertiary-active", + "type": "color", + "rawValue": "{violet.dusty.500}", + "computedValue": "#6D619F", + "components": [ + "header-controls" + ] }, { "name": "--intergalactic-sidebar-nav-control-hover",