diff --git a/.changeset/stupid-candles-hug.md b/.changeset/stupid-candles-hug.md new file mode 100644 index 0000000000..040eb62947 --- /dev/null +++ b/.changeset/stupid-candles-hug.md @@ -0,0 +1,5 @@ +--- +'@backstage/canon': patch +--- + +Add new Switch component in Canon. diff --git a/packages/canon/css/components.css b/packages/canon/css/components.css index f3be22720c..1b60bf74ed 100644 --- a/packages/canon/css/components.css +++ b/packages/canon/css/components.css @@ -1332,3 +1332,61 @@ width: 100%; overflow: hidden; } + +.canon-Switch { + align-items: center; + gap: var(--canon-space-3); + font-size: var(--canon-font-size-3); + color: var(--canon-fg-primary); + cursor: pointer; + display: flex; + position: relative; + + &[data-pressed] .canon-SwitchIndicator { + &:before { + background: var(--canon-fg-solid); + } + } + + &[data-selected] { + & .canon-SwitchIndicator { + background: var(--canon-bg-solid); + + &:before { + background: var(--canon-fg-solid); + transform: translateX(100%); + } + } + + &[data-pressed] { + & .indicator { + background: var(--canon-gray-3); + } + } + } + + &[data-focus-visible] .canon-SwitchIndicator { + outline-offset: 2px; + outline: 2px solid; + } +} + +.canon-SwitchIndicator { + background: var(--canon-gray-3); + border: 2px; + border-radius: 1.143rem; + width: 2rem; + height: 1.143rem; + transition: all .2s; + + &:before { + content: ""; + background: var(--canon-fg-solid); + border-radius: 16px; + width: .857rem; + height: .857rem; + margin: .143rem; + transition: all .2s; + display: block; + } +} diff --git a/packages/canon/css/styles.css b/packages/canon/css/styles.css index 8e98996d6d..83329e817c 100644 --- a/packages/canon/css/styles.css +++ b/packages/canon/css/styles.css @@ -10556,3 +10556,61 @@ width: 100%; overflow: hidden; } + +.canon-Switch { + align-items: center; + gap: var(--canon-space-3); + font-size: var(--canon-font-size-3); + color: var(--canon-fg-primary); + cursor: pointer; + display: flex; + position: relative; + + &[data-pressed] .canon-SwitchIndicator { + &:before { + background: var(--canon-fg-solid); + } + } + + &[data-selected] { + & .canon-SwitchIndicator { + background: var(--canon-bg-solid); + + &:before { + background: var(--canon-fg-solid); + transform: translateX(100%); + } + } + + &[data-pressed] { + & .indicator { + background: var(--canon-gray-3); + } + } + } + + &[data-focus-visible] .canon-SwitchIndicator { + outline-offset: 2px; + outline: 2px solid; + } +} + +.canon-SwitchIndicator { + background: var(--canon-gray-3); + border: 2px; + border-radius: 1.143rem; + width: 2rem; + height: 1.143rem; + transition: all .2s; + + &:before { + content: ""; + background: var(--canon-fg-solid); + border-radius: 16px; + width: .857rem; + height: .857rem; + margin: .143rem; + transition: all .2s; + display: block; + } +} diff --git a/packages/canon/css/switch.css b/packages/canon/css/switch.css new file mode 100644 index 0000000000..ee517543d7 --- /dev/null +++ b/packages/canon/css/switch.css @@ -0,0 +1,57 @@ +.canon-Switch { + align-items: center; + gap: var(--canon-space-3); + font-size: var(--canon-font-size-3); + color: var(--canon-fg-primary); + cursor: pointer; + display: flex; + position: relative; + + &[data-pressed] .canon-SwitchIndicator { + &:before { + background: var(--canon-fg-solid); + } + } + + &[data-selected] { + & .canon-SwitchIndicator { + background: var(--canon-bg-solid); + + &:before { + background: var(--canon-fg-solid); + transform: translateX(100%); + } + } + + &[data-pressed] { + & .indicator { + background: var(--canon-gray-3); + } + } + } + + &[data-focus-visible] .canon-SwitchIndicator { + outline-offset: 2px; + outline: 2px solid; + } +} + +.canon-SwitchIndicator { + background: var(--canon-gray-3); + border: 2px; + border-radius: 1.143rem; + width: 2rem; + height: 1.143rem; + transition: all .2s; + + &:before { + content: ""; + background: var(--canon-fg-solid); + border-radius: 16px; + width: .857rem; + height: .857rem; + margin: .143rem; + transition: all .2s; + display: block; + } +} diff --git a/packages/canon/report.api.md b/packages/canon/report.api.md index ceec381c83..bcc32ef651 100644 --- a/packages/canon/report.api.md +++ b/packages/canon/report.api.md @@ -22,6 +22,7 @@ import { ReactNode } from 'react'; import { RefAttributes } from 'react'; import type { RemixiconComponentType } from '@remixicon/react'; import { ScrollArea as ScrollArea_2 } from '@base-ui-components/react/scroll-area'; +import type { SwitchProps as SwitchProps_2 } from 'react-aria-components'; import { Table as Table_2 } from '@tanstack/react-table'; import { Tabs as Tabs_2 } from '@base-ui-components/react/tabs'; import { TdHTMLAttributes } from 'react'; @@ -1159,6 +1160,16 @@ export type StylingPropDef = { parseValue?: (value: string) => string | undefined; }; +// @public (undocumented) +export const Switch: ForwardRefExoticComponent< + SwitchProps & RefAttributes +>; + +// @public (undocumented) +export interface SwitchProps extends SwitchProps_2 { + label?: string; +} + // @public export const Table: { Root: ForwardRefExoticComponent< diff --git a/packages/canon/src/components/Switch/Switch.styles.css b/packages/canon/src/components/Switch/Switch.styles.css index b328414aa0..98368efa13 100644 --- a/packages/canon/src/components/Switch/Switch.styles.css +++ b/packages/canon/src/components/Switch/Switch.styles.css @@ -32,7 +32,7 @@ &[data-selected] { .canon-SwitchIndicator { - background: var(--canon-gray-3); + background: var(--canon-bg-solid); &:before { background: var(--canon-fg-solid); diff --git a/packages/canon/src/components/Switch/Switch.tsx b/packages/canon/src/components/Switch/Switch.tsx index b84a8c9c5f..78bbaa3930 100644 --- a/packages/canon/src/components/Switch/Switch.tsx +++ b/packages/canon/src/components/Switch/Switch.tsx @@ -18,6 +18,7 @@ import { forwardRef } from 'react'; import { Switch as AriaSwitch } from 'react-aria-components'; import type { SwitchProps } from './types'; +/** @public */ export const Switch = forwardRef( ({ label, ...props }, ref) => { return ( diff --git a/packages/canon/src/components/Switch/index.tsx b/packages/canon/src/components/Switch/index.tsx index 10a5429188..171969809d 100644 --- a/packages/canon/src/components/Switch/index.tsx +++ b/packages/canon/src/components/Switch/index.tsx @@ -14,4 +14,5 @@ * limitations under the License. */ -export { Switch } from './Switch'; +export * from './Switch'; +export * from './types'; diff --git a/packages/canon/src/components/Switch/types.ts b/packages/canon/src/components/Switch/types.ts index 1b4fcd66ed..725671edd5 100644 --- a/packages/canon/src/components/Switch/types.ts +++ b/packages/canon/src/components/Switch/types.ts @@ -16,6 +16,10 @@ import type { SwitchProps as AriaSwitchProps } from 'react-aria-components'; +/** @public */ export interface SwitchProps extends AriaSwitchProps { + /** + * The label of the switch + */ label?: string; }