diff --git a/packages/calcite-components/.stylelintrc.cjs b/packages/calcite-components/.stylelintrc.cjs index 0998dad6911..2e02214db54 100644 --- a/packages/calcite-components/.stylelintrc.cjs +++ b/packages/calcite-components/.stylelintrc.cjs @@ -1,7 +1,13 @@ // @ts-check // ⚠️ AUTO-GENERATED CODE - DO NOT EDIT -const customFunctions = []; +const customFunctions = [ + "get-trailing-text-input-padding", + "medium-modular-scale", + "modular-scale", + "scale-duration", + "small-modular-scale" +]; // ⚠️ END OF AUTO-GENERATED CODE const scssPatternRules = [ diff --git a/packages/calcite-components/src/assets/styles/includes.scss b/packages/calcite-components/src/assets/styles/includes.scss index 5235536f57b..3d1bb47381e 100644 --- a/packages/calcite-components/src/assets/styles/includes.scss +++ b/packages/calcite-components/src/assets/styles/includes.scss @@ -107,50 +107,53 @@ } } -@mixin x-button() { - :host([scale="s"]) { - .x-button { - inline-size: theme("spacing.4"); - block-size: theme("spacing.4"); - } - } - - :host([scale="m"]) { - .x-button { - inline-size: theme("spacing.6"); - block-size: theme("spacing.6"); - } - } - - :host([scale="l"]) { - .x-button { - inline-size: theme("spacing.8"); - block-size: theme("spacing.8"); - } - } - +@mixin x-button( + $size: "var(--calcite-internal-close-size, 1.5rem /* 24px */)", + $padding: "0", + $color: "var(--calcite-close-icon-color, var(--calcite-color-text-1))", + $backgroundColor: "var(--calcite-close-background-color, var(--calcite-color-transparent))", + $backgroundColorHover: "var(--calcite-close-background-color-hover, var(--calcite-color-transparent-hover))", + $backgroundColorPress: "var(--calcite-close-background-color-press, var(--calcite-color-transparent-press))" +) { .x-button { - @apply appearance-none bg-transparent border-2 content-center cursor-pointer flex focus-base items-center justify-center m-0 self-center text-color-3 transition-default; + @apply border-none + cursor-pointer + focus-base + items-center + m-0 + transition-default; - border-radius: 50%; - border-color: transparent; - background-color: var(--calcite-color-foreground-2); + background-color: #{$backgroundColor}; + -webkit-appearance: none; + display: flex; + align-content: center; + justify-content: center; + color: #{$color}; + block-size: #{$size}; + inline-size: #{$size}; + min-block-size: #{$size}; + min-inline-size: #{$size}; + padding: #{$padding}; - &:active, - &:hover { - @apply text-color-1; - background-color: var(--calcite-color-foreground-3); + &:hover, + &:focus { + background-color: #{$backgroundColorHover}; + } + &:focus { + @apply focus-inset; } - &:active { - @apply border-solid; - border-color: theme("borderColor.color-brand"); + background-color: #{$backgroundColorPress}; } - & calcite-icon { + calcite-icon { color: inherit; } } + + .x-button--round { + border-radius: 9999px; + } } @mixin close-button( @@ -164,7 +167,7 @@ focus-base items-center m-0 - rounded-half + rounded-half transition-default; background-color: var(--calcite-close-background-color, var(--calcite-color-transparent)); diff --git a/packages/calcite-components/src/components.d.ts b/packages/calcite-components/src/components.d.ts index bfa5b3f2fc8..a914c76d380 100644 --- a/packages/calcite-components/src/components.d.ts +++ b/packages/calcite-components/src/components.d.ts @@ -4568,6 +4568,9 @@ export namespace Components { */ "contentBehind": boolean; } + /** + * @deprecated Use the `calcite-shell-panel` component instead. + */ interface CalciteShellCenterRow { /** * When `true`, the content area displays like a floating panel. @@ -7553,6 +7556,9 @@ declare global { prototype: HTMLCalciteShellElement; new (): HTMLCalciteShellElement; }; + /** + * @deprecated Use the `calcite-shell-panel` component instead. + */ interface HTMLCalciteShellCenterRowElement extends Components.CalciteShellCenterRow, HTMLStencilElement { } var HTMLCalciteShellCenterRowElement: { @@ -12764,6 +12770,9 @@ declare namespace LocalJSX { */ "contentBehind"?: boolean; } + /** + * @deprecated Use the `calcite-shell-panel` component instead. + */ interface CalciteShellCenterRow { /** * When `true`, the content area displays like a floating panel. @@ -14428,6 +14437,9 @@ declare module "@stencil/core" { "calcite-select": LocalJSX.CalciteSelect & JSXBase.HTMLAttributes; "calcite-sheet": LocalJSX.CalciteSheet & JSXBase.HTMLAttributes; "calcite-shell": LocalJSX.CalciteShell & JSXBase.HTMLAttributes; + /** + * @deprecated Use the `calcite-shell-panel` component instead. + */ "calcite-shell-center-row": LocalJSX.CalciteShellCenterRow & JSXBase.HTMLAttributes; "calcite-shell-panel": LocalJSX.CalciteShellPanel & JSXBase.HTMLAttributes; "calcite-slider": LocalJSX.CalciteSlider & JSXBase.HTMLAttributes; diff --git a/packages/calcite-components/src/components/button/button.e2e.ts b/packages/calcite-components/src/components/button/button.e2e.ts index f3b128559f0..f14ec40a517 100644 --- a/packages/calcite-components/src/components/button/button.e2e.ts +++ b/packages/calcite-components/src/components/button/button.e2e.ts @@ -507,15 +507,11 @@ describe("calcite-button", () => { Layers `; - let page; - let buttonEl; - let buttonFocusStyle; - let buttonHoverStyle; it("should have defined CSS custom properties", async () => { - page = await newE2EPage({ html: buttonSnippet }); + const page = await newE2EPage({ html: buttonSnippet }); const buttonStyles = await page.evaluate(() => { - buttonEl = document.querySelector("calcite-button"); + const buttonEl = document.querySelector("calcite-button"); buttonEl.style.setProperty("--calcite-color-transparent-hover", "rgba(34, 23, 200, 0.4)"); buttonEl.style.setProperty("--calcite-color-transparent-press", "rgba(1, 20, 44, 0.1"); return { @@ -529,41 +525,31 @@ describe("calcite-button", () => { describe("when mode attribute is not provided", () => { it("should render button pseudo classes with default values tied to light mode", async () => { - page = await newE2EPage({ html: buttonSnippet }); - buttonEl = await page.find("calcite-button >>> button"); - await buttonEl.focus(); - await page.waitForChanges(); - buttonFocusStyle = await buttonEl.getComputedStyle(); - expect(buttonFocusStyle.getPropertyValue("background-color")).toEqual("rgba(0, 0, 0, 0.04)"); - + const page = await newE2EPage({ html: buttonSnippet }); + const buttonEl = await page.find("calcite-button >>> button"); await buttonEl.hover(); await page.waitForChanges(); - buttonHoverStyle = await buttonEl.getComputedStyle(); + const buttonHoverStyle = await buttonEl.getComputedStyle(); expect(buttonHoverStyle.getPropertyValue("background-color")).toEqual("rgba(0, 0, 0, 0.04)"); }); }); describe("when mode attribute is dark", () => { it("should render button pseudo classes with value tied to dark mode", async () => { - page = await newE2EPage({ + const page = await newE2EPage({ html: `
${buttonSnippet}
`, }); - buttonEl = await page.find("calcite-button >>> button"); - await buttonEl.focus(); - await page.waitForChanges(); - buttonFocusStyle = await buttonEl.getComputedStyle(); - expect(buttonFocusStyle.getPropertyValue("background-color")).toEqual("rgba(255, 255, 255, 0.04)"); - + const buttonEl = await page.find("calcite-button >>> button"); await buttonEl.hover(); await page.waitForChanges(); - buttonHoverStyle = await buttonEl.getComputedStyle(); + const buttonHoverStyle = await buttonEl.getComputedStyle(); expect(buttonHoverStyle.getPropertyValue("background-color")).toEqual("rgba(255, 255, 255, 0.04)"); }); }); it("should allow the CSS custom property to be overridden", async () => { const overrideStyle = "rgba(255, 255, 0, 0.9)"; - page = await newE2EPage({ + const page = await newE2EPage({ html: `
${buttonSnippet}
`, }); - buttonEl = await page.find("calcite-button >>> button"); - await buttonEl.focus(); - await page.waitForChanges(); - buttonFocusStyle = await buttonEl.getComputedStyle(); - expect(buttonFocusStyle.getPropertyValue("background-color")).toEqual(overrideStyle); - + const buttonEl = await page.find("calcite-button >>> button"); await buttonEl.hover(); await page.waitForChanges(); - buttonHoverStyle = await buttonEl.getComputedStyle(); - expect(buttonHoverStyle.getPropertyValue("background-color")).toEqual(overrideStyle); + const buttonFocusStyle = await buttonEl.getComputedStyle(); + expect(buttonFocusStyle.getPropertyValue("background-color")).toEqual(overrideStyle); }); }); diff --git a/packages/calcite-components/src/components/button/button.scss b/packages/calcite-components/src/components/button/button.scss index 5a01a0740b2..eb47bda45c1 100644 --- a/packages/calcite-components/src/components/button/button.scss +++ b/packages/calcite-components/src/components/button/button.scss @@ -1,64 +1,144 @@ +/** + * CSS Custom Properties + * + * These properties can be overridden using the component's tag as selector. + * + * @prop --calcite-button-background-color: Specifies the component's background color. + * @prop --calcite-button-border-color: Specifies the component's border color. + * @prop --calcite-button-corner-radius: Specifies the component's corner radius. + * @prop --calcite-button-corner-radius-start-start: Specifies the component's top-left corner radius. will fallback to --calcite-button-corner-radius. + * @prop --calcite-button-corner-radius-start-end: Specifies the component's top-right corner radius. Will fallback to --calcite-button-corner-radius. + * @prop --calcite-button-corner-radius-end-start: Specifies the component's bottom-left corner radius. Will fallback to --calcite-button-corner-radius. + * @prop --calcite-button-corner-radius-end-end: Specifies the component's bottom-right corner radius. Will fallback to --calcite-button-corner-radius. + * @prop --calcite-button-icon-color: Specifies the color of an icon in the component. + * @prop --calcite-button-loader-color: Specifies the component's loader color. + * @prop --calcite-button-shadow-color: Specifies the component's shadow. + * @prop --calcite-button-text-color: Specifies the component's text color. + */ + :host { @apply inline-block w-auto align-middle; -} + border-start-start-radius: var( + --calcite-button-corner-radius-start-start, + var(--calcite-button-corner-radius, var(--calcite-internal-button-corner-radius, var(--calcite-corner-radius))) + ); + border-start-end-radius: var( + --calcite-button-corner-radius-start-end, + var(--calcite-button-corner-radius, var(--calcite-internal-button-corner-radius, var(--calcite-corner-radius))) + ); + border-end-start-radius: var( + --calcite-button-corner-radius-end-start, + var(--calcite-button-corner-radius, var(--calcite-internal-button-corner-radius, var(--calcite-corner-radius))) + ); + border-end-end-radius: var( + --calcite-button-corner-radius-end-end, + var(--calcite-button-corner-radius, var(--calcite-internal-button-corner-radius, var(--calcite-corner-radius))) + ); +} + +a, +button { + --calcite-internal-button-content-margin: theme("margin.2"); + --calcite-internal-button-padding-x: 7px; + --calcite-internal-button-padding-y: 3px; + + @apply appearance-none + border-none + box-border + cursor-pointer + flex + focus-base + font-inherit + font-normal + h-full + items-center + justify-center + no-underline + relative + rounded-none + select-none + text-center + w-full; + background-color: var( + --calcite-button-background-color, + var(--calcite-internal-button-background-color, transparent) + ); + border-start-start-radius: var( + --calcite-button-corner-radius-start-start, + var(--calcite-button-corner-radius, var(--calcite-internal-button-corner-radius, var(--calcite-corner-radius))) + ); + border-start-end-radius: var( + --calcite-button-corner-radius-start-end, + var(--calcite-button-corner-radius, var(--calcite-internal-button-corner-radius, var(--calcite-corner-radius))) + ); + border-end-start-radius: var( + --calcite-button-corner-radius-end-start, + var(--calcite-button-corner-radius, var(--calcite-internal-button-corner-radius, var(--calcite-corner-radius))) + ); + border-end-end-radius: var( + --calcite-button-corner-radius-end-end, + var(--calcite-button-corner-radius, var(--calcite-internal-button-corner-radius, var(--calcite-corner-radius))) + ); + border-block-start-color: var( + --calcite-button-border-color, + var(--calcite-internal-button-border-block-start-color, var(--calcite-internal-button-border-color, transparent)) + ); + border-block-end-color: var( + --calcite-button-border-color, + var(--calcite-internal-button-border-block-end-color, var(--calcite-internal-button-border-color, transparent)) + ); + border-inline-start-color: var( + --calcite-button-border-color, + var(--calcite-internal-button-border-inline-start-color, var(--calcite-internal-button-border-color, transparent)) + ); + border-inline-end-color: var( + --calcite-button-border-color, + var(--calcite-internal-button-border-inline-end-color, var(--calcite-internal-button-border-color, transparent)) + ); + border-style: solid; + border-width: var(--calcite-border-width-sm); + box-shadow: inset 0 0 0 var(--calcite-internal-button-shadow-spread, 0) + var(--calcite-button-shadow-color, var(--calcite-internal-button-shadow-color, transparent)); + color: var(--calcite-button-text-color, var(--calcite-internal-button-text-color, var(--calcite-color-text-3))); + padding-block: var(--calcite-internal-button-padding-y); + padding-inline: var(--calcite-internal-button-padding-x); -// fab variants -:host([round]) { - border-radius: 50px; - & a, - & button { - border-radius: 50px; - } -} - -// focus styles -:host button, -:host a { - @apply focus-base; - &:focus { - @apply focus-outset; - } -} -// button base -:host button, -:host a { - --calcite-button-content-margin-internal: theme("margin.2"); - --calcite-button-padding-x-internal: 7px; - --calcite-button-padding-y-internal: 3px; - padding-block: var(--calcite-button-padding-y-internal); - padding-inline: var(--calcite-button-padding-x-internal); - @apply font-inherit - relative - box-border - flex - h-full - w-full - cursor-pointer - select-none - appearance-none - items-center - justify-center - rounded-none - border-none - text-center - font-normal - no-underline; // include transition from focus transition: color var(--calcite-animation-timing) ease-in-out, background-color var(--calcite-animation-timing) ease-in-out, box-shadow var(--calcite-animation-timing) ease-in-out, outline-color var(--calcite-internal-animation-timing-fast) ease-in-out; + + &:focus { + @apply focus-outset; + --calcite-internal-button-shadow-spread: 2px; + } &:hover { @apply no-underline; + --calcite-internal-button-shadow-spread: 1px; + } + &:active { + --calcite-internal-button-shadow-spread: 2px; } - & span { + + span { @apply truncate; } } +calcite-loader { + color: var( + --calcite-button-loader-color, + var( + --calcite-internal-button-loader-color, + var(--calcite-button-text-color, var(--calcite-internal-button-text-color)) + ) + ); +} + .content { - margin-inline: var(--calcite-button-content-margin-internal); + margin-inline: var(--calcite-internal-button-content-margin); } .icon-start-empty { @@ -72,16 +152,222 @@ } } +.icon { + @apply relative + m-0 + inline-flex + font-normal; + line-height: inherit; + color: var(--calcite-button-icon-color, currentColor); +} + +// fab variants +:host([round]) { + --calcite-internal-button-corner-radius: 50px; +} + +// button styles +:host([appearance="solid"]) { + &:host([kind="inverse"]) { + --calcite-internal-button-text-color: var(--calcite-color-text-inverse); + --calcite-internal-button-background-color: var(--calcite-color-inverse); + --calcite-internal-button-loader-color: var(--calcite-color-text-inverse); + + &:host(:hover), + &:host(:focus) { + --calcite-internal-button-background-color: var(--calcite-color-inverse-hover); + } + &:host(:active) { + --calcite-internal-button-background-color: var(--calcite-color-inverse-press); + } + } + + &:host([kind="neutral"]) { + --calcite-internal-button-text-color: var(--calcite-color-text-1); + --calcite-internal-button-background-color: var(--calcite-color-foreground-3); + --calcite-internal-button-loader-color: var(--calcite-color-text-1); + + &:host(:hover), + &:host(:focus) { + --calcite-internal-button-background-color: var(--calcite-color-foreground-2); + } + &:host(:active) { + --calcite-internal-button-background-color: var(--calcite-color-foreground-1); + } + } + + &:host([kind="danger"]) { + --calcite-internal-button-text-color: var(--calcite-color-text-inverse); + --calcite-internal-button-background-color: var(--calcite-color-status-danger); + --calcite-internal-button-loader-color: var(--calcite-color-text-inverse); + + &:host(:hover), + &:host(:focus) { + --calcite-internal-button-background-color: var(--calcite-color-status-danger-hover); + } + &:host(:active) { + --calcite-internal-button-background-color: var(--calcite-color-status-danger-press); + } + } + + &:host([kind="brand"]) { + --calcite-internal-button-text-color: var(--calcite-color-text-inverse); + --calcite-internal-button-background-color: var(--calcite-color-brand); + --calcite-internal-button-loader-color: var(--calcite-color-text-inverse); + + &:host(:hover), + &:host(:focus) { + --calcite-internal-button-background-color: var(--calcite-color-brand-hover); + } + &:host(:active) { + --calcite-internal-button-background-color: var(--calcite-color-brand-press); + } + } +} + +// outline +:host([appearance="outline"]), +:host([appearance="outline-fill"]) { + &:host([kind="neutral"]), + &:host([kind="inverse"]) { + --calcite-internal-button-text-color: var(--calcite-color-text-1); + --calcite-internal-button-loader-color: var(--calcite-color-text-1); + } + &:host([kind="inverse"]) { + --calcite-internal-button-border-color: var(--calcite-color-inverse); + + &:host(:hover) { + --calcite-internal-button-border-color: var(--calcite-color-inverse-hover); + --calcite-internal-button-shadow-color: var(--calcite-color-inverse-hover); + } + &:host(:focus) { + --calcite-internal-button-border-color: var(--calcite-color-inverse); + --calcite-internal-button-shadow-color: var(--calcite-color-inverse); + } + &:host(:active) { + --calcite-internal-button-border-color: var(--calcite-color-inverse-press); + --calcite-internal-button-shadow-color: var(--calcite-color-inverse-press); + } + } + + &:host([kind="neutral"]) { + --calcite-internal-button-text-color: var(--calcite-color-text-1); + --calcite-internal-button-loader-color: var(--calcite-color-text-1); + --calcite-internal-button-border-color: var(--calcite-color-border-1); + + &:host(:hover), + &:host(:focus), + &:host(:active) { + --calcite-internal-button-shadow-color: var(--calcite-color-foreground-3); + } + } + + &:host([kind="brand"]) { + --calcite-internal-button-text-color: var(--calcite-color-brand); + --calcite-internal-button-loader-color: var(--calcite-color-brand); + --calcite-internal-button-border-color: var(--calcite-color-brand); + + &:host(:hover) { + --calcite-internal-button-text-color: var(--calcite-color-brand-hover); + --calcite-internal-button-border-color: var(--calcite-color-brand-hover); + --calcite-internal-button-shadow-color: var(--calcite-color-brand-hover); + } + &:host(:focus) { + --calcite-internal-button-text-color: var(--calcite-color-brand); + --calcite-internal-button-border-color: var(--calcite-color-brand); + --calcite-internal-button-shadow-color: var(--calcite-color-brand); + } + &:host(:active) { + --calcite-internal-button-text-color: var(--calcite-color-brand-press); + --calcite-internal-button-border-color: var(--calcite-color-brand-press); + --calcite-internal-button-shadow-color: var(--calcite-color-brand-press); + } + } + + &:host([kind="danger"]) { + --calcite-internal-button-text-color: var(--calcite-color-status-danger); + --calcite-internal-button-loader-color: var(--calcite-color-status-danger); + --calcite-internal-button-border-color: var(--calcite-color-status-danger); + + &:host(:hover) { + --calcite-internal-button-text-color: var(--calcite-color-status-danger-hover); + --calcite-internal-button-border-color: var(--calcite-color-status-danger-hover); + --calcite-internal-button-shadow-color: var(--calcite-color-status-danger-hover); + } + &:host(:focus) { + --calcite-internal-button-text-color: var(--calcite-color-status-danger); + --calcite-internal-button-border-color: var(--calcite-color-status-danger); + --calcite-internal-button-shadow-color: var(--calcite-color-status-danger); + } + &:host(:active) { + --calcite-internal-button-text-color: var(--calcite-color-status-danger-press); + --calcite-internal-button-border-color: var(--calcite-color-status-danger-press); + --calcite-internal-button-shadow-color: var(--calcite-color-status-danger-press); + } + } +} + +:host([appearance="outline-fill"]) { + --calcite-internal-button-background-color: var(--calcite-color-foreground-1); +} + +:host([appearance="transparent"]), +:host([appearance="outline"]) { + --calcite-internal-button-background-color: var(--calcite-color-transparent); +} + +// transparent +:host([appearance="transparent"]) { + &:host(:hover), + &:host(:focus) { + --calcite-internal-button-background-color: var(--calcite-color-transparent-hover); + } + &:host(:active) { + --calcite-internal-button-background-color: var(--calcite-color-transparent-press); + } + + &:host([kind="brand"]) { + --calcite-internal-button-loader-color: var(--calcite-color-brand); + --calcite-internal-button-text-color: var(--calcite-color-brand); + + &:host(:hover) { + --calcite-internal-button-text-color: var(--calcite-color-brand-hover); + } + &:host(:focus) { + --calcite-internal-button-text-color: var(--calcite-color-brand); + } + &:host(:active) { + --calcite-internal-button-text-color: var(--calcite-color-brand-press); + } + } + &:host([kind="neutral"]) { + --calcite-internal-button-text-color: var(--calcite-color-text-1); + } + &:host([kind="danger"]) { + --calcite-internal-button-text-color: var(--calcite-color-status-danger); + --calcite-internal-button-loader-color: var(--calcite-color-status-danger); + &:host(:hover) { + --calcite-internal-button-text-color: var(--calcite-color-status-danger-hover); + } + &:host(:focus) { + --calcite-internal-button-text-color: var(--calcite-color-status-danger); + } + &:host(:active) { + --calcite-internal-button-text-color: var(--calcite-color-status-danger-press); + } + } +} + :host([scale="m"]) { button, a { - --calcite-button-content-margin-internal: theme("margin.3"); + --calcite-internal-button-content-margin: theme("margin.3"); } } :host([scale="l"]) { button, a { - --calcite-button-content-margin-internal: theme("margin.4"); + --calcite-internal-button-content-margin: theme("margin.4"); } } @@ -147,19 +433,11 @@ a:not(.content--slotted), button:not(.content--slotted) { .icon--start + .icon--end { - margin-inline-start: var(--calcite-button-content-margin-internal); + margin-inline-start: var(--calcite-internal-button-content-margin); } } } -.icon { - @apply relative - m-0 - inline-flex - font-normal; - line-height: inherit; -} - @include disabled(); @keyframes loader-in { @@ -199,7 +477,7 @@ button.content--slotted, a.content--slotted { .calcite-button--loader calcite-loader { - margin-inline-end: var(--calcite-button-content-margin-internal); + margin-inline-end: var(--calcite-internal-button-content-margin); } } // hide icons when loading with no text @@ -212,279 +490,6 @@ } } -// button styles -:host([appearance]) { - button, - a { - @apply border-color-transparent - border - border-solid; - } -} - -:host([kind="brand"]) { - button, - a { - @apply text-color-inverse bg-brand; - &:hover, - &:focus { - @apply bg-brand-hover; - } - &:active { - @apply bg-brand-press; - } - calcite-loader { - @apply text-color-inverse; - } - } -} -:host([kind="danger"]) { - button, - a { - @apply text-color-inverse bg-danger; - &:hover, - &:focus { - @apply bg-danger-hover; - } - &:active { - @apply bg-danger-press; - } - calcite-loader { - @apply text-color-inverse; - } - } -} -:host([kind="neutral"]) { - button, - a { - @apply text-color-1 bg-foreground-3; - &:hover, - &:focus { - @apply bg-foreground-2; - } - &:active { - @apply bg-foreground-1; - } - calcite-loader { - @apply text-color-1; - } - } -} -:host([kind="inverse"]) { - button, - a { - @apply text-color-inverse; - background-color: var(--calcite-color-inverse); - &:hover, - &:focus { - background-color: var(--calcite-color-inverse-hover); - } - &:active { - background-color: var(--calcite-color-inverse-press); - } - calcite-loader { - @apply text-color-inverse; - } - } -} -// outline -:host([appearance="outline-fill"]) { - button, - a { - @apply bg-foreground-1 border border-solid; - box-shadow: inset 0 0 0 1px transparent; - } -} -:host([appearance="outline-fill"][kind="brand"]) { - button, - a { - @apply border-color-brand bg-foreground-1; - color: theme("colors.brand"); - &:hover { - @apply border-color-brand-hover; - color: theme("colors.brand-hover"); - box-shadow: inset 0 0 0 1px var(--calcite-color-brand-hover); - } - &:focus { - @apply border-color-brand; - color: theme("colors.brand"); - box-shadow: inset 0 0 0 2px var(--calcite-color-brand); - } - &:active { - @apply border-color-brand-press; - color: theme("colors.brand-press"); - box-shadow: inset 0 0 0 2px var(--calcite-color-brand-press); - } - calcite-loader { - color: theme("colors.brand"); - } - } -} -:host([appearance="outline-fill"][kind="danger"]) { - button, - a { - @apply border-color-danger bg-foreground-1; - color: theme("colors.danger"); - &:hover { - @apply border-color-danger-hover; - color: theme("colors.danger-hover"); - box-shadow: inset 0 0 0 1px var(--calcite-color-status-danger-hover); - } - &:focus { - @apply border-color-danger; - color: theme("colors.danger"); - box-shadow: inset 0 0 0 2px var(--calcite-color-status-danger); - } - &:active { - @apply border-color-danger-press; - color: theme("colors.danger-press"); - box-shadow: inset 0 0 0 2px var(--calcite-color-status-danger-press); - } - calcite-loader { - color: theme("colors.danger"); - } - } -} -:host([appearance="outline-fill"][kind="neutral"]) { - button, - a { - @apply text-color-1 bg-foreground-1; - border-color: theme("borderColor.color.1"); - &:hover { - box-shadow: inset 0 0 0 1px var(--calcite-color-foreground-3); - } - &:focus { - box-shadow: inset 0 0 0 2px var(--calcite-color-foreground-3); - } - &:active { - box-shadow: inset 0 0 0 2px var(--calcite-color-foreground-3); - } - calcite-loader { - @apply text-color-1; - } - } -} -:host([appearance="outline-fill"][kind="inverse"]) { - button, - a { - @apply text-color-1 bg-foreground-1; - border-color: var(--calcite-color-inverse); - &:hover { - border-color: var(--calcite-color-inverse-hover); - box-shadow: inset 0 0 0 1px var(--calcite-color-inverse-hover); - } - &:focus { - border-color: var(--calcite-color-inverse); - box-shadow: inset 0 0 0 2px var(--calcite-color-inverse); - } - &:active { - border-color: var(--calcite-color-inverse-press); - box-shadow: inset 0 0 0 2px var(--calcite-color-inverse-press); - } - calcite-loader { - @apply text-color-1; - } - } -} -:host([appearance="outline"]) { - button, - a { - @apply border border-solid bg-transparent; - box-shadow: inset 0 0 0 1px transparent; - } -} -:host([appearance="outline"][kind="brand"]) { - button, - a { - @apply border-color-brand bg-transparent; - color: theme("colors.brand"); - &:hover { - @apply border-color-brand-hover; - color: theme("colors.brand-hover"); - box-shadow: inset 0 0 0 1px var(--calcite-color-brand-hover); - } - &:focus { - @apply border-color-brand; - color: theme("colors.brand"); - box-shadow: inset 0 0 0 2px var(--calcite-color-brand); - } - &:active { - @apply border-color-brand-press; - color: theme("colors.brand-press"); - box-shadow: inset 0 0 0 2px var(--calcite-color-brand-press); - } - calcite-loader { - color: theme("colors.brand"); - } - } -} -:host([appearance="outline"][kind="danger"]) { - button, - a { - @apply border-color-danger bg-transparent; - color: theme("colors.danger"); - &:hover { - @apply border-color-danger-hover; - color: theme("colors.danger-hover"); - box-shadow: inset 0 0 0 1px var(--calcite-color-status-danger-hover); - } - &:focus { - @apply border-color-danger; - color: theme("colors.danger"); - box-shadow: inset 0 0 0 2px var(--calcite-color-status-danger); - } - &:active { - @apply border-color-danger-press; - color: theme("colors.danger-press"); - box-shadow: inset 0 0 0 2px var(--calcite-color-status-danger-press); - } - calcite-loader { - color: theme("colors.danger"); - } - } -} -:host([appearance="outline"][kind="neutral"]) { - button, - a { - @apply text-color-1 bg-transparent; - border-color: theme("borderColor.color.1"); - &:hover { - box-shadow: inset 0 0 0 1px var(--calcite-color-foreground-3); - } - &:focus { - box-shadow: inset 0 0 0 2px var(--calcite-color-foreground-3); - } - &:active { - box-shadow: inset 0 0 0 2px var(--calcite-color-foreground-3); - } - calcite-loader { - @apply text-color-1; - } - } -} -:host([appearance="outline"][kind="inverse"]) { - button, - a { - @apply text-color-1 bg-transparent; - border-color: var(--calcite-color-inverse); - &:hover { - border-color: var(--calcite-color-inverse-hover); - box-shadow: inset 0 0 0 1px var(--calcite-color-inverse-hover); - } - &:focus { - border-color: var(--calcite-color-inverse); - box-shadow: inset 0 0 0 2px var(--calcite-color-inverse); - } - &:active { - border-color: var(--calcite-color-inverse-press); - box-shadow: inset 0 0 0 2px var(--calcite-color-inverse-press); - } - calcite-loader { - @apply text-color-1; - } - } -} - :host([appearance="outline-fill"][split-child="primary"]) button, :host([appearance="outline"][split-child="primary"]) button { border-inline-end-width: 0; @@ -497,91 +502,14 @@ border-inline-end-width: theme("borderWidth.DEFAULT"); } -// transparent -:host([appearance="transparent"]:not(.enable-editing-button)) { - button, - a { - @apply bg-transparent; - &:hover, - &:focus { - background-color: var(--calcite-color-transparent-hover); - } - &:active { - background-color: var(--calcite-color-transparent-press); - } - } -} -:host([appearance="transparent"][kind="brand"]) { - button, - a { - color: theme("colors.brand"); - &:hover { - color: theme("colors.brand-hover"); - } - &:focus { - color: theme("colors.brand"); - } - &:active { - color: theme("colors.brand-press"); - } - calcite-loader { - color: theme("colors.brand"); - } - } -} - -:host([appearance="transparent"][kind="danger"]) { - button, - a { - color: theme("colors.danger"); - &:hover { - color: theme("colors.danger-hover"); - } - &:focus { - color: theme("colors.danger"); - } - &:active { - color: theme("colors.danger-press"); - } - calcite-loader { - color: theme("colors.danger"); - } - } -} - -:host([appearance="transparent"][kind="neutral"]:not(.cancel-editing-button)) { - button, - a, - calcite-loader { - @apply text-color-1; - } -} - :host([appearance="transparent"][kind="neutral"].cancel-editing-button) { button { - @apply text-color-3 - border-t-color-input - border-b-color-input - border-t - border-b; - border-block-style: solid; - &:not(.content--slotted) { - --calcite-button-padding-y-internal: 0; - } - - &:hover { - @apply text-color-1; + --calcite-internal-button-padding-y: 0; } } } -:host([appearance="transparent"][kind="neutral"].enable-editing-button) { - button { - @apply bg-transparent; - } -} - :host(.confirm-changes-button), :host(.cancel-editing-button), :host(.enable-editing-button) { @@ -592,14 +520,6 @@ } } -:host([appearance="transparent"][kind="inverse"]) { - button, - a, - calcite-loader { - @apply text-color-inverse; - } -} - // generate button scales (scenario: text exists) :host([scale="s"]) button.content--slotted, :host([scale="s"]) a.content--slotted { @@ -609,67 +529,67 @@ // accommodate for transparent buttons not having borders :host([scale="s"][appearance="transparent"]) button.content--slotted, :host([scale="s"][appearance="transparent"]) a.content--slotted { - --calcite-button-padding-x-internal: theme("padding.2"); + --calcite-internal-button-padding-x: theme("padding.2"); } :host([scale="s"]) button, :host([scale="s"]) a { - --calcite-button-padding-y-internal: 3px; + --calcite-internal-button-padding-y: 3px; } :host([scale="m"]) button.content--slotted, :host([scale="m"]) a.content--slotted { - --calcite-button-padding-x-internal: 11px; + --calcite-internal-button-padding-x: 11px; @apply text-n1h; } :host([scale="m"]) button, :host([scale="m"]) a { - --calcite-button-padding-y-internal: 7px; + --calcite-internal-button-padding-y: 7px; } // accommodate for transparent buttons not having borders :host([scale="m"][appearance="transparent"]) button.content--slotted, :host([scale="m"][appearance="transparent"]) a.content--slotted { - --calcite-button-padding-x-internal: theme("padding.3"); + --calcite-internal-button-padding-x: theme("padding.3"); } :host([scale="l"]) button.content--slotted, :host([scale="l"]) a.content--slotted { - --calcite-button-padding-x-internal: 15px; + --calcite-internal-button-padding-x: 15px; @apply text-0h; } :host([scale="l"]) { .button-padding { - --calcite-button-padding-x-internal: theme("padding.4"); - --calcite-button-padding-y-internal: 11px; + --calcite-internal-button-padding-x: theme("padding.4"); + --calcite-internal-button-padding-y: 11px; } //shrink the padding if an icon is present to preserve the height .button-padding--shrunk { - --calcite-button-padding-y-internal: 9px; + --calcite-internal-button-padding-y: 9px; } } // generate fab scales (scenario: 1 icon, ie., should be square) :host([scale="s"]) button:not(.content--slotted), :host([scale="s"]) a:not(.content--slotted) { - --calcite-button-padding-x-internal: theme("padding[0.5]"); - --calcite-button-padding-y-internal: 3px; + --calcite-internal-button-padding-x: theme("padding[0.5]"); + --calcite-internal-button-padding-y: 3px; @apply text-0h w-6; min-block-size: theme("height.6"); } :host([scale="m"]) button:not(.content--slotted), :host([scale="m"]) a:not(.content--slotted) { - --calcite-button-padding-x-internal: theme("padding[0.5]"); - --calcite-button-padding-y-internal: 7px; + --calcite-internal-button-padding-x: theme("padding[0.5]"); + --calcite-internal-button-padding-y: 7px; @apply text-0h w-8; min-block-size: theme("height.8"); } :host([scale="l"]) button:not(.content--slotted), :host([scale="l"]) a:not(.content--slotted) { - --calcite-button-padding-x-internal: theme("padding[0.5]"); - --calcite-button-padding-y-internal: 9px; + --calcite-internal-button-padding-x: theme("padding[0.5]"); + --calcite-internal-button-padding-y: 9px; @apply text-0h w-11; min-block-size: theme("height.11"); } @@ -686,33 +606,33 @@ // accommodate for transparent buttons not having borders :host([scale="l"][appearance="transparent"]) button:not(.content--slotted), :host([scale="l"][appearance="transparent"]) a:not(.content--slotted) { - --calcite-button-padding-y-internal: theme("padding[2.5]"); + --calcite-internal-button-padding-y: theme("padding[2.5]"); } // generate fab scales (scenario: 2 icons, ie., should not be square) :host([scale="s"][icon-start][icon-end]) button:not(.content--slotted), :host([scale="s"][icon-start][icon-end]) a:not(.content--slotted) { - --calcite-button-padding-x-internal: 23px; + --calcite-internal-button-padding-x: 23px; @apply text-0h h-6; } // accommodate for transparent buttons not having borders :host([scale="s"][icon-start][icon-end][appearance="transparent"]) button:not(.content--slotted), :host([scale="s"][icon-start][icon-end][appearance="transparent"]) a:not(.content--slotted) { - --calcite-button-padding-x-internal: theme("padding.6"); + --calcite-internal-button-padding-x: theme("padding.6"); } :host([scale="m"][icon-start][icon-end]) button:not(.content--slotted), :host([scale="m"][icon-start][icon-end]) a:not(.content--slotted) { - --calcite-button-padding-x-internal: theme("padding.8"); + --calcite-internal-button-padding-x: theme("padding.8"); @apply text-0h h-8; } // accommodate for transparent buttons not having borders :host([scale="m"][icon-start][icon-end][appearance="transparent"]) button:not(.content--slotted), :host([scale="m"][icon-start][icon-end][appearance="transparent"]) a:not(.content--slotted) { - --calcite-button-padding-x-internal: 33px; + --calcite-internal-button-padding-x: 33px; } :host([scale="l"][icon-start][icon-end]) button:not(.content--slotted), :host([scale="l"][icon-start][icon-end]) a:not(.content--slotted) { - --calcite-button-padding-x-internal: 43px; + --calcite-internal-button-padding-x: 43px; @apply text-0h h-11; // add space between when only 2 icons .icon--start + .icon--end { @@ -722,7 +642,7 @@ // accommodate for transparent buttons not having borders :host([scale="l"][icon-start][icon-end][appearance="transparent"]) button:not(.content--slotted), :host([scale="l"][icon-start][icon-end][appearance="transparent"]) a:not(.content--slotted) { - --calcite-button-padding-x-internal: theme("padding.11"); + --calcite-internal-button-padding-x: theme("padding.11"); } @include base-component(); diff --git a/packages/calcite-components/src/components/combobox/combobox.scss b/packages/calcite-components/src/components/combobox/combobox.scss index d6ebd9b2007..33ced65a5e4 100644 --- a/packages/calcite-components/src/components/combobox/combobox.scss +++ b/packages/calcite-components/src/components/combobox/combobox.scss @@ -10,15 +10,13 @@ @apply relative block; } -@include disabled(); -@include x-button(); - :host([scale="s"]) { @apply text-n2; --calcite-combobox-item-spacing-unit-l: theme("spacing.2"); --calcite-combobox-item-spacing-unit-s: theme("spacing.1"); --calcite-combobox-input-height: theme("spacing.4"); --calcite-internal-combobox-input-margin-block: calc(theme("spacing.1") - theme("borderWidth.DEFAULT")); + --calcite-internal-close-size: 1rem; .x-button { margin-inline: theme("spacing.2"); @@ -31,6 +29,7 @@ --calcite-combobox-item-spacing-unit-s: theme("spacing.2"); --calcite-combobox-input-height: theme("spacing.4"); --calcite-internal-combobox-input-margin-block: calc(theme("spacing.2") - theme("borderWidth.DEFAULT")); + --calcite-internal-close-size: 1.5rem; .x-button { margin-inline-end: theme("spacing.3"); @@ -43,12 +42,17 @@ --calcite-combobox-item-spacing-unit-s: theme("spacing.3"); --calcite-combobox-input-height: theme("spacing.6"); --calcite-internal-combobox-input-margin-block: calc(theme("spacing[2.5]") - theme("borderWidth.DEFAULT")); + --calcite-internal-close-size: 2rem; .x-button { margin-inline-end: theme("spacing.4"); } } +.x-button { + align-self: center; +} + .wrapper { @apply bg-foreground-1 text-color-1 @@ -259,6 +263,12 @@ calcite-chip { @apply block; } +@include disabled(); +@include x-button( + $backgroundColor: "var(--calcite-close-background-color, var(--calcite-color-foreground-2))", + $backgroundColorHover: "var(--calcite-close-background-color-hover, var(--calcite-color-foreground-3))", + $color: "var(--calcite-close-icon-color, var(--calcite-color-text-3))" +); @include form-validation-message(); @include hidden-form-input(); @include base-component(); diff --git a/packages/calcite-components/src/components/functional/XButton.tsx b/packages/calcite-components/src/components/functional/XButton.tsx index 1263a8020ea..a0393597505 100644 --- a/packages/calcite-components/src/components/functional/XButton.tsx +++ b/packages/calcite-components/src/components/functional/XButton.tsx @@ -3,29 +3,45 @@ import { JSXAttributes, JSXBase } from "@stencil/core/internal"; import { Scale } from "../interfaces"; import { getIconScale } from "../../utils/component"; -export interface XButtonProps extends JSXAttributes { +export interface XButtonProps extends JSXAttributes { disabled: boolean; + focusable?: boolean; label: string; + round?: boolean; scale: Scale; + title?: string; onClick?: JSXBase.DOMAttributes["onClick"]; } export const CSS = { button: "x-button", + buttonRound: "x-button--round", }; export const XButton: FunctionalComponent = ({ disabled, + focusable, key, label, + onClick, + ref, + round = true, scale, + title, }): VNode => ( + /> ) : null; } diff --git a/packages/calcite-components/src/components/tab/tab.e2e.ts b/packages/calcite-components/src/components/tab/tab.e2e.ts index 1ff8bf0a3de..54da9a19ea4 100644 --- a/packages/calcite-components/src/components/tab/tab.e2e.ts +++ b/packages/calcite-components/src/components/tab/tab.e2e.ts @@ -1,4 +1,5 @@ -import { defaults, renders, hidden } from "../../tests/commonTests"; +import { defaults, renders, hidden, themed } from "../../tests/commonTests"; +import { CSS } from "./resources"; describe("calcite-tab", () => { const tabHtml = "A tab"; @@ -20,4 +21,24 @@ describe("calcite-tab", () => { { propertyName: "scale", defaultValue: "m" }, ]); }); + + describe("theme", () => { + describe("default", () => { + themed("calcite-tab", { + "--calcite-tab-content-space-y": { + shadowSelector: `.${CSS.content}`, + targetProp: "paddingBlock", + }, + }); + }); + + describe("deprecated", () => { + themed("calcite-tab", { + "--calcite-tab-content-block-padding": { + shadowSelector: `.${CSS.content}`, + targetProp: "paddingBlock", + }, + }); + }); + }); }); diff --git a/packages/calcite-components/src/components/tab/tab.scss b/packages/calcite-components/src/components/tab/tab.scss index 63f7d27fa60..896d840444c 100644 --- a/packages/calcite-components/src/components/tab/tab.scss +++ b/packages/calcite-components/src/components/tab/tab.scss @@ -3,7 +3,7 @@ * * These properties can be overridden using the component's tag as selector. * - * @prop --calcite-tab-content-block-padding: Specifies the block padding of the component's content in the `default` slot. + * @prop --calcite-tab-content-block-padding: [Deprecated] Use `--calcite-tab-content-space-y` instead. Specifies the block padding of the component's content in the `default` slot. */ :host([selected]) { @@ -23,22 +23,31 @@ .content { @apply box-border; - padding-block: var(--calcite-internal-tab-content-block-padding); + padding-block: var( + --calcite-tab-content-space-y, + var(--calcite-tab-content-block-padding, var(--calcite-internal-tabs-content-space-y-fallback)) + ); } .scale-s { - --calcite-internal-tab-content-block-padding: var(--calcite-tab-content-block-padding, theme("spacing.1")); - @apply text-n2h; + --calcite-internal-tabs-content-space-y-fallback: theme("spacing.1"); + + font-size: var(--calcite-font-size-sm); + line-height: 1rem; } .scale-m { - --calcite-internal-tab-content-block-padding: var(--calcite-tab-content-block-padding, theme("spacing.2")); - @apply text-n1h; + --calcite-internal-tabs-content-space-y-fallback: theme("spacing.2"); + + font-size: var(--calcite-font-size); + line-height: 1rem; } .scale-l { - --calcite-internal-tab-content-block-padding: var(--calcite-tab-content-block-padding, theme("spacing.[2.5]")); - @apply text-0h; + --calcite-internal-tabs-content-space-y-fallback: theme("spacing.[2.5]"); + + font-size: var(--calcite-font-size-md); + line-height: 1.25rem; } section, diff --git a/packages/calcite-components/src/components/tabs/resources.ts b/packages/calcite-components/src/components/tabs/resources.ts index 325745e85ad..62f036fc6d2 100644 --- a/packages/calcite-components/src/components/tabs/resources.ts +++ b/packages/calcite-components/src/components/tabs/resources.ts @@ -1,3 +1,7 @@ +export const CSS = { + section: "section", +}; + export const SLOTS = { titleGroup: "title-group", }; diff --git a/packages/calcite-components/src/components/tabs/tabs.e2e.ts b/packages/calcite-components/src/components/tabs/tabs.e2e.ts index 819afba39c5..80d329406e5 100644 --- a/packages/calcite-components/src/components/tabs/tabs.e2e.ts +++ b/packages/calcite-components/src/components/tabs/tabs.e2e.ts @@ -1,10 +1,11 @@ import { E2EElement, E2EPage, EventSpy, newE2EPage } from "@stencil/core/testing"; import { html } from "../../../support/formatting"; -import { accessible, defaults, hidden, reflects, renders } from "../../tests/commonTests"; +import { accessible, defaults, hidden, reflects, renders, themed } from "../../tests/commonTests"; import { GlobalTestProps } from "../../tests/utils"; import { Scale } from "../interfaces"; -import { TabPosition } from "../tabs/interfaces"; -import { CSS as TabTitleCSS } from "../tab-title/resources"; +import { CSS as XButtonCSS } from "../functional/XButton"; +import { TabPosition } from "./interfaces"; +import { CSS } from "./resources"; describe("calcite-tabs", () => { const tabsContent = html` @@ -359,7 +360,7 @@ describe("calcite-tabs", () => { }); it("should emit tab change events when closing affects selected tab", async () => { - await page.click(`#tab-title-4 >>> .${TabTitleCSS.closeButton}`); + await page.click(`#tab-title-4 >>> .${XButtonCSS.button}`); await page.waitForChanges(); expect(tabsActivateSpy).toHaveReceivedEventTimes(1); @@ -377,7 +378,7 @@ describe("calcite-tabs", () => { }); it("should NOT emit tab change events when closing does not affect selected tab", async () => { - await page.click(`#tab-title-1 >>> .${TabTitleCSS.closeButton}`); + await page.click(`#tab-title-1 >>> .${XButtonCSS.button}`); await page.waitForChanges(); expect(tabsActivateSpy).toHaveReceivedEventTimes(0); @@ -393,31 +394,43 @@ describe("calcite-tabs", () => { expect(await allTabs[2].isVisible()).toBe(false); expect(await allTabs[3].isVisible()).toBe(true); }); + }); - it("should allow selecting the next tab after previous one is closed and removed from DOM", async () => { - type TestWindow = GlobalTestProps<{ selectedTitleTab: string }>; + describe("theme", () => { + describe("default", () => { + themed("calcite-tabs", { + "--calcite-tabs-border-color": { + shadowSelector: `.${CSS.section}`, + targetProp: "borderBlockStartColor", + }, + }); + }); - await page.evaluate(() => { - document.addEventListener("calciteTabChange", (event) => { - (window as TestWindow).selectedTitleTab = (event.target as HTMLCalciteTabNavElement).selectedTitle.innerText; - }); - document.addEventListener("calciteTabClose", (event) => { - const closedTabTitleElement = event.target as HTMLCalciteTabTitleElement; - const id = closedTabTitleElement.id.split("").at(-1); - closedTabTitleElement.remove(); - document.querySelector(`calcite-tab#tab-${id}`).remove(); + describe("bordered", () => { + describe("default", () => { + themed(html` `, { + "--calcite-tabs-background-color": { + targetProp: "backgroundColor", + }, + "--calcite-tabs-border-color": [ + { + targetProp: "boxShadow", + }, + { + shadowSelector: `.${CSS.section}`, + targetProp: "borderColor", + }, + ], }); }); - const tab2 = await page.find("#tab-title-2"); - - await page.click(`#tab-title-1 >>> .${TabTitleCSS.closeButton}`); - await tab2.click(); - await page.waitForChanges(); - - const selectedTitleOnEmit = await page.evaluate(() => (window as TestWindow).selectedTitleTab); - - expect(selectedTitleOnEmit).toBe("Tab 2 Title"); + describe("bottom position", () => { + themed(html` `, { + "--calcite-tabs-border-color": { + targetProp: "boxShadow", + }, + }); + }); }); }); }); diff --git a/packages/calcite-components/src/components/tabs/tabs.scss b/packages/calcite-components/src/components/tabs/tabs.scss index 96bf67d971e..d844f1ef30f 100644 --- a/packages/calcite-components/src/components/tabs/tabs.scss +++ b/packages/calcite-components/src/components/tabs/tabs.scss @@ -1,26 +1,72 @@ +/** + * CSS Custom Properties + * + * These properties can be overridden using the component's tag as selector. + * + * @prop --calcite-tab-accent-color-hover: Specifies the component's accent color when hovered. + * @prop --calcite-tab-accent-color-selected: Specifies the component's accent color when selected. + * @prop --calcite-tab-background-color-hover: Specifies the component's background color when hovered. + * @prop --calcite-tab-background-color: Specifies the component's background color. + * @prop --calcite-tab-content-space-y: Specifies the block padding of the component's content. + * @prop --calcite-tab-icon-color: Specifies the component's icon color. + * @prop --calcite-tab-icon-end-color: Specifies the component's `iconEnd` color. Fallback to `--calcite-tab-icon-color` or current color. + * @prop --calcite-tab-icon-start-color: Specifies the component's `iconStart` color. Fallback to `--calcite-tab-icon-color` or current color. + * @prop --calcite-tab-text-color-selected: Specifies the component's text color when selected. + * @prop --calcite-tab-text-color: Specifies the component's text color. + * @prop --calcite-tabs-background-color: The background color of the component. + * @prop --calcite-tabs-border-color: The border color of the component. + */ + :host { @apply flex flex-col; + + --calcite-internal-tabs-border-color: var(--calcite-tabs-border-color, var(--calcite-color-border-1)); + --calcite-internal-tabs-background-color: var(--calcite-tabs-background-color, var(--calcite-color-foreground-1)); + --calcite-internal-tab-accent-color-hover: var(--calcite-tab-accent-color-hover, var(--calcite-color-border-3)); + --calcite-internal-tab-accent-color-selected: var(--calcite-tab-accent-color-selected, var(--calcite-color-brand)); + --calcite-internal-tab-background-color-hover: var( + --calcite-tab-background-color-hover, + var(--calcite-color-foreground-2) + ); } :host([bordered]) { - box-shadow: inset 0 1px 0 var(--calcite-color-border-1); - background-color: var(--calcite-color-foreground-1); + box-shadow: inset 0 1px 0 var(--calcite-internal-tabs-border-color); + background-color: var(--calcite-internal-tabs-background-color); section { - @apply border-color-1 border border-solid; + border-color: var(--calcite-internal-tabs-border-color); + border-style: solid; } } +section { + @apply border flex flex-grow overflow-hidden; + + border-block-start-style: solid; + border-block-start-color: var(--calcite-internal-tabs-border-color); +} + :host([bordered][position="bottom"]) { box-shadow: - inset 0 1px 0 var(--calcite-color-border-1), - inset 0 -1px 0 var(--calcite-color-border-1); + inset 0 1px 0 var(--calcite-internal-tabs-border-color), + inset 0 -1px 0 var(--calcite-internal-tabs-border-color); } :host([bordered]:not([position="bottom"])) ::slotted(calcite-tab-nav) { margin-block-end: -1px; } +:host([position="bottom"]) { + @apply flex-col-reverse; + + section { + @apply flex-col-reverse + border-t-0 + border-b; + } +} + :host([bordered][scale="s"]) section { @apply p-3; } @@ -33,28 +79,9 @@ @apply p-4; } -:host([position="bottom"]) { - @apply flex-col-reverse; -} - -section { - @apply border-t-color-1 - flex - flex-grow - overflow-hidden - border-t; - border-block-start-style: solid; -} - -:host([position="bottom"]) section { - @apply border-b-color-1 - flex-col-reverse - border-t-0 - border-b; -} - :host([position="bottom"]:not([bordered])) section { border-block-end-style: solid; + border-block-end-color: var(--calcite-internal-tabs-border-color); } @media (forced-colors: active) { diff --git a/packages/calcite-components/src/components/tabs/tabs.tsx b/packages/calcite-components/src/components/tabs/tabs.tsx index 4c7755f4b3a..8d8358a0ed2 100644 --- a/packages/calcite-components/src/components/tabs/tabs.tsx +++ b/packages/calcite-components/src/components/tabs/tabs.tsx @@ -2,7 +2,7 @@ import { Component, Element, Fragment, h, Listen, Prop, State, VNode, Watch } fr import { Scale } from "../interfaces"; import { getSlotAssignedElements, slotChangeGetAssignedElements } from "../../utils/dom"; import { TabLayout, TabPosition } from "./interfaces"; -import { SLOTS } from "./resources"; +import { CSS, SLOTS } from "./resources"; /** * @slot - A slot for adding `calcite-tab`s. @@ -196,7 +196,7 @@ export class Tabs { return ( -
+
diff --git a/packages/calcite-components/src/custom-theme.stories.ts b/packages/calcite-components/src/custom-theme.stories.ts index 7a1aa0767eb..3c1e9aa1a29 100644 --- a/packages/calcite-components/src/custom-theme.stories.ts +++ b/packages/calcite-components/src/custom-theme.stories.ts @@ -32,7 +32,7 @@ import { popover, popoverTokens } from "./custom-theme/popover"; import { progress, progressTokens } from "./custom-theme/progress"; import { segmentedControl } from "./custom-theme/segmented-control"; import { slider } from "./custom-theme/slider"; -import { tabs } from "./custom-theme/tabs"; +import { tabs, tabsBordered, tabsTokens } from "./custom-theme/tabs"; import { textArea, textAreaTokens } from "./custom-theme/text-area"; import { avatarIcon, avatarInitials, avatarThumbnail, avatarTokens } from "./custom-theme/avatar"; @@ -115,7 +115,7 @@ const kitchenSink = (args: Record, useTestValues = false) =>
${checkbox}
${chips} ${pagination} ${slider} -
${datePicker} ${tabs} ${loader} ${calciteSwitch} ${avatarIcon} ${avatarInitials} ${avatarThumbnail} ${progress} ${handle} ${textArea} ${popover}
+
${datePicker} ${tabs} ${tabsBordered} ${loader} ${calciteSwitch} ${avatarIcon} ${avatarInitials} ${avatarThumbnail} ${progress} ${handle} ${textArea} ${popover}
${alert} @@ -123,22 +123,23 @@ const kitchenSink = (args: Record, useTestValues = false) => const componentTokens = { ...globalTokens, - ...accordionTokens, ...accordionItemTokens, - ...actionTokens, + ...accordionTokens, ...actionBarTokens, ...actionGroupTokens, ...actionMenuTokens, ...actionPadTokens, + ...actionTokens, + ...alertTokens, ...avatarTokens, ...cardTokens, - ...alertTokens, - ...chipTokens, ...checkboxTokens, + ...chipTokens, ...handleTokens, + ...inputTokens, ...popoverTokens, ...progressTokens, - ...inputTokens, + ...tabsTokens, ...textAreaTokens, }; diff --git a/packages/calcite-components/src/custom-theme/tabs.ts b/packages/calcite-components/src/custom-theme/tabs.ts index ff61b2d6c1e..69c87d49de4 100644 --- a/packages/calcite-components/src/custom-theme/tabs.ts +++ b/packages/calcite-components/src/custom-theme/tabs.ts @@ -1,10 +1,125 @@ import { html } from "../../support/formatting"; -export const tabs = html` - - Tab 1 Title - Tab 2 Title - Tab 3 Title - Tab 4 Title - -`; +export const tabsTokens = { + calciteTabsBackgroundColor: "", + calciteTabsBorderColor: "", + calciteTabAccentColorSelected: "", + calciteTabBackgroundColorHover: "", + calciteTabBackgroundColor: "", + calciteTabContentSpaceY: "", + calciteTabIconColor: "", + calciteTabTextColorSelected: "", + calciteTabTextColor: "", +}; + +export const tabs = html` + + + + + Tab 1 Title + + Tab 2 Title + Tab 3 Title + Tab 4 Title + Tab 5 Title + Tab 6 Title + Tab 7 Title + Tab 8 Title + + Tab 1 Content + Tab 2 Content + Tab 3 Content + Tab 4 Content + Tab 5 Content + Tab 6 Content + Tab 7 Content + Tab 8 Content + + +
+ + + + Tab 1 Title + + Tab 2 Title + Tab 3 Title + Tab 4 Title + Tab 5 Title + Tab 6 Title + Tab 7 Title + Tab 8 Title + + Tab 1 Content + Tab 2 Content + Tab 3 Content + Tab 4 Content + Tab 5 Content + Tab 6 Content + Tab 7 Content + Tab 8 Content + +`; + +export const tabsBordered = html` + + + + + Tab 1 Title + + Tab 2 Title + Tab 3 Title + Tab 4 Title + Tab 5 Title + Tab 6 Title + Tab 7 Title + Tab 8 Title + + Tab 1 Content + Tab 2 Content + Tab 3 Content + Tab 4 Content + Tab 5 Content + Tab 6 Content + Tab 7 Content + Tab 8 Content + + +
+ + + + Tab 1 Title + + Tab 2 Title + Tab 3 Title + Tab 4 Title + Tab 5 Title + Tab 6 Title + Tab 7 Title + Tab 8 Title + + Tab 1 Content + Tab 2 Content + Tab 3 Content + Tab 4 Content + Tab 5 Content + Tab 6 Content + Tab 7 Content + Tab 8 Content + +`; diff --git a/packages/calcite-components/src/demos/tabs.html b/packages/calcite-components/src/demos/tabs.html index 866245228a4..c6196696e91 100644 --- a/packages/calcite-components/src/demos/tabs.html +++ b/packages/calcite-components/src/demos/tabs.html @@ -46,36 +46,6 @@
large
- -
-
simple
- -
- - Tab 1 Title - Tab 2 Title - Tab 3 Title - -
- -
- - Tab 1 Title - Tab 2 Title - Tab 3 Title - -
- -
- - Tab 1 Title - Tab 2 Title - Tab 3 Title - Tab 4 Title - -
-
-
tab position: top (default)
@@ -592,6 +562,125 @@
+ + + + +
+
Theme
+ +
+ + + Tab 1 Title + Tab 2 Title + Tab 3 Title + Tab 4 Title + Tab 5 Title + Tab 6 Title + Tab 7 Title + Tab 8 Title + + Tab 1 Content + Tab 2 Content + Tab 3 Content + Tab 4 Content + Tab 5 Content + Tab 6 Content + Tab 7 Content + Tab 8 Content + + +
+ + + + Tab 1 Title + Tab 2 Title + Tab 3 Title + Tab 4 Title + Tab 5 Title + Tab 6 Title + Tab 7 Title + Tab 8 Title + + Tab 1 Content + Tab 2 Content + Tab 3 Content + Tab 4 Content + Tab 5 Content + Tab 6 Content + Tab 7 Content + Tab 8 Content + +
+ +
+ + + Tab 1 Title + Tab 2 Title + Tab 3 Title + Tab 4 Title + Tab 5 Title + Tab 6 Title + Tab 7 Title + Tab 8 Title + + Tab 1 Content + Tab 2 Content + Tab 3 Content + Tab 4 Content + Tab 5 Content + Tab 6 Content + Tab 7 Content + Tab 8 Content + + +
+ + + + Tab 1 Title + Tab 2 Title + Tab 3 Title + Tab 4 Title + Tab 5 Title + Tab 6 Title + Tab 7 Title + Tab 8 Title + + Tab 1 Content + Tab 2 Content + Tab 3 Content + Tab 4 Content + Tab 5 Content + Tab 6 Content + Tab 7 Content + Tab 8 Content + +
+
+