diff --git a/apps/docs/stories/Layout/Stack.stories.tsx b/apps/docs/stories/Layout/Stack.stories.tsx index 3b8797c..7f11b08 100644 --- a/apps/docs/stories/Layout/Stack.stories.tsx +++ b/apps/docs/stories/Layout/Stack.stories.tsx @@ -1,5 +1,6 @@ import type { Meta, StoryObj } from "@storybook/react"; import { Stack } from "@themeless-ui/react"; +import { SizeElement } from "../../utils"; const meta = { title: "Layout/Stack", @@ -10,11 +11,7 @@ const meta = { export default meta; type Story = StoryObj; -const children = [ -
1
, -
2
, -
3
, -]; +const children = [...Array(3).keys()].map((n) => ); export const Vertical: Story = { args: { diff --git a/apps/docs/stories/Typography/Blockquote.stories.tsx b/apps/docs/stories/Typography/Blockquote.stories.tsx index 670e3fc..fa5bdda 100644 --- a/apps/docs/stories/Typography/Blockquote.stories.tsx +++ b/apps/docs/stories/Typography/Blockquote.stories.tsx @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from "@storybook/react"; -import { Blockquote, Paragraph } from "@themeless-ui/react"; +import { Blockquote, Paragraph, Prose } from "@themeless-ui/react"; const meta = { title: "Typography/Blockquote", @@ -41,3 +41,15 @@ export const WithoutAuthor: Story = { children, }, }; + +export const UsingWithProse = { + render: () => ( + + {lipsum} +
+ {lipsum} +
+ {lipsum} +
+ ), +}; diff --git a/apps/docs/stories/Typography/Heading.stories.tsx b/apps/docs/stories/Typography/Heading.stories.tsx index 168bd57..cd87f69 100644 --- a/apps/docs/stories/Typography/Heading.stories.tsx +++ b/apps/docs/stories/Typography/Heading.stories.tsx @@ -1,5 +1,6 @@ import type { Meta, StoryObj } from "@storybook/react"; -import { Heading, Paragraph } from "@themeless-ui/react"; +import { Heading, Paragraph, Prose } from "@themeless-ui/react"; +import { ExampleStack } from "../../utils"; const meta = { title: "Typography/Heading", @@ -24,57 +25,51 @@ export const Default: Story = { export const Levels = { render: () => ( -
-
- Heading 1 - Heading 2 - Heading 3 - Heading 4 - Heading 5 - Heading 6 -
-
+ + Heading 1 + Heading 2 + Heading 3 + Heading 4 + Heading 5 + Heading 6 + ), }; export const LongContent = { render: () => ( -
-
- Heading 1 — {lipsum} - Heading 2 — {lipsum} - Heading 3 — {lipsum} - Heading 4 — {lipsum} - Heading 5 — {lipsum} - Heading 6 — {lipsum} -
-
+ + Heading 1 — {lipsum} + Heading 2 — {lipsum} + Heading 3 — {lipsum} + Heading 4 — {lipsum} + Heading 5 — {lipsum} + Heading 6 — {lipsum} + ), }; -export const UsingWithParagraphs = { +export const UsingWithProse = { render: () => ( -
-
- Heading 1 - {lipsumParagraph} - {lipsumParagraph} - Heading 2 - {lipsumParagraph} - {lipsumParagraph} - Heading 3 - {lipsumParagraph} - {lipsumParagraph} - Heading 4 - {lipsumParagraph} - {lipsumParagraph} - Heading 5 - {lipsumParagraph} - {lipsumParagraph} - Heading 6 - {lipsumParagraph} - {lipsumParagraph} -
-
+ + Heading 1 + {lipsumParagraph} + {lipsumParagraph} + Heading 2 + {lipsumParagraph} + {lipsumParagraph} + Heading 3 + {lipsumParagraph} + {lipsumParagraph} + Heading 4 + {lipsumParagraph} + {lipsumParagraph} + Heading 5 + {lipsumParagraph} + {lipsumParagraph} + Heading 6 + {lipsumParagraph} + {lipsumParagraph} + ), }; diff --git a/apps/docs/stories/Typography/List.stories.tsx b/apps/docs/stories/Typography/List.stories.tsx index 039592c..96ca3f5 100644 --- a/apps/docs/stories/Typography/List.stories.tsx +++ b/apps/docs/stories/Typography/List.stories.tsx @@ -1,5 +1,6 @@ import type { Meta, StoryObj } from "@storybook/react"; -import { List } from "@themeless-ui/react"; +import { Heading, List, Paragraph, Prose } from "@themeless-ui/react"; +import { ExampleGrid, ExampleItem } from "../../utils"; const meta = { title: "Typography/List", @@ -16,6 +17,9 @@ const children = [ Consectetur adipiscing elit, ]; +const lipsum = + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec accumsan ex vel lacinia volutpat. Ut ultricies, mauris et varius finibus, nulla ante efficitur libero, eget convallis odio ex ut neque. Praesent quis odio ac felis pretium pharetra sit amet quis neque. Nam nec libero purus. Maecenas sagittis lobortis lacinia. Aliquam non vehicula metus. Vivamus fringilla ante eget leo pretium cursus. Morbi venenatis diam metus, ut faucibus dolor mollis a. Nulla nec ex sapien. Curabitur a tempor est. Mauris faucibus congue mi, sit amet pulvinar justo porttitor nec. Nunc et eros a est fermentum lacinia id at nisi."; + export const UnorderedList: Story = { args: { type: "unordered", @@ -29,3 +33,158 @@ export const OrderedList: Story = { children, }, }; + +export const NestedLists: Story = { + render: () => { + const unordered = ( + + + First level + + + Second level + + + Third level + + Fourth level + Fourth level + + + + + + + + First level + + + Second level + + + Third level + + Fourth level + + + + + Second level + + + + ); + + const ordered = ( + + + First level + + + Second level + + + Third level + + Fourth level + Fourth level + + + + + + + + First level + + + Second level + + + Third level + + Fourth level + + + + + Second level + + + + ); + + const mixed = ( + + + First level + + + Second level + + + Third level + + Fourth level + Fourth level + + + + + + + + First level + + + Second level + + + Third level + + Fourth level + + + + + Second level + + + + ); + + return ( + + {unordered} + {ordered} + {mixed} + + {unordered} + + + {ordered} + + + {mixed} + + + ); + }, +}; + +export const UsingWithProse = { + render: () => ( + + Heading 1 + {lipsum} + {children} + {lipsum} + Heading 2 + {children} + Heading 3 + {children} + {lipsum} + {children} + + ), +}; diff --git a/apps/docs/stories/Typography/Paragraph.stories.tsx b/apps/docs/stories/Typography/Paragraph.stories.tsx index 628ba21..a72a044 100644 --- a/apps/docs/stories/Typography/Paragraph.stories.tsx +++ b/apps/docs/stories/Typography/Paragraph.stories.tsx @@ -1,5 +1,5 @@ import type { Meta, StoryObj } from "@storybook/react"; -import { Paragraph, Text } from "@themeless-ui/react"; +import { Paragraph, Prose, Text } from "@themeless-ui/react"; const meta = { title: "Typography/Paragraph", @@ -19,19 +19,23 @@ export const Default: Story = { }, }; -export const UsingWithText = { +export const UsingWithProse = { render: () => ( - <> + {lipsum} - - Lorem ipsum dolor sit amet - Donec accumsan ex vellacinia volutpat. Ut - tricies, mauris et{" "} - varius finibus,{" "} - nulla ante efficitur libero, eget convallis{" "} - odio ex ut neque. - {lipsum} - + + ), +}; + +export const UsingWithText = { + render: () => ( + + Lorem ipsum dolor sit amet + Donec accumsan ex vellacinia volutpat. Ut tricies,{" "} + mauris et varius{" "} + finibus, nulla ante efficitur libero, eget + convallis odio ex ut neque. + ), }; diff --git a/apps/docs/stories/Typography/Prose.stories.tsx b/apps/docs/stories/Typography/Prose.stories.tsx new file mode 100644 index 0000000..b37b5ce --- /dev/null +++ b/apps/docs/stories/Typography/Prose.stories.tsx @@ -0,0 +1,52 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { + Blockquote, + Heading, + List, + Paragraph, + Prose, +} from "@themeless-ui/react"; + +const meta = { + title: "Typography/Prose", + component: Prose, + tags: ["autodocs"], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +const lipsum = + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec accumsan ex vel lacinia volutpat. Ut ultricies, mauris et varius finibus, nulla ante efficitur libero, eget convallis odio ex ut neque. Praesent quis odio ac felis pretium pharetra sit amet quis neque. Nam nec libero purus. Maecenas sagittis lobortis lacinia. Aliquam non vehicula metus. Vivamus fringilla ante eget leo pretium cursus. Morbi venenatis diam metus, ut faucibus dolor mollis a. Nulla nec ex sapien. Curabitur a tempor est. Mauris faucibus congue mi, sit amet pulvinar justo porttitor nec. Nunc et eros a est fermentum lacinia id at nisi."; +const cite = "https://source-of-the-quote.example.com"; +const author = "Samuel L. Ipsum"; +const source = "Lorem Ipsum"; + +export const Default: Story = { + args: { + children: [ + + Heading 1 + , + {lipsum}, + {lipsum}, + + Heading 2 + , + + Lorem ipsum + Dolor sit amet + Consectetur adipiscing elit + , + {lipsum}, + + Heading 3 + , + {lipsum}, +
+ {lipsum} +
, + {lipsum}, + ], + }, +}; diff --git a/apps/docs/stories/Typography/Text.stories.tsx b/apps/docs/stories/Typography/Text.stories.tsx index e3b6213..5e0ce77 100644 --- a/apps/docs/stories/Typography/Text.stories.tsx +++ b/apps/docs/stories/Typography/Text.stories.tsx @@ -1,6 +1,6 @@ import type { Meta, StoryObj } from "@storybook/react"; import { Text } from "@themeless-ui/react"; -import { ReactNode } from "react"; +import { ExampleGrid, ExampleTitle } from "../../utils"; const meta = { title: "Typography/Text", @@ -17,170 +17,112 @@ export const Default: Story = { }, }; -const Description = ({ children }: { children: ReactNode }) => ( - - {children}:{" "} - -); - export const TextTypes = { render: () => ( -
    -
  • - abbr - Abbreviation -
  • -
  • - abbr with title - - Abbreviation - -
  • -
  • - b - Bring attention to -
  • -
  • - cite - Citation -
  • -
  • - code - Inline code -
  • -
  • - del - Deleted text -
  • -
  • - del with cite - - Deleted text - -
  • -
  • - em - Emphasis -
  • -
  • - i - Idiomatic text -
  • -
  • - ins - Inserted text -
  • -
  • - ins with cite - - Inserted text - -
  • -
  • - kbd - Keyboard input -
  • -
  • - mark - Mark text -
  • -
  • - q - Inline quotation -
  • -
  • - q with cite - - Inline quotation - -
  • -
  • - s - Strikethrough -
  • -
  • - samp - Sample output -
  • -
  • - small - Side comment -
  • -
  • - span - Content span -
  • -
  • - strong - Strong importance -
  • -
  • - sub - Subscript -
  • -
  • - sup - Superscript -
  • -
  • - u - Unarticulated annotation -
  • -
  • - var - Variable -
  • -
+ + abbr + Abbreviation + abbr with title + + Abbreviation + + b + Bring attention to + cite + Citation + code + Inline code + del + Deleted text + del with cite + + Deleted text + + em + Emphasis + i + Idiomatic text + ins + Inserted text + ins with cite + + Inserted text + + kbd + Keyboard input + mark + Mark text + q + Inline quotation + q with cite + + Inline quotation + + s + Strikethrough + samp + Sample output + small + Side comment + span + Content span + strong + Strong importance + sub + Subscript + sup + Superscript + u + Unarticulated annotation + var + Variable + ), }; export const CombiningTextTypes = { render: () => ( -
    -
  • - strong in mark - - Lorem ipsum dolor sit amet, consectetur - adipiscing elit. - -
  • -
  • - del and ins in cite - - Lorem ipsum{" "} - - dolor - sit amet - - , consectetur adipiscing elit. + + code in span + + sans-serif monospace sans-serif + + strong in mark + + Lorem ipsum dolor sit amet, consectetur + adipiscing elit. + + del and ins in cite + + Lorem ipsum{" "} + + dolor + sit amet -
  • -
  • - var in code - - let foo = "bar"; + , consectetur adipiscing elit. + + var in code + + let foo = "bar"; + + samp in kbd + + + File -
  • -
  • - samp in kbd + ⇒ - - File - - ⇒ - - New Document - + New Document -
  • -
+ + ), }; diff --git a/apps/nextjs-example/app/about/page.tsx b/apps/nextjs-example/app/about/page.tsx index 6c6d818..0f1bc85 100644 --- a/apps/nextjs-example/app/about/page.tsx +++ b/apps/nextjs-example/app/about/page.tsx @@ -1,9 +1,9 @@ -import { Heading, Paragraph, Stack } from "@themeless-ui/react"; +import { Heading, Paragraph, Prose } from "@themeless-ui/react"; export default async function About() { return (
- + About Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis pulvinar @@ -14,7 +14,7 @@ export default async function About() { taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. - +
); } diff --git a/apps/nextjs-example/app/posts/[slug]/page.tsx b/apps/nextjs-example/app/posts/[slug]/page.tsx index d8ae8f4..525aadc 100644 --- a/apps/nextjs-example/app/posts/[slug]/page.tsx +++ b/apps/nextjs-example/app/posts/[slug]/page.tsx @@ -1,5 +1,5 @@ import { mdxComponents } from "@/utils/mdx"; -import { Heading, Stack } from "@themeless-ui/react"; +import { Heading, Prose, Stack } from "@themeless-ui/react"; import { allPosts } from "contentlayer/generated"; import { format, parseISO } from "date-fns"; import { getMDXComponent } from "next-contentlayer/hooks"; @@ -35,7 +35,9 @@ export default async function Post({ params }: { params: { slug: string } }) { - + + + ); diff --git a/apps/react-example/src/examples/Typography/TypographyExample.tsx b/apps/react-example/src/examples/Typography/TypographyExample.tsx index 274f6b0..7277416 100644 --- a/apps/react-example/src/examples/Typography/TypographyExample.tsx +++ b/apps/react-example/src/examples/Typography/TypographyExample.tsx @@ -3,6 +3,7 @@ import { Heading, List, Paragraph, + Prose, Stack, Text, } from "@themeless-ui/react"; @@ -10,178 +11,182 @@ import { export function TypographyExample() { return (
- - - Lorem ipsum dolor sit amet, consectetur adipiscing elit - - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam - lacinia cursus ex, in lacinia est.{" "} - Vivamus rhoncus mollis felis nec efficitur. - Maecenas id malesuada quam. Suspendisse aliquam urna sed posuere - malesuada. Ut viverra ipsum eget ipsum eleifend dignissim. Nullam - vitae nunc quam. Ut aliquam pharetra nunc, eget posuere nisi viverra - sed. Vivamus nec nibh at est ultrices laoreet volutpat ut sapien. Sed - scelerisque augue nec ex interdum, in tincidunt nunc imperdiet. Sed - lacinia vulputate sem eu pharetra. Ut faucibus dui urna, ac maximus - eros finibus eget. Cras imperdiet odio non erat egestas sagittis. - Donec eget odio turpis. Curabitur dictum libero in velit ultrices - sollicitudin. Mauris semper vulputate consectetur. - - - Suspendisse accumsan rhoncus neque. Maecenas molestie sollicitudin - semper. Nullam pulvinar sollicitudin justo. Sed sollicitudin lorem at - est rutrum, a suscipit lorem venenatis.{" "} - - In volutpat, ex eget tempus auctor, lorem turpis finibus dui, et - ultrices urna orci eget lorem. Suspendisse mauris tellus, mattis id - feugiat vel, imperdiet quis massa. Integer non lacus est. - {" "} - Suspendisse nunc augue, tristique at enim vel, sollicitudin maximus - ante. Quisque rutrum tempor velit non varius. Suspendisse ornare - mauris at mi vulputate fringilla. - - Cras ut ipsum ut erat semper gravida - - Cras ut ipsum ut erat semper gravida. Nam suscipit varius tincidunt. - Vestibulum vulputate sed dolor nec laoreet. Cras enim nulla, bibendum - eu placerat non, consequat at erat. Nam eleifend maximus faucibus. - Praesent sagittis sem non urna consectetur, non fringilla mi posuere. - Sed non mi tortor.{" "} - Cras efficitur blandit rhoncus. Cras - ullamcorper non diam nec sagittis. Nunc eget lorem eu ex rutrum - molestie sed vitae augue. Maecenas in risus libero. Fusce sapien - lacus, tristique eget justo sed, auctor fringilla metus. Mauris augue - nunc, lobortis in lectus vel, faucibus posuere velit. - -
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec - accumsan ex vel lacinia volutpat. Ut ultricies, mauris et varius - finibus, nulla ante efficitur libero, eget convallis odio ex ut neque. - Praesent quis odio ac felis pretium pharetra sit amet quis neque. Nam - nec libero purus. Maecenas sagittis lobortis lacinia. Aliquam non - vehicula metus. Vivamus fringilla ante eget leo pretium cursus. Morbi - venenatis diam metus, ut faucibus dolor mollis a. Nulla nec ex sapien. - Curabitur a tempor est. Mauris faucibus congue mi, sit amet pulvinar - justo porttitor nec. Nunc et eros a est fermentum lacinia id at nisi. -
- - Etiam porta purus a aliquam rutrum. Vivamus finibus sed metus et - vestibulum. Ut ornare eget mi nec congue. Nunc et dui sed diam viverra - porta. Phasellus gravida massa lorem, et ultrices tellus scelerisque - eget. Cras congue congue pulvinar. Aliquam aliquet dolor est, eget - lobortis tortor efficitur ut. Nam accumsan, nisl quis pretium - imperdiet, leo nulla efficitur lectus, eget vestibulum diam lorem id - ante. Cras sit amet cursus purus, eget bibendum arcu. - - Cras sit amet cursus purus - Sed sodales eros - - Sed sodales eros ut arcu tincidunt, et condimentum lacus ultricies. - Quisque rhoncus, nulla et vulputate vestibulum, ligula dolor tristique - massa, sollicitudin fermentum eros magna nec est. Nulla facilisi. - Quisque efficitur turpis sit amet ornare euismod. Pellentesque in - neque vitae risus posuere condimentum at in ex. Morbi consequat erat - at risus laoreet rhoncus. Suspendisse pharetra bibendum ante eu - gravida. Pellentesque interdum eget tortor sed venenatis. Suspendisse - mollis turpis non justo sollicitudin convallis. Ut quis eros lacus. - Cras aliquam non ex ultrices sollicitudin. Suspendisse efficitur id - lorem ut gravida. Morbi laoreet nec magna molestie eleifend. Proin - ligula risus, tristique et nunc et, sagittis aliquet lacus. Duis - sollicitudin elit vitae nisl rhoncus pretium. Donec at auctor neque. - - - Nunc imperdiet, dui et molestie congue, odio velit imperdiet lacus, at - aliquet nulla urna sit amet orci. Praesent sed dolor luctus, ornare - metus id, iaculis ante. Integer non suscipit nunc, eu cursus risus. - Nulla vel iaculis est, et viverra metus. Mauris venenatis sodales - lacus ultricies scelerisque. Praesent lobortis felis purus, non - vulputate leo sollicitudin vitae. In a felis non nunc congue volutpat - ut sed orci. Duis volutpat tristique neque ac sodales. Duis faucibus - maximus lectus, a aliquam nisi pharetra nec. Sed risus tortor, - sollicitudin sed malesuada a, imperdiet vitae nisi. Curabitur ut - hendrerit ex. Pellentesque habitant morbi tristique senectus et netus - et malesuada fames ac turpis egestas. Nam tellus nisi, tincidunt vitae - justo ac, scelerisque feugiat dolor. Proin vitae erat pretium, luctus - lorem eu, imperdiet augue. - - Vivamus lacinia semper dolor - - Vivamus lacinia semper dolor, et vehicula velit condimentum sed. Proin - consequat tellus ac arcu tincidunt aliquet. Ut bibendum sodales justo, - in malesuada nulla semper non. Morbi lectus diam, tincidunt varius - magna id, congue semper ipsum. Vestibulum nisi eros, aliquet mollis - scelerisque ac, aliquam non magna. Suspendisse nec mi cursus, - fermentum velit nec, sollicitudin enim. Maecenas elementum in velit - vitae viverra. Etiam ut consequat lorem, eget posuere dui. Sed enim - massa, ornare ac ipsum venenatis, convallis luctus arcu. Ut vel - consectetur arcu. - - - Lorem ipsum - Dolor sit amet - Consectetur adipiscing elit - - - Suspendisse convallis mi sed metus consectetur euismod. Proin vel - libero nisi. Curabitur nec nunc eget mauris tempus consectetur. Sed et - elit at enim luctus imperdiet sollicitudin eu diam. Proin vitae nisi - ornare, ullamcorper felis sit amet, placerat leo. Integer sapien - mauris, cursus fringilla erat quis, commodo pharetra nulla. Vivamus - sit amet hendrerit dui, eu egestas dolor. Donec interdum convallis - velit ut pellentesque. Quisque eu ultrices nisi. Integer eleifend ante - ut scelerisque porta. Aenean accumsan eget velit vestibulum iaculis. - Praesent elementum fermentum massa vitae sollicitudin. Sed eget - maximus leo, ac aliquam quam. - - Integer maximus sapien - - Integer maximus sapien a libero venenatis, id vulputate leo molestie. - Suspendisse pellentesque, turpis vel vehicula varius, quam purus - dapibus orci, at molestie tortor massa ut purus. Maecenas sit amet - vulputate ex. Suspendisse nec nibh vitae erat rhoncus semper feugiat - et diam. Suspendisse potenti. Cras neque tortor, consequat eu enim in, - suscipit dapibus quam. Quisque eget pulvinar dolor. Etiam porta - tincidunt velit, in laoreet elit tincidunt a. Nulla volutpat eleifend - dictum. - - - Nulla scelerisque nulla leo, et lacinia est feugiat eu. Morbi - dignissim nulla lectus, in fermentum felis ullamcorper nec. Proin at - ligula eros. Ut non erat gravida orci tempus fringilla vitae nec nisl. - In varius, dui scelerisque blandit malesuada, erat ante placerat - ipsum, eget malesuada neque leo vitae tortor. Praesent eleifend felis - velit, id egestas lorem blandit id. Nulla pulvinar nisi malesuada - mauris tempus, ac lobortis dolor sagittis. - - Cras fermentum porta - - Cras fermentum porta enim, at pellentesque diam egestas sit amet. Sed - sed auctor odio. Donec turpis purus, aliquam non nisi quis, mollis - tempor metus. Phasellus cursus nulla et ipsum vehicula, fringilla - aliquam nisi venenatis. Donec consequat venenatis nisl at egestas. - Proin scelerisque sagittis turpis. Curabitur gravida, purus non congue - condimentum, urna mauris fringilla ante, sed finibus ante tellus vitae - lectus. Pellentesque in imperdiet ligula. - - - Etiam rutrum mi sit amet pulvinar suscipit. Praesent quis enim ac orci - elementum tempor congue sodales erat. Suspendisse potenti. Proin et - feugiat quam. Mauris vel laoreet lectus, sit amet bibendum dolor. - Fusce ut odio semper, tincidunt tortor et, imperdiet velit. Donec - lacinia diam a enim porttitor, sit amet blandit nisl congue. Praesent - cursus lorem eget vehicula auctor. Praesent tincidunt interdum - elementum. Vestibulum vel accumsan lacus. Integer eget volutpat nibh, - nec ornare nulla. Duis id velit pulvinar, finibus nunc eget, - ullamcorper libero. Vivamus leo ex, interdum in auctor non, tempor - vehicula dui. Vestibulum sed efficitur eros. Donec lacinia ultrices - eros vel mattis. - -
+ + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam + lacinia cursus ex, in lacinia est.{" "} + Vivamus rhoncus mollis felis nec + efficitur. Maecenas id malesuada quam. Suspendisse aliquam urna sed + posuere malesuada. Ut viverra ipsum eget ipsum eleifend dignissim. + Nullam vitae nunc quam. Ut aliquam pharetra nunc, eget posuere nisi + viverra sed. Vivamus nec nibh at est ultrices laoreet volutpat ut + sapien. Sed scelerisque augue nec ex interdum, in tincidunt nunc + imperdiet. Sed lacinia vulputate sem eu pharetra. Ut faucibus dui + urna, ac maximus eros finibus eget. Cras imperdiet odio non erat + egestas sagittis. Donec eget odio turpis. Curabitur dictum libero in + velit ultrices sollicitudin. Mauris semper vulputate consectetur. + + + Suspendisse accumsan rhoncus neque. Maecenas molestie sollicitudin + semper. Nullam pulvinar sollicitudin justo. Sed sollicitudin lorem + at est rutrum, a suscipit lorem venenatis.{" "} + + In volutpat, ex eget tempus auctor, lorem turpis finibus dui, et + ultrices urna orci eget lorem. Suspendisse mauris tellus, mattis + id feugiat vel, imperdiet quis massa. Integer non lacus est. + {" "} + Suspendisse nunc augue, tristique at enim vel, sollicitudin maximus + ante. Quisque rutrum tempor velit non varius. Suspendisse ornare + mauris at mi vulputate fringilla. + + Cras ut ipsum ut erat semper gravida + + Cras ut ipsum ut erat semper gravida. Nam suscipit varius tincidunt. + Vestibulum vulputate sed dolor nec laoreet. Cras enim nulla, + bibendum eu placerat non, consequat at erat. Nam eleifend maximus + faucibus. Praesent sagittis sem non urna consectetur, non fringilla + mi posuere. Sed non mi tortor.{" "} + Cras efficitur blandit rhoncus. Cras + ullamcorper non diam nec sagittis. Nunc eget lorem eu ex rutrum + molestie sed vitae augue. Maecenas in risus libero. Fusce sapien + lacus, tristique eget justo sed, auctor fringilla metus. Mauris + augue nunc, lobortis in lectus vel, faucibus posuere velit. + +
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec + accumsan ex vel lacinia volutpat. Ut ultricies, mauris et varius + finibus, nulla ante efficitur libero, eget convallis odio ex ut + neque. Praesent quis odio ac felis pretium pharetra sit amet quis + neque. Nam nec libero purus. Maecenas sagittis lobortis lacinia. + Aliquam non vehicula metus. Vivamus fringilla ante eget leo pretium + cursus. Morbi venenatis diam metus, ut faucibus dolor mollis a. + Nulla nec ex sapien. Curabitur a tempor est. Mauris faucibus congue + mi, sit amet pulvinar justo porttitor nec. Nunc et eros a est + fermentum lacinia id at nisi. +
+ + Etiam porta purus a aliquam rutrum. Vivamus finibus sed metus et + vestibulum. Ut ornare eget mi nec congue. Nunc et dui sed diam + viverra porta. Phasellus gravida massa lorem, et ultrices tellus + scelerisque eget. Cras congue congue pulvinar. Aliquam aliquet dolor + est, eget lobortis tortor efficitur ut. Nam accumsan, nisl quis + pretium imperdiet, leo nulla efficitur lectus, eget vestibulum diam + lorem id ante. Cras sit amet cursus purus, eget bibendum arcu. + + Cras sit amet cursus purus + Sed sodales eros + + Sed sodales eros ut arcu tincidunt, et condimentum lacus ultricies. + Quisque rhoncus, nulla et vulputate vestibulum, ligula dolor + tristique massa, sollicitudin fermentum eros magna nec est. Nulla + facilisi. Quisque efficitur turpis sit amet ornare euismod. + Pellentesque in neque vitae risus posuere condimentum at in ex. + Morbi consequat erat at risus laoreet rhoncus. Suspendisse pharetra + bibendum ante eu gravida. Pellentesque interdum eget tortor sed + venenatis. Suspendisse mollis turpis non justo sollicitudin + convallis. Ut quis eros lacus. Cras aliquam non ex ultrices + sollicitudin. Suspendisse efficitur id lorem ut gravida. Morbi + laoreet nec magna molestie eleifend. Proin ligula risus, tristique + et nunc et, sagittis aliquet lacus. Duis sollicitudin elit vitae + nisl rhoncus pretium. Donec at auctor neque. + + + Nunc imperdiet, dui et molestie congue, odio velit imperdiet lacus, + at aliquet nulla urna sit amet orci. Praesent sed dolor luctus, + ornare metus id, iaculis ante. Integer non suscipit nunc, eu cursus + risus. Nulla vel iaculis est, et viverra metus. Mauris venenatis + sodales lacus ultricies scelerisque. Praesent lobortis felis purus, + non vulputate leo sollicitudin vitae. In a felis non nunc congue + volutpat ut sed orci. Duis volutpat tristique neque ac sodales. Duis + faucibus maximus lectus, a aliquam nisi pharetra nec. Sed risus + tortor, sollicitudin sed malesuada a, imperdiet vitae nisi. + Curabitur ut hendrerit ex. Pellentesque habitant morbi tristique + senectus et netus et malesuada fames ac turpis egestas. Nam tellus + nisi, tincidunt vitae justo ac, scelerisque feugiat dolor. Proin + vitae erat pretium, luctus lorem eu, imperdiet augue. + + Vivamus lacinia semper dolor + + Vivamus lacinia semper dolor, et vehicula velit condimentum sed. + Proin consequat tellus ac arcu tincidunt aliquet. Ut bibendum + sodales justo, in malesuada nulla semper non. Morbi lectus diam, + tincidunt varius magna id, congue semper ipsum. Vestibulum nisi + eros, aliquet mollis scelerisque ac, aliquam non magna. Suspendisse + nec mi cursus, fermentum velit nec, sollicitudin enim. Maecenas + elementum in velit vitae viverra. Etiam ut consequat lorem, eget + posuere dui. Sed enim massa, ornare ac ipsum venenatis, convallis + luctus arcu. Ut vel consectetur arcu. + + + Lorem ipsum + Dolor sit amet + Consectetur adipiscing elit + + + Suspendisse convallis mi sed metus consectetur euismod. Proin vel + libero nisi. Curabitur nec nunc eget mauris tempus consectetur. Sed + et elit at enim luctus imperdiet sollicitudin eu diam. Proin vitae + nisi ornare, ullamcorper felis sit amet, placerat leo. Integer + sapien mauris, cursus fringilla erat quis, commodo pharetra nulla. + Vivamus sit amet hendrerit dui, eu egestas dolor. Donec interdum + convallis velit ut pellentesque. Quisque eu ultrices nisi. Integer + eleifend ante ut scelerisque porta. Aenean accumsan eget velit + vestibulum iaculis. Praesent elementum fermentum massa vitae + sollicitudin. Sed eget maximus leo, ac aliquam quam. + + Integer maximus sapien + + Integer maximus sapien a libero venenatis, id vulputate leo + molestie. Suspendisse pellentesque, turpis vel vehicula varius, quam + purus dapibus orci, at molestie tortor massa ut purus. Maecenas sit + amet vulputate ex. Suspendisse nec nibh vitae erat rhoncus semper + feugiat et diam. Suspendisse potenti. Cras neque tortor, consequat + eu enim in, suscipit dapibus quam. Quisque eget pulvinar dolor. + Etiam porta tincidunt velit, in laoreet elit tincidunt a. Nulla + volutpat eleifend dictum. + + + Nulla scelerisque nulla leo, et lacinia est feugiat eu. Morbi + dignissim nulla lectus, in fermentum felis ullamcorper nec. Proin at + ligula eros. Ut non erat gravida orci tempus fringilla vitae nec + nisl. In varius, dui scelerisque blandit malesuada, erat ante + placerat ipsum, eget malesuada neque leo vitae tortor. Praesent + eleifend felis velit, id egestas lorem blandit id. Nulla pulvinar + nisi malesuada mauris tempus, ac lobortis dolor sagittis. + + Cras fermentum porta + + Cras fermentum porta enim, at pellentesque diam egestas sit amet. + Sed sed auctor odio. Donec turpis purus, aliquam non nisi quis, + mollis tempor metus. Phasellus cursus nulla et ipsum vehicula, + fringilla aliquam nisi venenatis. Donec consequat venenatis nisl at + egestas. Proin scelerisque sagittis turpis. Curabitur gravida, purus + non congue condimentum, urna mauris fringilla ante, sed finibus ante + tellus vitae lectus. Pellentesque in imperdiet ligula. + + + Etiam rutrum mi sit amet pulvinar suscipit. Praesent quis enim ac + orci elementum tempor congue sodales erat. Suspendisse potenti. + Proin et feugiat quam. Mauris vel laoreet lectus, sit amet bibendum + dolor. Fusce ut odio semper, tincidunt tortor et, imperdiet velit. + Donec lacinia diam a enim porttitor, sit amet blandit nisl congue. + Praesent cursus lorem eget vehicula auctor. Praesent tincidunt + interdum elementum. Vestibulum vel accumsan lacus. Integer eget + volutpat nibh, nec ornare nulla. Duis id velit pulvinar, finibus + nunc eget, ullamcorper libero. Vivamus leo ex, interdum in auctor + non, tempor vehicula dui. Vestibulum sed efficitur eros. Donec + lacinia ultrices eros vel mattis. + +
+
); } diff --git a/apps/web-components-example/index.html b/apps/web-components-example/index.html index 3466322..5c68e0e 100644 --- a/apps/web-components-example/index.html +++ b/apps/web-components-example/index.html @@ -75,6 +75,14 @@ Paragraph + + Prose + + Paragraph + Paragraph + + + Stack diff --git a/packages/react/src/components/Prose/Prose.test.tsx b/packages/react/src/components/Prose/Prose.test.tsx new file mode 100644 index 0000000..34002eb --- /dev/null +++ b/packages/react/src/components/Prose/Prose.test.tsx @@ -0,0 +1,36 @@ +import { + componentToJson, + describe, + expect, + it, + render, + renderer, + screen, +} from "../../../test"; +import { Heading } from "../Heading"; +import { Paragraph } from "../Paragraph"; +import { Text } from "../Text"; +import { Prose } from "./Prose"; + +const lipsum = + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec accumsan ex vel lacinia volutpat. Ut ultricies, mauris et varius finibus, nulla ante efficitur libero, eget convallis odio ex ut neque. Praesent quis odio ac felis pretium pharetra sit amet quis neque. Nam nec libero purus. Maecenas sagittis lobortis lacinia. Aliquam non vehicula metus. Vivamus fringilla ante eget leo pretium cursus. Morbi venenatis diam metus, ut faucibus dolor mollis a. Nulla nec ex sapien. Curabitur a tempor est. Mauris faucibus congue mi, sit amet pulvinar justo porttitor nec. Nunc et eros a est fermentum lacinia id at nisi."; + +const defaultProse = ( + + Heading + {lipsum} + Text + +); + +describe("Prose", async () => { + it("should render the prose", () => { + expect(componentToJson(renderer.create(defaultProse))).toMatchSnapshot(); + + render(defaultProse); + + const prose = screen.getByTestId("prose"); + + expect(prose).toBeInTheDocument(); + }); +}); diff --git a/packages/react/src/components/Prose/Prose.tsx b/packages/react/src/components/Prose/Prose.tsx new file mode 100644 index 0000000..6e1899b --- /dev/null +++ b/packages/react/src/components/Prose/Prose.tsx @@ -0,0 +1,26 @@ +import { CommonComponentProps, cn } from "@themeless-ui/utils"; +import { ReactNode } from "react"; + +export type ProseProps = { + /** + * Prose content. + */ + children?: ReactNode; +} & CommonComponentProps; + +const className = cn("prose"); + +/** + * A wrapper component for text content. Adds default spacing for the following components: + * - `
` + * - `` + * - `` + * - `` + */ +export function Prose({ children, id, testId }: ProseProps) { + return ( +
+ {children} +
+ ); +} diff --git a/packages/react/src/components/Prose/__snapshots__/Prose.test.tsx.snap b/packages/react/src/components/Prose/__snapshots__/Prose.test.tsx.snap new file mode 100644 index 0000000..3bc58cc --- /dev/null +++ b/packages/react/src/components/Prose/__snapshots__/Prose.test.tsx.snap @@ -0,0 +1,24 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Prose > should render the prose 1`] = ` +
+

+ Heading +

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec accumsan ex vel lacinia volutpat. Ut ultricies, mauris et varius finibus, nulla ante efficitur libero, eget convallis odio ex ut neque. Praesent quis odio ac felis pretium pharetra sit amet quis neque. Nam nec libero purus. Maecenas sagittis lobortis lacinia. Aliquam non vehicula metus. Vivamus fringilla ante eget leo pretium cursus. Morbi venenatis diam metus, ut faucibus dolor mollis a. Nulla nec ex sapien. Curabitur a tempor est. Mauris faucibus congue mi, sit amet pulvinar justo porttitor nec. Nunc et eros a est fermentum lacinia id at nisi. +

+ + Text + +
+`; diff --git a/packages/react/src/components/Prose/index.ts b/packages/react/src/components/Prose/index.ts new file mode 100644 index 0000000..42e43b2 --- /dev/null +++ b/packages/react/src/components/Prose/index.ts @@ -0,0 +1,2 @@ +export { Prose } from "./Prose"; +export type { ProseProps } from "./Prose"; diff --git a/packages/react/src/components/index.ts b/packages/react/src/components/index.ts index 0c28f59..f43e4cf 100644 --- a/packages/react/src/components/index.ts +++ b/packages/react/src/components/index.ts @@ -5,6 +5,7 @@ export * from "./Heading"; export * from "./Input"; export * from "./List"; export * from "./Paragraph"; +export * from "./Prose"; export * from "./Stack"; export * from "./Text"; export * from "./Textarea"; diff --git a/packages/style/src/components.css b/packages/style/src/components.css index c97d1b7..b30ab6e 100644 --- a/packages/style/src/components.css +++ b/packages/style/src/components.css @@ -5,6 +5,7 @@ @import "./components/input.css"; @import "./components/list.css"; @import "./components/paragraph.css"; +@import "./components/prose.css"; @import "./components/stack.css"; @import "./components/text.css"; @import "./components/textarea.css"; diff --git a/packages/style/src/components/blockquote.css b/packages/style/src/components/blockquote.css index 107828f..84ece8b 100644 --- a/packages/style/src/components/blockquote.css +++ b/packages/style/src/components/blockquote.css @@ -1,7 +1,7 @@ .tui__blockquote { display: block; box-sizing: border-box; - margin: var(--tui__spacing-16) var(--tui__spacing-32); + margin: 0; color: var(--tui__color-black); font-family: var(--tui__font-family-serif); font-size: var(--tui__font-size-md); @@ -13,9 +13,13 @@ } .tui__blockquote > footer { - margin: var(--tui__spacing-16) 0; + margin-top: var(--tui__spacing-16); } .tui__blockquote-source { font-style: italic; } + +.tui__prose .tui__blockquote { + margin: var(--tui__spacing-16) var(--tui__spacing-32); +} diff --git a/packages/style/src/components/heading.css b/packages/style/src/components/heading.css index 210930c..c59c67c 100644 --- a/packages/style/src/components/heading.css +++ b/packages/style/src/components/heading.css @@ -10,48 +10,66 @@ } h1.tui__heading { - margin-bottom: var(--tui__spacing-24); font-size: var(--tui__font-size-3xl); font-weight: var(--tui__font-weight-extra-bold); line-height: var(--tui__line-height-sm); } h2.tui__heading { - margin-top: var(--tui__spacing-40); - margin-bottom: var(--tui__spacing-16); font-size: var(--tui__font-size-2xl); font-weight: var(--tui__font-weight-bold); line-height: var(--tui__line-height-sm); } h3.tui__heading { - margin-top: var(--tui__spacing-32); - margin-bottom: var(--tui__spacing-12); font-size: var(--tui__font-size-xl); font-weight: var(--tui__font-weight-semi-bold); line-height: var(--tui__line-height-md); } h4.tui__heading { - margin-top: var(--tui__spacing-24); - margin-bottom: var(--tui__spacing-8); font-size: var(--tui__font-size-md); font-weight: var(--tui__font-weight-semi-bold); line-height: var(--tui__line-height-md); } h5.tui__heading { - margin-top: var(--tui__spacing-24); - margin-bottom: var(--tui__spacing-8); font-size: var(--tui__font-size-md); font-weight: var(--tui__font-weight-semi-bold); line-height: var(--tui__line-height-md); } h6.tui__heading { - margin-top: var(--tui__spacing-24); - margin-bottom: var(--tui__spacing-8); font-size: var(--tui__font-size-md); font-weight: var(--tui__font-weight-semi-bold); line-height: var(--tui__line-height-md); } + +.tui__prose h1.tui__heading { + margin-bottom: var(--tui__spacing-24); +} + +.tui__prose h2.tui__heading { + margin-top: var(--tui__spacing-40); + margin-bottom: var(--tui__spacing-16); +} + +.tui__prose h3.tui__heading { + margin-top: var(--tui__spacing-32); + margin-bottom: var(--tui__spacing-12); +} + +.tui__prose h4.tui__heading { + margin-top: var(--tui__spacing-24); + margin-bottom: var(--tui__spacing-8); +} + +.tui__prose h5.tui__heading { + margin-top: var(--tui__spacing-24); + margin-bottom: var(--tui__spacing-8); +} + +.tui__prose h6.tui__heading { + margin-top: var(--tui__spacing-24); + margin-bottom: var(--tui__spacing-8); +} diff --git a/packages/style/src/components/list.css b/packages/style/src/components/list.css index fc9d76d..e8a9e3b 100644 --- a/packages/style/src/components/list.css +++ b/packages/style/src/components/list.css @@ -1,8 +1,13 @@ .tui__list { display: block; box-sizing: border-box; - padding-left: var(--tui__spacing-32); - margin: var(--tui__spacing-16) 0; + padding: 0; + margin: 0; + list-style-position: inside; +} + +.tui__list .tui__list { + padding: 0 0 0 var(--tui__spacing-16); } ul.tui__list { @@ -10,7 +15,7 @@ ul.tui__list { } ol.tui__list { - list-style-type: decimal; + counter-reset: item; } .tui__list > li { @@ -24,3 +29,21 @@ ol.tui__list { line-height: var(--tui__line-height-md); overflow-wrap: break-word; } + +ol.tui__list > li { + display: block; +} + +ol.tui__list > li::before { + content: counters(item, ".") ". "; + counter-increment: item; +} + +.tui__prose .tui__list { + padding: 0 0 0 var(--tui__spacing-16); + margin: 0 0 var(--tui__spacing-16) 0; +} + +.tui__prose :is(.tui__list > li) > .tui__list { + margin: 0; +} diff --git a/packages/style/src/components/paragraph.css b/packages/style/src/components/paragraph.css index 5280905..a318375 100644 --- a/packages/style/src/components/paragraph.css +++ b/packages/style/src/components/paragraph.css @@ -1,7 +1,7 @@ .tui__paragraph { display: block; box-sizing: border-box; - margin: var(--tui__spacing-16) 0; + margin: 0; color: var(--tui__color-black); font-family: var(--tui__font-family-serif); font-size: var(--tui__font-size-md); @@ -12,6 +12,10 @@ overflow-wrap: break-word; } -:is(h1, h2, h3, h4, h5, h6) + .tui__paragraph { +.tui__prose .tui__paragraph { + margin: var(--tui__spacing-16) 0; +} + +.tui__prose :is(h1, h2, h3, h4, h5, h6) + .tui__paragraph { margin-top: 0; } diff --git a/packages/style/src/components/prose.css b/packages/style/src/components/prose.css new file mode 100644 index 0000000..213bda3 --- /dev/null +++ b/packages/style/src/components/prose.css @@ -0,0 +1,5 @@ +.tui__prose { + display: flex; + box-sizing: border-box; + flex-flow: column nowrap; +} diff --git a/packages/web-components/src/components/Prose/Prose.ts b/packages/web-components/src/components/Prose/Prose.ts new file mode 100644 index 0000000..75c2a1b --- /dev/null +++ b/packages/web-components/src/components/Prose/Prose.ts @@ -0,0 +1,30 @@ +import style from "@themeless-ui/style/dist/prose.css?inline"; +import { cn } from "@themeless-ui/utils"; +import { html, nothing, unsafeCSS } from "lit"; +import { customElement } from "lit/decorators.js"; +import { TUIComponent } from "../TUIComponent"; + +const className = cn("prose"); + +@customElement("tui-prose") +export class Prose extends TUIComponent { + static styles = unsafeCSS(style); + + override render() { + return html` +
+ +
+ `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "tui-prose": Prose; + } +} diff --git a/packages/web-components/src/components/Prose/index.ts b/packages/web-components/src/components/Prose/index.ts new file mode 100644 index 0000000..e24c9f8 --- /dev/null +++ b/packages/web-components/src/components/Prose/index.ts @@ -0,0 +1 @@ +export { Prose } from "./Prose"; diff --git a/packages/web-components/src/components/index.ts b/packages/web-components/src/components/index.ts index 5106925..f1567a5 100644 --- a/packages/web-components/src/components/index.ts +++ b/packages/web-components/src/components/index.ts @@ -6,6 +6,7 @@ export * from "./Input"; export * from "./List"; export * from "./ListItem"; export * from "./Paragraph"; +export * from "./Prose"; export * from "./Stack"; export * from "./Text"; export * from "./Textarea";