diff --git a/packages/components/outline-core-heading/README.md b/packages/components/outline-core-heading/README.md new file mode 100644 index 000000000..57728ae46 --- /dev/null +++ b/packages/components/outline-core-heading/README.md @@ -0,0 +1,17 @@ +# outline-core-heading + +## Properties + +| Property | Attribute | Type | Description | +|---------------------|----------------------|-------------------------|--------------------------------------------------| +| `additionalClasses` | `additional-classes` | `string` | Additional CSS classes to apply to the heading element. | +| `level` | `level` | `string \| undefined` | The tag to apply: h1 \| h2 \| h3 \| h4 \| h5 \| h6 | +| `size` | `size` | `AllowedHeadingSizes` | The size of the heading. | +| `weight` | `weight` | `AllowedHeadingWeights` | The weight of the heading. | + +## Methods + +| Method | Type | +|--------------------|--------------------------------------------------| +| `fullMarkupInSlot` | `(classes: { [key: string]: string \| boolean; }): TemplateResult` | +| `generateHeading` | `(classes: { [key: string]: string \| boolean; }): TemplateResult` | diff --git a/packages/components/outline-core-heading/index.ts b/packages/components/outline-core-heading/index.ts new file mode 100644 index 000000000..ea7ea58a4 --- /dev/null +++ b/packages/components/outline-core-heading/index.ts @@ -0,0 +1,3 @@ +export { OutlineCoreHeading } from './src/outline-core-heading'; +export type { AllowedHeadingLevels, AllowedHeadingSizes } from './src/config'; +export { HeadingLevels, HeadingSizes, HeadingWeights } from './src/config'; diff --git a/packages/components/outline-core-heading/package.json b/packages/components/outline-core-heading/package.json new file mode 100644 index 000000000..54100551b --- /dev/null +++ b/packages/components/outline-core-heading/package.json @@ -0,0 +1,40 @@ +{ + "name": "@phase2/outline-core-heading", + "version": "0.0.0", + "description": "The Outline Components for the web heading component", + "keywords": [ + "outline components", + "outline design", + "heading" + ], + "main": "index.ts", + "types": "index.ts", + "typings": "index.d.ts", + "files": [ + "/dist/", + "/src/", + "!/dist/tsconfig.build.tsbuildinfo" + ], + "author": "Phase2 Technology", + "repository": { + "type": "git", + "url": "https://github.com/phase2/outline.git", + "directory": "packages/outline-core-heading" + }, + "license": "BSD-3-Clause", + "scripts": { + "build": "node ../../scripts/build.js", + "package": "yarn publish" + }, + "dependencies": { + "@phase2/outline-core": "^0.1.9", + "lit": "^2.3.1", + "tslib": "^2.1.0" + }, + "publishConfig": { + "access": "public" + }, + "exports": { + ".": "./index.ts" + } +} diff --git a/packages/components/outline-core-heading/src/config.ts b/packages/components/outline-core-heading/src/config.ts new file mode 100644 index 000000000..3ff68cc9c --- /dev/null +++ b/packages/components/outline-core-heading/src/config.ts @@ -0,0 +1,27 @@ +export const HeadingLevels = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', undefined]; +export type AllowedHeadingLevels = (typeof HeadingLevels)[number]; + +// Updated to limit the allowed values to the set we want to be selectable in Storybook. +export const HeadingSizes = [ + 'xs', + 'sm', + 'md', + 'lg', + 'xl', + 'xxl', + 'xxxl', +] as const; +export type AllowedHeadingSizes = (typeof HeadingSizes)[number]; + +export const HeadingWeights = [ + 'thin', + 'extralight', + 'light', + 'normal', + 'medium', + 'semibold', + 'bold', + 'extrabold', + 'black', +] as const; +export type AllowedHeadingWeights = (typeof HeadingWeights)[number]; diff --git a/packages/components/outline-core-heading/src/outline-core-heading.css b/packages/components/outline-core-heading/src/outline-core-heading.css new file mode 100644 index 000000000..7e52c9e15 --- /dev/null +++ b/packages/components/outline-core-heading/src/outline-core-heading.css @@ -0,0 +1,90 @@ +.clickable-card { + /* Required to allow the functionallity of full card being clickable */ + h1, + h2, + h3, + h4, + h5, + h6 { + a { + &:hover { + text-decoration: none; + } + &:after { + position: absolute; + inset: 0; + content: ''; + } + } + } +} + +.md { + @apply text-base; +} + +.xs { + @apply text-xs; +} + +.sm { + @apply text-sm; +} + +.lg { + @apply text-lg; +} + +.lg.mobile { + @apply text-base; +} + +.xl { + @apply text-xl; +} + +.xl.mobile { + @apply text-base; +} + +.xxl { + @apply text-2xl; +} + +.xxl.mobile { + @apply text-lg; +} + +.xxxl { + @apply text-3xl; +} + +.xxxl.mobile { + @apply text-lg; +} + +/* Font weights */ +.thin { + @apply font-thin; +} +.extralight { + @apply font-extralight; +} +.light { + @apply font-light; +} +.normal { + @apply font-normal; +} +.semibold { + @apply font-semibold; +} +.bold { + @apply font-bold; +} +.extrabold { + @apply font-extrabold; +} +.black { + @apply font-black; +} diff --git a/packages/components/outline-core-heading/src/outline-core-heading.lightdom.css b/packages/components/outline-core-heading/src/outline-core-heading.lightdom.css new file mode 100644 index 000000000..7e52c9e15 --- /dev/null +++ b/packages/components/outline-core-heading/src/outline-core-heading.lightdom.css @@ -0,0 +1,90 @@ +.clickable-card { + /* Required to allow the functionallity of full card being clickable */ + h1, + h2, + h3, + h4, + h5, + h6 { + a { + &:hover { + text-decoration: none; + } + &:after { + position: absolute; + inset: 0; + content: ''; + } + } + } +} + +.md { + @apply text-base; +} + +.xs { + @apply text-xs; +} + +.sm { + @apply text-sm; +} + +.lg { + @apply text-lg; +} + +.lg.mobile { + @apply text-base; +} + +.xl { + @apply text-xl; +} + +.xl.mobile { + @apply text-base; +} + +.xxl { + @apply text-2xl; +} + +.xxl.mobile { + @apply text-lg; +} + +.xxxl { + @apply text-3xl; +} + +.xxxl.mobile { + @apply text-lg; +} + +/* Font weights */ +.thin { + @apply font-thin; +} +.extralight { + @apply font-extralight; +} +.light { + @apply font-light; +} +.normal { + @apply font-normal; +} +.semibold { + @apply font-semibold; +} +.bold { + @apply font-bold; +} +.extrabold { + @apply font-extrabold; +} +.black { + @apply font-black; +} diff --git a/packages/components/outline-core-heading/src/outline-core-heading.ts b/packages/components/outline-core-heading/src/outline-core-heading.ts new file mode 100644 index 000000000..a3916c854 --- /dev/null +++ b/packages/components/outline-core-heading/src/outline-core-heading.ts @@ -0,0 +1,149 @@ +/** + * The Heading component. + * @element outline-core-heading + * @slot defaultSlot + */ +import { TemplateResult } from 'lit'; +import { html, unsafeStatic } from 'lit/static-html.js'; +import { AdoptedStyleSheets } from '@phase2/outline-adopted-stylesheets-controller'; +import { classMap } from 'lit/directives/class-map.js'; +import { customElement, property } from 'lit/decorators.js'; +import globalStyles from './outline-core-heading.lightdom.css.lit'; + +import { OutlineElement } from '@phase2/outline-core'; + +import componentStyles from './outline-core-heading.css.lit'; +import { AllowedHeadingLevels } from './config'; + +export const allowedHeadingSizes = [ + 'xs', + 'sm', + 'md', + 'lg', + 'xl', + 'xxl', + 'xxxl', +]; +export const allowedHeadingWeights = [ + 'thin', + 'extralight', + 'light', + 'normal', + 'medium', + 'semibold', + 'bold', + 'extrabold', + 'black', +]; + +// export type ButtonVariant = keyof typeof buttonVariantsTypes; +export type HeadingSizes = keyof typeof allowedHeadingSizes; +export type HeadingWeights = keyof typeof allowedHeadingWeights; + +@customElement('outline-core-heading') +export class OutlineCoreHeading extends OutlineElement { + static styles = [componentStyles]; + AdoptedStyleSheets: AdoptedStyleSheets; + + connectedCallback() { + super.connectedCallback(); + this.AdoptedStyleSheets = new AdoptedStyleSheets(globalStyles); + this.addController(this.AdoptedStyleSheets); + } + + /** + * The tag to apply: h1 | h2 | h3 | h4 | h5 | h6 + */ + @property({ type: String, reflect: true, attribute: 'level' }) + level: AllowedHeadingLevels; + + /** + * The size of the heading. + * @type {HeadingSizes} + */ + @property({ + type: String, + reflect: true, + attribute: 'size', + converter: size => { + if (size && !Object.values(allowedHeadingSizes).includes(size)) { + size = allowedHeadingSizes[0]; + } + return size; + }, + }) + size: HeadingSizes; + + /** + * The weight of the heading. + * @type {HeadingWeights} + */ + @property({ + type: String, + reflect: true, + attribute: 'weight', + converter: weight => { + if (weight && !Object.values(allowedHeadingWeights).includes(weight)) { + weight = allowedHeadingWeights[0]; + } + return weight; + }, + }) + weight: HeadingWeights; + + /** + * Additional CSS classes to apply to the heading element. + * @type {string} + */ + @property({ type: String, reflect: true, attribute: 'additional-classes' }) + additionalClasses: string; + + generateHeading(classes: { + [key: string]: boolean | string; + }): TemplateResult { + return html` + <${unsafeStatic(this.level as string)} class=${classMap(classes)}> + + + `; + } + + fullMarkupInSlot(classes: { + [key: string]: boolean | string; + }): TemplateResult { + return html` `; + } + + render(): TemplateResult { + const classes = { + [`${this.additionalClasses}`]: this.additionalClasses, + [`${String(this.size)}`]: this.size as string, + [`${String(this.weight)}`]: this.weight as string, + }; + const typedValues = allowedHeadingSizes.concat(allowedHeadingWeights); + const slottedHeading: HTMLElement | null = + this.querySelector(':is(h1, h2, h3, h4, h5, h6)') ?? null; + if (slottedHeading) { + // add classes from shadow DOM of component to light DOM of Slot + slottedHeading.classList.remove(...typedValues); + if (this.size) { + slottedHeading?.classList.add(this.size as string); + } + if (this.weight) { + slottedHeading?.classList.add(this.weight as string); + } + } + + if (this.level) { + return this.generateHeading(classes); + } else { + return this.fullMarkupInSlot(classes); + } + } +} + +declare global { + interface HTMLElementTagNameMap { + 'outline-core-heading': OutlineCoreHeading; + } +} diff --git a/packages/components/outline-core-heading/src/test/outline-core-heading.test.ts b/packages/components/outline-core-heading/src/test/outline-core-heading.test.ts new file mode 100644 index 000000000..b5411c24c --- /dev/null +++ b/packages/components/outline-core-heading/src/test/outline-core-heading.test.ts @@ -0,0 +1,26 @@ +import { OutlineCoreHeading } from '../outline-core-heading'; +import { fixture, html, assert } from '@open-wc/testing'; + +describe('outline-heading', () => { + it('is defined', () => { + const el = document.createElement('outline-heading'); + assert.instanceOf(el, OutlineCoreHeading); + }); + + it('renders with default values', async () => { + const el = await fixture(html``); + assert.shadowDom.equal( + el, + ` +

+ +

+ ` + ); + }); + + it('renders with slotted content', async () => { + const el = await fixture(html`Test`); + assert.lightDom.equal(el, `Test`); + }); +}); diff --git a/packages/components/outline-core-heading/tsconfig.build.json b/packages/components/outline-core-heading/tsconfig.build.json new file mode 100644 index 000000000..ebc8e4b8e --- /dev/null +++ b/packages/components/outline-core-heading/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "./dist" + }, + "include": ["index.ts", "src/**/*", "tests/**/*"], + "references": [{ "path": "../outline-core/tsconfig.build.json" }] +} diff --git a/packages/documentation/outline-storybook/config/storybook.main.css b/packages/documentation/outline-storybook/config/storybook.main.css index 70c1d8ddd..1eb20ce1a 100644 --- a/packages/documentation/outline-storybook/config/storybook.main.css +++ b/packages/documentation/outline-storybook/config/storybook.main.css @@ -1,385 +1,381 @@ @import url('https://rsms.me/inter/inter.css'); -:root { - --brand-primary: #2563eb; - --brand-secondary: #059669; - --brand-tertiary: #dc2626; - --brand-quaternary: #d97706; - --brand-quinary: #9333ea; - --brand-senary: #db2777; - --brand-septenary: #4f46e5; - --brand-octonary: #525252; - --brand-nonary: #1e3a8a; - --brand-denary: #171717; - --status-success: #2f855a; - --status-warning: #b64301; - --status-error: #c53030; - --status-info: #1e3a8a; - --outline-phase2-blue: #0080ff; - --outline-karma-coral: #fa5c5c; - --outline-soft-black: #171717; - --outline-not-gray: #cfc7d4; - --outline-misty-teal: #73f2e5; - --outline-electric-violet: #9484ff; - --outline-dusty-blue: #7fc7ee; - --outline-transparent: transparent; - --outline-white: #fff; - --outline-black: #000; +:root{ + --brand-primary:#2563eb; + --brand-secondary:#059669; + --brand-tertiary:#dc2626; + --brand-quaternary:#d97706; + --brand-quinary:#9333ea; + --brand-senary:#db2777; + --brand-septenary:#4f46e5; + --brand-octonary:#525252; + --brand-nonary:#1e3a8a; + --brand-denary:#171717; + --status-success:#2f855a; + --status-warning:#b64301; + --status-error:#c53030; + --status-info:#1e3a8a; + --outline-phase2-blue:#0080ff; + --outline-karma-coral:#fa5c5c; + --outline-soft-black:#171717; + --outline-not-gray:#cfc7d4; + --outline-misty-teal:#73f2e5; + --outline-electric-violet:#9484ff; + --outline-dusty-blue:#7fc7ee; + --outline-transparent:transparent; + --outline-white:#fff; + --outline-black:#000; + + --outline-gray-50:#fafafa; + --outline-gray-100:#f5f5f5; + --outline-gray-200:#e5e5e5; + --outline-gray-300:#d4d4d4; + --outline-gray-400:#a3a3a3; + --outline-gray-500:#737373; + --outline-gray-600:#525252; + --outline-gray-700:#404040; + --outline-gray-800:#262626; + --outline-gray-900:#171717; - --outline-gray-50: #fafafa; - --outline-gray-100: #f5f5f5; - --outline-gray-200: #e5e5e5; - --outline-gray-300: #d4d4d4; - --outline-gray-400: #a3a3a3; - --outline-gray-500: #737373; - --outline-gray-600: #525252; - --outline-gray-700: #404040; - --outline-gray-800: #262626; - --outline-gray-900: #171717; + --outline-blue-50:#eff6ff; + --outline-blue-100:#dbeafe; + --outline-blue-200:#bfdbfe; + --outline-blue-300:#93c5fd; + --outline-blue-400:#60a5fa; + --outline-blue-500:#3b82f6; + --outline-blue-600:#2563eb; + --outline-blue-700:#1d4ed8; + --outline-blue-800:#1e40af; + --outline-blue-900:#1e3a8a; - --outline-blue-50: #eff6ff; - --outline-blue-100: #dbeafe; - --outline-blue-200: #bfdbfe; - --outline-blue-300: #93c5fd; - --outline-blue-400: #60a5fa; - --outline-blue-500: #3b82f6; - --outline-blue-600: #2563eb; - --outline-blue-700: #1d4ed8; - --outline-blue-800: #1e40af; - --outline-blue-900: #1e3a8a; + --red-50:#fef2f2; + --red-100:#fee2e2; + --red-200:#fecaca; + --red-300:#fca5a5; + --red-400:#f87171; + --red-500:#ef4444; + --red-600:#dc2626; + --red-700:#b91c1c; + --red-800:#991b1b; + --red-900:#7f1d1d; + --yellow-50:#fffbeb; + --yellow-100:#fef3c7; + --yellow-200:#fde68a; + --yellow-300:#fcd34d; + --yellow-400:#fbbf24; + --yellow-500:#f59e0b; + --yellow-600:#d97706; + --yellow-700:#b45309; + --yellow-800:#92400e; + --yellow-900:#78350f; + --green-50:#ecfdf5; + --green-100:#d1fae5; + --green-200:#a7f3d0; + --green-300:#6ee7b7; + --green-400:#34d399; + --green-500:#10b981; + --green-600:#059669; + --green-700:#047857; + --green-800:#065f46; + --green-900:#064e3b; + --indigo-50:#eef2ff; + --indigo-100:#e0e7ff; + --indigo-200:#c7d2fe; + --indigo-300:#a5b4fc; + --indigo-400:#818cf8; + --indigo-500:#6366f1; + --indigo-600:#4f46e5; + --indigo-700:#4338ca; + --indigo-800:#3730a3; + --indigo-900:#312e81; + --purple-50:#faf5ff; + --purple-100:#f3e8ff; + --purple-200:#e9d5ff; + --purple-300:#d8b4fe; + --purple-400:#c084fc; + --purple-500:#a855f7; + --purple-600:#9333ea; + --purple-700:#7e22ce; + --purple-800:#6b21a8; + --purple-900:#581c87; + --pink-50:#fdf2f8; + --pink-100:#fce7f3; + --pink-200:#fbcfe8; + --pink-300:#f9a8d4; + --pink-400:#f472b6; + --pink-500:#ec4899; + --pink-600:#db2777; + --pink-700:#be185d; + --pink-800:#9d174d; + --pink-900:#831843; + --screen-xs:480px; + --screen-sm:640px; + --screen-md:768px; + --screen-lg:1024px; + --screen-xl:1280px; + --screen-xxl:1440px; + --screen-xxxl:2180px; - --red-50: #fef2f2; - --red-100: #fee2e2; - --red-200: #fecaca; - --red-300: #fca5a5; - --red-400: #f87171; - --red-500: #ef4444; - --red-600: #dc2626; - --red-700: #b91c1c; - --red-800: #991b1b; - --red-900: #7f1d1d; - --yellow-50: #fffbeb; - --yellow-100: #fef3c7; - --yellow-200: #fde68a; - --yellow-300: #fcd34d; - --yellow-400: #fbbf24; - --yellow-500: #f59e0b; - --yellow-600: #d97706; - --yellow-700: #b45309; - --yellow-800: #92400e; - --yellow-900: #78350f; - --green-50: #ecfdf5; - --green-100: #d1fae5; - --green-200: #a7f3d0; - --green-300: #6ee7b7; - --green-400: #34d399; - --green-500: #10b981; - --green-600: #059669; - --green-700: #047857; - --green-800: #065f46; - --green-900: #064e3b; - --indigo-50: #eef2ff; - --indigo-100: #e0e7ff; - --indigo-200: #c7d2fe; - --indigo-300: #a5b4fc; - --indigo-400: #818cf8; - --indigo-500: #6366f1; - --indigo-600: #4f46e5; - --indigo-700: #4338ca; - --indigo-800: #3730a3; - --indigo-900: #312e81; - --purple-50: #faf5ff; - --purple-100: #f3e8ff; - --purple-200: #e9d5ff; - --purple-300: #d8b4fe; - --purple-400: #c084fc; - --purple-500: #a855f7; - --purple-600: #9333ea; - --purple-700: #7e22ce; - --purple-800: #6b21a8; - --purple-900: #581c87; - --pink-50: #fdf2f8; - --pink-100: #fce7f3; - --pink-200: #fbcfe8; - --pink-300: #f9a8d4; - --pink-400: #f472b6; - --pink-500: #ec4899; - --pink-600: #db2777; - --pink-700: #be185d; - --pink-800: #9d174d; - --pink-900: #831843; - --screen-xs: 480px; - --screen-sm: 640px; - --screen-md: 768px; - --screen-lg: 1024px; - --screen-xl: 1280px; - --screen-xxl: 1440px; - --screen-xxxl: 2180px; + --spacing-0:0px; + --spacing-1:0.25rem; + --spacing-2:0.5rem; + --spacing-3:0.75rem; + --spacing-4:1rem; + --spacing-5:1.25rem; + --spacing-6:1.5rem; + --spacing-7:1.75rem; + --spacing-8:2rem; + --spacing-9:2.25rem; + --spacing-10:2.5rem; + --spacing-11:2.75rem; + --spacing-12:3rem; + --spacing-14:3.5rem; + --spacing-16:4rem; + --spacing-20:5rem; + --spacing-24:6rem; + --spacing-28:7rem; + --spacing-32:8rem; + --spacing-36:9rem; + --spacing-40:10rem; + --spacing-44:11rem; + --spacing-48:12rem; + --spacing-52:13rem; + --spacing-56:14rem; + --spacing-60:15rem; + --spacing-64:16rem; + --spacing-72:18rem; + --spacing-80:20rem; + --spacing-96:24rem; + --spacing-px:1px; - --spacing-0: 0px; - --spacing-1: 0.25rem; - --spacing-2: 0.5rem; - --spacing-3: 0.75rem; - --spacing-4: 1rem; - --spacing-5: 1.25rem; - --spacing-6: 1.5rem; - --spacing-7: 1.75rem; - --spacing-8: 2rem; - --spacing-9: 2.25rem; - --spacing-10: 2.5rem; - --spacing-11: 2.75rem; - --spacing-12: 3rem; - --spacing-14: 3.5rem; - --spacing-16: 4rem; - --spacing-20: 5rem; - --spacing-24: 6rem; - --spacing-28: 7rem; - --spacing-32: 8rem; - --spacing-36: 9rem; - --spacing-40: 10rem; - --spacing-44: 11rem; - --spacing-48: 12rem; - --spacing-52: 13rem; - --spacing-56: 14rem; - --spacing-60: 15rem; - --spacing-64: 16rem; - --spacing-72: 18rem; - --spacing-80: 20rem; - --spacing-96: 24rem; - --spacing-px: 1px; + --fs-xs:0.75rem; + --fs-sm:0.875rem; + --fs-base:1rem; + --fs-lg:1.125rem; + --fs-xl:1.25rem; + --fs-2xl:1.5rem; + --fs-3xl:1.875rem; + --fs-4xl:2.25rem; + --fs-5xl:3.5rem; + --fs-6xl:4.5rem; + --fs-7xl:5.5rem; + --fs-8xl:6.5rem; + --fs-9xl:7.5rem; - --fs-xs: 0.75rem; - --fs-sm: 0.875rem; - --fs-base: 1rem; - --fs-lg: 1.125rem; - --fs-xl: 1.25rem; - --fs-2xl: 1.5rem; - --fs-3xl: 1.875rem; - --fs-4xl: 2.25rem; - --fs-5xl: 3.5rem; - --fs-6xl: 4.5rem; - --fs-7xl: 5.5rem; - --fs-8xl: 6.5rem; - --fs-9xl: 7.5rem; + --lh-xs:1rem; + --lh-sm:1.25rem; + --lh-base:1.5rem; + --lh-lg:1.75rem; + --lh-xl:1.75rem; + --lh-2xl:2rem; + --lh-3xl:2.25rem; + --lh-4xl:2.5rem; + --lh-5xl:3.75rem; + --lh-6xl:4.75rem; + --lh-7xl:5.75rem; + --lh-8xl:6.75rem; + --lh-9xl:7.75rem; - --lh-xs: 1rem; - --lh-sm: 1.25rem; - --lh-base: 1.5rem; - --lh-lg: 1.75rem; - --lh-xl: 1.75rem; - --lh-2xl: 2rem; - --lh-3xl: 2.25rem; - --lh-4xl: 2.5rem; - --lh-5xl: 3.75rem; - --lh-6xl: 4.75rem; - --lh-7xl: 5.75rem; - --lh-8xl: 6.75rem; - --lh-9xl: 7.75rem; + --ff-display:'Inter var', 'Helvetica', 'Arial', 'sans-serif'; + --ff-body:'Inter var', 'Helvetica', 'Arial', 'sans-serif'; + --ff-demo:'Inter var', 'Helvetica', 'Arial', 'sans-serif'; - --ff-display: 'Inter var', 'Helvetica', 'Arial', 'sans-serif'; - --ff-body: 'Inter var', 'Helvetica', 'Arial', 'sans-serif'; - --ff-demo: 'Inter var', 'Helvetica', 'Arial', 'sans-serif'; + --fw-thin:100; + --fw-extralight:200; + --fw-light:300; + --fw-normal:400; + --fw-medium:500; + --fw-semibold:600; + --fw-bold:700; + --fw-extrabold:800; + --fw-black:900; - --fw-thin: 100; - --fw-extralight: 200; - --fw-light: 300; - --fw-normal: 400; - --fw-medium: 500; - --fw-semibold: 600; - --fw-bold: 700; - --fw-extrabold: 800; - --fw-black: 900; + --fs-h1:4rem; + --fs-h1-medium:3rem; + --fs-h1-small:2.5rem; + + --lh-h1:3rem; + --lh-h1-medium:3.75rem; + --lh-h1-small:2rem; - --fs-h1: 4rem; - --fs-h1-medium: 3rem; - --fs-h1-small: 2.5rem; + --fs-h2:2.75rem; + --fs-h2-medium:2.5rem; + --fs-h2-small:2rem; + + --lh-h2:3.5rem; + --lh-h2-medium:3rem; + --lh-h2-small:2.5rem; + - --lh-h1: 3rem; - --lh-h1-medium: 3.75rem; - --lh-h1-small: 2rem; - - --fs-h2: 2.75rem; - --fs-h2-medium: 2.5rem; - --fs-h2-small: 2rem; - - --lh-h2: 3.5rem; - --lh-h2-medium: 3rem; - --lh-h2-small: 2.5rem; - - --fs-h3: 2rem; - --fs-h3-medium: 1.75rem; - --fs-h3-small: 1.5rem; - - --lh-h3: 2.25rem; - --lh-h3-medium: 2rem; - --lh-h3-small: 1.75rem; - - --fs-h4: 1.5rem; - --fs-h4-medium: 1.5rem; - --fs-h4-small: 1.375rem; - - --lh-h4: 2rem; - --lh-h4-medium: 1.75rem; - --lh-h4-small: 1.75rem; - - --fs-h5: 1.375rem; - --fs-h5-medium: 1.25rem; - --fs-h5-small: 1.125rem; - - --lh-h5: 1.75rem; - --lh-h5-medium: 1.5rem; - --lh-h5-small: 1.375rem; - - --fs-h6: 1.125rem; - --fs-h6-medium: 1.125rem; - --fs-h6-small: 1rem; - - --lh-h6: 1.5rem; - --lh-h6-medium: 1.375rem; - --lh-h6-small: 1.25rem; - --outline-ring-width: 2px; + --fs-h3:2rem; + --fs-h3-medium:1.75rem; + --fs-h3-small:1.5rem; + + --lh-h3:2.25rem; + --lh-h3-medium:2rem; + --lh-h3-small:1.75rem; + + --fs-h4:1.5rem; + --fs-h4-medium:1.5rem; + --fs-h4-small:1.375rem; + + --lh-h4:2rem; + --lh-h4-medium:1.75rem; + --lh-h4-small:1.75rem; + + --fs-h5:1.375rem; + --fs-h5-medium:1.25rem; + --fs-h5-small:1.125rem; + + --lh-h5:1.75rem; + --lh-h5-medium:1.5rem; + --lh-h5-small:1.375rem; + + --fs-h6:1.125rem; + --fs-h6-medium:1.125rem; + --fs-h6-small:1rem; + + --lh-h6:1.5rem; + --lh-h6-medium:1.375rem; + --lh-h6-small:1.25rem; + --outline-ring-width:2px; --outline-ring-inset: ; - --outline-ring-offset-width: 2px; - --outline-ring-offset-color: var(--outline-gray-100); - --outline-ring-color: var(--outline-soft-black); - --outline-ring-offset-shadow: var(--outline-ring-inset) 0 0 0 - var(--outline-ring-offset-width) var(--outline-ring-offset-color); - --outline-ring-shadow: var(--outline-ring-inset) 0 0 0 - calc(var(--outline-ring-width) + var(--outline-ring-offset-width)) - var(--outline-ring-color); + --outline-ring-offset-width:2px; + --outline-ring-offset-color:var(--outline-gray-100); + --outline-ring-color:var(--outline-soft-black); + --outline-ring-offset-shadow:var(--outline-ring-inset) 0 0 0 var(--outline-ring-offset-width) var(--outline-ring-offset-color); + --outline-ring-shadow:var(--outline-ring-inset) 0 0 0 calc(var(--outline-ring-width) + var(--outline-ring-offset-width)) var(--outline-ring-color); + + --outline-shadow:0 0 rgba(0, 0, 0, 0); + --outline-shadow-colored:0 0 rgba(0, 0, 0, 0); - --outline-shadow: 0 0 rgba(0, 0, 0, 0); - --outline-shadow-colored: 0 0 rgba(0, 0, 0, 0); } /* ! tailwindcss v3.0.0 | MIT License | https://tailwindcss.com */ *, ::before, -::after { - box-sizing: border-box; - border-width: 0; - border-style: solid; - border-color: currentColor; +::after{ + box-sizing:border-box; + border-width:0; + border-style:solid; + border-color:currentColor; } ::before, -::after { - --tw-content: ''; -} -html { - line-height: 1.5; - -webkit-text-size-adjust: 100%; - tab-size: 4; - font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, - 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, - 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; -} -body { - margin: 0; - line-height: inherit; -} -hr { - height: 0; - color: inherit; - border-top-width: 1px; -} -abbr[title] { - -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; +::after{ + --tw-content:''; +} +html{ + line-height:1.5; + -webkit-text-size-adjust:100%; + tab-size:4; + font-family:ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; +} +body{ + margin:0; + line-height:inherit; +} +hr{ + height:0; + color:inherit; + border-top-width:1px; +} +abbr[title]{ + -webkit-text-decoration:underline dotted; + text-decoration:underline dotted; } h1, h2, h3, h4, h5, -h6 { - font-size: inherit; - font-weight: inherit; +h6{ + font-size:inherit; + font-weight:inherit; } -a { - color: inherit; - text-decoration: inherit; +a{ + color:inherit; + text-decoration:inherit; } b, -strong { - font-weight: bolder; +strong{ + font-weight:bolder; } code, kbd, samp, -pre { - font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, - 'Liberation Mono', 'Courier New', monospace; - font-size: 1em; +pre{ + font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + font-size:1em; } -small { - font-size: 80%; +small{ + font-size:80%; } sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; +sup{ + font-size:75%; + line-height:0; + position:relative; + vertical-align:baseline; } -sub { - bottom: -0.25em; +sub{ + bottom:-0.25em; } -sup { - top: -0.5em; +sup{ + top:-0.5em; } -table { - text-indent: 0; - border-color: inherit; - border-collapse: collapse; +table{ + text-indent:0; + border-color:inherit; + border-collapse:collapse; } button, input, optgroup, select, -textarea { - font-family: inherit; - font-size: 100%; - line-height: inherit; - color: inherit; - margin: 0; - padding: 0; +textarea{ + font-family:inherit; + font-size:100%; + line-height:inherit; + color:inherit; + margin:0; + padding:0; } button, -select { - text-transform: none; +select{ + text-transform:none; } button, [type='button'], [type='reset'], -[type='submit'] { - -webkit-appearance: button; - background-color: transparent; - background-image: none; +[type='submit']{ + -webkit-appearance:button; + background-color:transparent; + background-image:none; } -:-moz-focusring { - outline: auto; +:-moz-focusring{ + outline:auto; } -:-moz-ui-invalid { - box-shadow: none; +:-moz-ui-invalid{ + box-shadow:none; } -progress { - vertical-align: baseline; +progress{ + vertical-align:baseline; } ::-webkit-inner-spin-button, -::-webkit-outer-spin-button { - height: auto; +::-webkit-outer-spin-button{ + height:auto; } -[type='search'] { - -webkit-appearance: textfield; - outline-offset: -2px; +[type='search']{ + -webkit-appearance:textfield; + outline-offset:-2px; } -::-webkit-search-decoration { - -webkit-appearance: none; +::-webkit-search-decoration{ + -webkit-appearance:none; } -::-webkit-file-upload-button { - -webkit-appearance: button; - font: inherit; +::-webkit-file-upload-button{ + -webkit-appearance:button; + font:inherit; } -summary { - display: list-item; +summary{ + display:list-item; } blockquote, dl, @@ -393,37 +389,37 @@ h6, hr, figure, p, -pre { - margin: 0; +pre{ + margin:0; } -fieldset { - margin: 0; - padding: 0; +fieldset{ + margin:0; + padding:0; } -legend { - padding: 0; +legend{ + padding:0; } ol, ul, -menu { - list-style: none; - margin: 0; - padding: 0; +menu{ + list-style:none; + margin:0; + padding:0; } -textarea { - resize: vertical; +textarea{ + resize:vertical; } input::placeholder, -textarea::placeholder { - opacity: 1; - color: #9ca3af; +textarea::placeholder{ + opacity:1; + color:#9ca3af; } button, -[role='button'] { - cursor: pointer; +[role="button"]{ + cursor:pointer; } -:disabled { - cursor: default; +:disabled{ + cursor:default; } img, svg, @@ -432,15 +428,15 @@ canvas, audio, iframe, embed, -object { - display: block; - vertical-align: middle; +object{ + display:block; + vertical-align:middle; } img, -video { - max-width: 100%; - height: auto; +video{ + max-width:100%; + height:auto; } -[hidden] { - display: none; +[hidden]{ + display:none; } diff --git a/packages/documentation/outline-storybook/stories/components/outline-heading.stories.ts b/packages/documentation/outline-storybook/stories/components/outline-heading.stories.ts index c8fb8cc9c..670072a29 100644 --- a/packages/documentation/outline-storybook/stories/components/outline-heading.stories.ts +++ b/packages/documentation/outline-storybook/stories/components/outline-heading.stories.ts @@ -6,10 +6,10 @@ import { argTypeSlotContent } from '@phase2/outline-core'; import { AllowedHeadingLevels, HeadingSizes, - HeadingStyles, -} from '@phase2/outline-heading'; + HeadingWeights, +} from '@phase2/outline-core-heading'; -import '@phase2/outline-heading'; +import '@phase2/outline-core-heading'; import '@phase2/outline-container'; const levelOptions: AllowedHeadingLevels[] = [ @@ -23,19 +23,20 @@ const levelOptions: AllowedHeadingLevels[] = [ export default { title: 'Content/Heading', - component: 'outline-heading', + component: 'outline-core-heading', // Tags are a new feature coming in 7.1, that we are using to drive this behaviour. tags: ['docsPage'], argTypes: { level: { - description: 'HTML level. Used by screen readers.', + description: + 'level property. Using this property means your heading will be in the shadowDOM which IS NOT RECOMMENDED.', options: levelOptions, control: { type: 'select', }, - table: { category: 'Properties', defaultValue: { summary: 'h2' } }, + table: { category: 'Properties', defaultValue: { summary: 'NULL' } }, }, - levelSize: { + size: { description: 'Presentation level. Used for styling.', options: HeadingSizes, control: { @@ -43,9 +44,9 @@ export default { }, table: { category: 'Properties', defaultValue: { summary: 'NULL' } }, }, - levelStyle: { + weight: { description: 'Presentation style. Font weight variation.', - options: HeadingStyles, + options: HeadingWeights, control: { type: 'select', }, @@ -61,108 +62,96 @@ export default { docs: { description: { component: ` -This component renders a heading. - -## Difference from \`h1\`, \`h2\`, etc elements - -This is rendered as various \`h1\`, etc elements, but is styled based on the \`level-size\`. This allows screen readers to properly read the structure of a page even when this diverges from the visual presentation of these headers. - -## Variation - -You can also set the font weight using the \`level-style\` attribute. - - `, - }, - source: { - code: ` - - {{ defaultSlot} - +This component renders styles for a heading as the default. You will need to hard define the appropriate tag within your slot that wraps your content. This component is intended to have the tag and the content within rendered to the light DOM. If you MUST use shadowDOM you can define the level prop but you must also remove the tag from your slot content. This is not recommended. `, }, }, }, }; -const Template = ({ - level, - levelSize, - levelStyle, - defaultSlot, -}: any): TemplateResult => +const Template = ({ level, size, weight, defaultSlot }: any): TemplateResult => html` - - ${defaultSlot} - + ${level ? defaultSlot : html`

${defaultSlot}

`} + +
`; export const Heading: any = Template.bind({}); Heading.args = { - level: 'h1', - levelSize: '3xl', - levelStyle: 'semibold', + level: null, + size: 'xxxl', + weight: 'semibold', }; -const StandardHeadingsTemplate = (): TemplateResult => { +const SlottedHeadingsWithAttributesTemplate = (): TemplateResult => { return html` -This is a standard Heading 1. -This is a standard Heading 2. -This is a standard Heading 3. -This is a standard Heading 4. -This is a standard Heading 5. -This is a standard Heading 6. +

This is a standard Heading 1.

+

This is a standard Heading 2.

+

This is a standard Heading 3.

+

This is a standard Heading 4.

+
This is a standard Heading 5.
+
This is a standard Heading 6.
`; }; -export const StandardHeadings = () => StandardHeadingsTemplate(); -StandardHeadings.parameters = { +export const SlottedHeadingsWithAttributes = () => + SlottedHeadingsWithAttributesTemplate(); +SlottedHeadingsWithAttributes.parameters = { docs: { description: { - story: `This example shows the standard heading elements. - This uses only the \`level\` attribute to declare the semantic level of the heading element. - This also allows us to show the default shift of sizes between smaller and larger breakpoints. + story: `This example shows the recommended way of creating headings using slots. The size and weight attributes are optional and can be customized for each heading. `, }, - source: { - code: ` -This is a standard Heading 1 element. -This is a standard Heading 2 element. -This is a standard Heading 3 element. -This is a standard Heading 4 element. -This is a standard Heading 5 element. -This is a standard Heading 6 element. -`, - }, }, }; -const DefaultHeadingTemplate = (): TemplateResult => { +const SlottedHeadingsWithNoAttributesTemplate = (): TemplateResult => { return html` -Sample heading text that should take up multiple lines so we can test for proper size and leading. +

This is a standard Heading 1.

+

This is a standard Heading 2.

+

This is a standard Heading 3.

+

This is a standard Heading 4.

+
This is a standard Heading 5.
+
This is a standard Heading 6.
`; }; -export const DefaultHeading: any = DefaultHeadingTemplate.bind({}); -DefaultHeading.args = {}; -DefaultHeading.parameters = { + +export const SlottedHeadingsWithNoAttributes = () => + SlottedHeadingsWithNoAttributesTemplate(); +SlottedHeadingsWithNoAttributes.parameters = { docs: { description: { - story: `This example shows an outline-heading element with no attributes being rendered. + story: `This example shows the recommended way of creating headings using slots but with no attributes for styling. `, }, - source: { - code: ` -Sample heading text that should take up multiple lines so we can test for proper size and leading. -`, + }, +}; + +const ShadowDomHeadingsWithAttributesTemplate = (): TemplateResult => { + return html` +This is a standard Heading 1. +This is a standard Heading 2. +This is a standard Heading 3. +This is a standard Heading 4. +This is a standard Heading 5. +This is a standard Heading 6. +`; +}; + +export const ShadowDomHeadingsWithAttributes = () => +ShadowDomHeadingsWithAttributesTemplate(); +ShadowDomHeadingsWithAttributes.parameters = { + docs: { + description: { + story: `This example shows how to use ShadowDOM if you must. Not recommended. + `, }, }, }; diff --git a/packages/outline-templates/default/src/components/sample/outline-extended-button/index.ts b/packages/outline-templates/default/src/components/sample/outline-extended-button/index.ts new file mode 100644 index 000000000..34a370776 --- /dev/null +++ b/packages/outline-templates/default/src/components/sample/outline-extended-button/index.ts @@ -0,0 +1 @@ +export { OutlineExtendedButton } from './outline-extended-button'; diff --git a/packages/outline-templates/default/src/components/sample/outline-extended-button/outline-extended-button.css b/packages/outline-templates/default/src/components/sample/outline-extended-button/outline-extended-button.css new file mode 100644 index 000000000..74fd37e69 --- /dev/null +++ b/packages/outline-templates/default/src/components/sample/outline-extended-button/outline-extended-button.css @@ -0,0 +1,3 @@ +.shiny { + border: 10px solid red; +} diff --git a/packages/outline-templates/default/src/components/sample/outline-extended-button/outline-extended-button.ts b/packages/outline-templates/default/src/components/sample/outline-extended-button/outline-extended-button.ts new file mode 100644 index 000000000..707e0bf8b --- /dev/null +++ b/packages/outline-templates/default/src/components/sample/outline-extended-button/outline-extended-button.ts @@ -0,0 +1,14 @@ +import { OutlineCoreButton } from '@phase2/outline-core-button'; +import { customElement } from 'lit/decorators.js'; +import '@phase2/outline-core-button'; +// Import @phase2 version breaking Storybook +// import { buttonVariantsTypes } from "@phase2/outline-core-button/src/outline-core-button"; +import { buttonVariantsTypes } from '../outline-core-button/src/outline-core-button'; + +buttonVariantsTypes.push('shiny'); + +// Rewriting does not work +// const buttonVariantsTypes = ['shiny', 'dull', 'matte']; + +@customElement('outline-extended-button') +export class OutlineExtendedButton extends OutlineCoreButton {} diff --git a/packages/outline-templates/default/src/components/sample/outline-extended-button/package.json b/packages/outline-templates/default/src/components/sample/outline-extended-button/package.json new file mode 100644 index 000000000..4e96ca292 --- /dev/null +++ b/packages/outline-templates/default/src/components/sample/outline-extended-button/package.json @@ -0,0 +1,41 @@ +{ + "name": "@phase2/outline-extended-button", + "version": "0.0.1", + "description": "The Outline Components for the web button component", + "keywords": [ + "outline components", + "outline design", + "button" + ], + "main": "index.ts", + "types": "index.ts", + "typings": "index.d.ts", + "files": [ + "/dist/", + "/src/", + "!/dist/tsconfig.build.tsbuildinfo" + ], + "author": "Phase2 Technology", + "repository": { + "type": "git", + "url": "https://github.com/phase2/outline.git", + "directory": "packages/outline-core-button" + }, + "license": "BSD-3-Clause", + "scripts": { + "build": "node ../../scripts/build.js", + "package": "yarn publish" + }, + "dependencies": { + "@phase2/outline-core": "^0.1.10", + "@phase2/outline-link": "^0.1.4", + "lit": "^2.3.1", + "tslib": "^2.1.0" + }, + "publishConfig": { + "access": "public" + }, + "exports": { + ".": "./index.ts" + } +} diff --git a/packages/outline-templates/default/src/components/sample/outline-extended-button/tsconfig.build.json b/packages/outline-templates/default/src/components/sample/outline-extended-button/tsconfig.build.json new file mode 100644 index 000000000..5eac9d313 --- /dev/null +++ b/packages/outline-templates/default/src/components/sample/outline-extended-button/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "./dist" + }, + "include": ["index.ts", "src/**/*", "tests/**/*"], + "references": [{ "path": "../../outline-core/tsconfig.build.json" }] +} diff --git a/yarn.lock b/yarn.lock index 5f501a8af..7288a51b7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2859,6 +2859,18 @@ "@types/sinon-chai" "^3.2.3" chai-a11y-axe "^1.5.0" +"@phase2/outline-config@^0.0.10": + version "0.0.10" + resolved "https://registry.yarnpkg.com/@phase2/outline-config/-/outline-config-0.0.10.tgz#ddeee1a39bd2be507ce36fc9983d12cb3a8f7a03" + integrity sha512-pHykGIyBj6kmAcJ8CijQjmFANN6cAIdWLoZEOeF0rdo0alHuwsWVvOq9e5vKzDeaiIEU8rwRvF1QpLNtOf2kcA== + +"@phase2/outline-core@^0.1.9": + version "0.1.12" + resolved "https://registry.yarnpkg.com/@phase2/outline-core/-/outline-core-0.1.12.tgz#a76a369523359b87b8b23f7986d7a6e372e8c547" + integrity sha512-mWbBKAl3Z3v5ZQO/CIDXXlNQfwsG8QxG3cVY6MfJziBV5elLwS+26MECfXsh2rSov1S0sh0quq6jpvbVgSeGCg== + dependencies: + "@phase2/outline-config" "^0.0.10" + "@pkgjs/parseargs@^0.11.0": version "0.11.0" resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"