From 28c24bf6748df529be2656567f558a321a8cb1fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Kuna?= <1282324+codecalm@users.noreply.github.com> Date: Wed, 14 Oct 2026 18:45:04 +0200 Subject: [PATCH] Move Shape to the core CSS bundle (#3305) --- .build/compat-baseline.txt | 67 +++++++- .changeset/shape-in-core.md | 5 + core/scss/_core.scss | 1 + core/scss/tabler-marketing.scss | 1 - core/scss/{marketing => ui}/_shape.scss | 2 + docs/content/ui/components/shape.mdx | 107 ++++++++++++ .../ui/getting-started/upgrade/1-7.mdx | 20 ++- preview/pages/shape.astro | 162 ++++++++++++++++++ screenshots/pages/shape.astro | 39 +++++ shared/data/menu.json | 5 + 10 files changed, 399 insertions(+), 10 deletions(-) create mode 100644 .changeset/shape-in-core.md rename core/scss/{marketing => ui}/_shape.scss (91%) create mode 100644 docs/content/ui/components/shape.mdx create mode 100644 preview/pages/shape.astro create mode 100644 screenshots/pages/shape.astro diff --git a/.build/compat-baseline.txt b/.build/compat-baseline.txt index 21e745017..a6e8134ab 100644 --- a/.build/compat-baseline.txt +++ b/.build/compat-baseline.txt @@ -14,7 +14,7 @@ # against: 1.6.1 # # Decided by codecalm on 2026-10-06 (#3278): Pricing moves from tabler-marketing.css -# to tabler.css. See the 1.7 upgrade guide, "Pricing is in the core bundle". +# to tabler.css. See the 1.7 upgrade guide, "Pricing and Shape are in the core bundle". css:tabler-marketing.css:--tblr-gray-200 # accepted: Pricing ships in tabler.css since 1.7, which every marketing page loads anyway css:tabler-marketing.css:--tblr-shadow-card # accepted: Pricing ships in tabler.css since 1.7, which every marketing page loads anyway css:tabler-marketing.css:.pricing # accepted: Pricing ships in tabler.css since 1.7, which every marketing page loads anyway @@ -27,3 +27,68 @@ css:tabler-marketing.css:.pricing-price-currency # accepted: Pricing ships in ta css:tabler-marketing.css:.pricing-price-description # accepted: Pricing ships in tabler.css since 1.7, which every marketing page loads anyway css:tabler-marketing.css:.pricing-title # accepted: Pricing ships in tabler.css since 1.7, which every marketing page loads anyway file:scss/marketing/_pricing.scss # accepted: Pricing ships in tabler.css since 1.7, which every marketing page loads anyway +# +# Decided by codecalm on 2026-10-08 (#3294): Shape moves from tabler-marketing.css +# to tabler.css. See the 1.7 upgrade guide, "Pricing and Shape are in the core bundle". +css:tabler-marketing.css:--tblr-azure # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-azure-lt # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-black # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-black-lt # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-blue # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-blue-lt # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-cyan # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-cyan-lt # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-gray # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-gray-dark # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-gray-dark-lt # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-gray-lt # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-green # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-green-lt # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-indigo # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-indigo-lt # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-lime # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-lime-lt # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-orange # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-orange-lt # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-pink # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-pink-lt # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-primary-lt # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-purple # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-purple-lt # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-red # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-red-lt # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-shape-border-radius # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-shape-icon-size # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-shape-size # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-teal # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-teal-lt # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-white # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-white-lt # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-yellow # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:--tblr-yellow-lt # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.icon # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-2xl # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-azure # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-black # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-blue # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-cyan # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-gray # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-gray-dark # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-green # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-indigo # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-lg # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-lime # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-md # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-orange # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-pink # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-purple # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-red # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-sm # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-teal # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-white # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-xl # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-xs # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-xxs # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +css:tabler-marketing.css:.shape-yellow # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway +file:scss/marketing/_shape.scss # accepted: Shape ships in tabler.css since 1.7, which every marketing page loads anyway diff --git a/.changeset/shape-in-core.md b/.changeset/shape-in-core.md new file mode 100644 index 000000000..1c7b1b6e8 --- /dev/null +++ b/.changeset/shape-in-core.md @@ -0,0 +1,5 @@ +--- +"@tabler/core": minor +--- + +Moved the `.shape` component from `tabler-marketing.css` to the core `tabler.css` bundle. diff --git a/core/scss/_core.scss b/core/scss/_core.scss index eca020f87..b668d7e11 100644 --- a/core/scss/_core.scss +++ b/core/scss/_core.scss @@ -84,6 +84,7 @@ @forward 'ui/pagination'; @forward 'ui/popovers'; @forward 'ui/pricing'; +@forward 'ui/shape'; @forward 'ui/progress'; @forward 'ui/ribbons'; @forward 'ui/markdown'; diff --git a/core/scss/tabler-marketing.scss b/core/scss/tabler-marketing.scss index ecd75a1d9..123a28806 100644 --- a/core/scss/tabler-marketing.scss +++ b/core/scss/tabler-marketing.scss @@ -5,7 +5,6 @@ @forward 'marketing/browser'; @forward 'marketing/sections'; @forward 'marketing/filters'; -@forward 'marketing/shape'; // This bundle uses its own utilities map instead of the global one, so the // utilities API is emitted via the parameterized mixin (last, as before). diff --git a/core/scss/marketing/_shape.scss b/core/scss/ui/_shape.scss similarity index 91% rename from core/scss/marketing/_shape.scss rename to core/scss/ui/_shape.scss index b09854eff..6d7e94141 100644 --- a/core/scss/marketing/_shape.scss +++ b/core/scss/ui/_shape.scss @@ -3,9 +3,11 @@ @use '../config' as *; .shape { + // scss-docs-start shape-css-vars --shape-size: #{$avatar-size}; --shape-icon-size: #{$avatar-icon-size}; --shape-border-radius: 35%; + // scss-docs-end shape-css-vars display: inline-flex; align-items: center; justify-content: center; diff --git a/docs/content/ui/components/shape.mdx b/docs/content/ui/components/shape.mdx new file mode 100644 index 000000000..c7b254973 --- /dev/null +++ b/docs/content/ui/components/shape.mdx @@ -0,0 +1,107 @@ +--- +title: Shape +summary: A tinted, rounded square that holds one icon, for feature lists and other places where an icon needs a background. +description: Put an icon on a soft, tinted background with the shape component. Pick a size and a color, or set the corner radius with a CSS variable. +related: [/ui/components/avatar, /ui/components/icon] +source: core/scss/ui/_shape.scss +css-vars: shape +added-in: '1.7.0' +classnames: + component: + - class: shape + desc: Container element, an inline rounded square in the primary color + color: + - class: shape-{color} + desc: Any palette color, for example shape-red or shape-teal + size: + - class: shape-{size} + desc: Avatar sizes from shape-xxs to shape-2xl +--- +import Example from '@components/Example.astro'; +import Icon from '@ui/Icon.astro'; + +## Default markup + +A shape is a `.shape` element with one icon inside. It is a square with soft corners, filled with a light tint of the primary color. The icon takes the stronger primary color. The square is the same size as an [avatar](/ui/components/avatar), so the two line up in a list. + + + + + +## Sizes + +Add `.shape-{size}` to change the size. The sizes are the avatar sizes, from `xxs` to `2xl`. The icon grows with the square. + + +
+ + + + + + + +
+
+ +## Colors + +Add `.shape-{color}` to use another palette color. The square takes the light tint of the color and the icon takes the full color. + + +
+ + + + + + + + + + + + +
+
+ +## Corner radius + +The corners are rounded by `35%` of the size. Set `--tblr-shape-border-radius` on the shape to change this: `50%` makes a circle, `0` makes a sharp square. + + +
+ + + +
+
+ +## In a feature list + +Shapes mark the items of a feature list. Put one above or next to each heading, with the same size and color on every item. + + +
+
+ +

Mobile-optimized

+

Every page works on any screen size.

+
+
+ +

Tested email clients

+

Checked in more than 90 email clients.

+
+
+ +

Minimal design

+

Clean layouts based on Bootstrap.

+
+
+
+ +## Accessibility + +- A shape is decoration. The icon inside renders with `aria-hidden="true"`, so the shape adds nothing to the accessibility tree. +- Put the meaning in the text next to the shape, not in the icon or the color. diff --git a/docs/content/ui/getting-started/upgrade/1-7.mdx b/docs/content/ui/getting-started/upgrade/1-7.mdx index cd42df5c9..585c9318c 100644 --- a/docs/content/ui/getting-started/upgrade/1-7.mdx +++ b/docs/content/ui/getting-started/upgrade/1-7.mdx @@ -1,15 +1,15 @@ --- title: Upgrade to 1.7 -summary: Move a project from Tabler 1.6 to 1.7. The Pricing component moved from the marketing bundle into the core bundle, so a page that loaded only the marketing stylesheet for it needs one more link. +summary: Move a project from Tabler 1.6 to 1.7. The Pricing and Shape components moved from the marketing bundle into the core bundle, so a page that loaded only the marketing stylesheet for them needs one more link. description: Upgrade guide from Tabler 1.6 to 1.7 with the components that moved from the marketing bundle into the core bundle, and what to change in your HTML and Sass imports. added-in: '1.7.0' order: 1 related: [/ui/getting-started/upgrade/1-6, /ui/getting-started/customize] --- -Tabler 1.7 is a small update. Every class, custom property, Sass variable and function from 1.6 is still there, and the only change that can touch your code is where one component ships: Pricing moved from `tabler-marketing.css` into the core `tabler.css`. A page that loads both files, as every marketing page does, needs no change. +Tabler 1.7 is a small update. Every class, custom property, Sass variable and function from 1.6 is still there, and the only change that can touch your code is where two components ship: Pricing and Shape moved from `tabler-marketing.css` into the core `tabler.css`. A page that loads both files, as every marketing page does, needs no change. -Check [Pricing is in the core bundle](#pricing-is-in-the-core-bundle) if you load `tabler-marketing.css` on its own or import its Sass partials one by one. +Check [Pricing and Shape are in the core bundle](#pricing-and-shape-are-in-the-core-bundle) if you load `tabler-marketing.css` on its own or import its Sass partials one by one. If you're coming from 1.5 or older, do the [1.6 upgrade](/ui/getting-started/upgrade/1-6) first. @@ -18,8 +18,8 @@ If you're coming from 1.5 or older, do the [1.6 upgrade](/ui/getting-started/upg If you…|You need to… ---|--- Load `tabler.css` and `tabler-marketing.css` together|Nothing -Load `tabler-marketing.css` without `tabler.css` on a page that uses `.pricing`|Add `tabler.css`, see [Pricing is in the core bundle](#pricing-is-in-the-core-bundle) -Import `scss/marketing/pricing` in your own Sass|Import `scss/ui/pricing`, see [Sass changes](#sass-changes) +Load `tabler-marketing.css` without `tabler.css` on a page that uses `.pricing` or `.shape`|Add `tabler.css`, see [Pricing and Shape are in the core bundle](#pricing-and-shape-are-in-the-core-bundle) +Import `scss/marketing/pricing` or `scss/marketing/shape` in your own Sass|Import `scss/ui/pricing` or `scss/ui/shape`, see [Sass changes](#sass-changes) ## Update the package @@ -39,11 +39,11 @@ Or update the CDN links: ``` -## Pricing is in the core bundle +## Pricing and Shape are in the core bundle -The [Pricing](/ui/components/pricing) component, `.pricing` and its `.pricing-*` parts, used to ship only in `tabler-marketing.css`. It's part of `tabler.css` now, so a dashboard can show plan cards without the marketing stylesheet. The class names and the markup are the same. +The [Pricing](/ui/components/pricing) component, `.pricing` and its `.pricing-*` parts, and the [Shape](/ui/components/shape) component, `.shape` with its size and color modifiers, used to ship only in `tabler-marketing.css`. They're part of `tabler.css` now, so a dashboard can show plan cards or an icon in a shape without the marketing stylesheet. The class names and the markup are the same. -`tabler-marketing.css` no longer contains the component. A page that loads both stylesheets keeps working. A page that loaded only `tabler-marketing.css` for the pricing cards has to add `tabler.css`, which it needs for the buttons and badges inside the cards anyway: +`tabler-marketing.css` no longer contains the two components. A page that loads both stylesheets keeps working. A page that loaded only `tabler-marketing.css` for them has to add `tabler.css`, which it needs for the buttons, badges and icons inside them anyway: ```diff - @@ -62,10 +62,13 @@ Only relevant if you compile the `scss/` sources yourself and import partials on Partial in 1.6|Partial in 1.7 ---|--- `scss/marketing/_pricing.scss`|`scss/ui/_pricing.scss` +`scss/marketing/_shape.scss`|`scss/ui/_shape.scss` ```diff - @use '@tabler/core/scss/marketing/pricing'; +- @use '@tabler/core/scss/marketing/shape'; + @use '@tabler/core/scss/ui/pricing'; ++ @use '@tabler/core/scss/ui/shape'; ``` ## What is new in 1.7 @@ -73,5 +76,6 @@ Partial in 1.6|Partial in 1.7 Besides the changes above, 1.7 adds: - [Pricing](/ui/components/pricing) as a documented core component, with a class reference. +- [Shape](/ui/components/shape), a rounded container for an icon in several sizes and every theme color, with its CSS variables documented. See the [changelog](https://github.com/tabler/tabler/releases) for the full list. diff --git a/preview/pages/shape.astro b/preview/pages/shape.astro new file mode 100644 index 000000000..cda315af2 --- /dev/null +++ b/preview/pages/shape.astro @@ -0,0 +1,162 @@ +--- +import DefaultLayout from '@shared/layouts/DefaultLayout.astro' +import Card from '@ui/Card.astro' +import CardBody from '@ui/CardBody.astro' +import CardTitle from '@ui/CardTitle.astro' +import CardSubtitle from '@ui/CardSubtitle.astro' +import DocsLink from '@ui/DocsLink.astro' +import Icon from '@ui/Icon.astro' +import { avatarSizes, extraColors } from '@shared/lib/tokens' + +const icons = ['devices', 'mailbox', 'palette', 'tools', 'brand-bootstrap', 'paint', 'rocket', 'shield-check'] + +const radii = [ + { label: 'Square', value: '0' }, + { label: 'Default', value: undefined }, + { label: 'Circle', value: '50%' }, +] + +const features = [ + { icon: 'devices', title: 'Mobile-optimized', text: 'Every page works on any screen size, from a phone to a wide monitor.' }, + { icon: 'mailbox', title: 'Tested email clients', text: 'Checked in more than 90 email clients and devices.' }, + { icon: 'palette', title: 'Minimal design', text: 'Clean layouts based on Bootstrap and Material Design principles.' }, +] + +const featureList = [ + { icon: 'tools', color: 'blue', title: 'Easy to customize', text: 'Change colors, fonts and spacing with Sass or CSS variables.' }, + { icon: 'brand-bootstrap', color: 'purple', title: 'Built on Bootstrap', text: 'Every Bootstrap component works out of the box.' }, + { icon: 'paint', color: 'green', title: 'Dark mode', text: 'One attribute switches the whole interface to a dark theme.' }, +] +--- + + + + +
+
+ + + Sizes + Add .shape-{size}, from xxs to 2xl, the same sizes as an avatar. +
+ { + avatarSizes.map((size) => ( + + + + )) + } +
+
+
+
+ +
+ + + Colors + Add .shape-{color} to use another palette color. +
+ + { + extraColors.map((color) => ( + + + + )) + } +
+
+
+
+ +
+ + + With icons + Put one .icon inside the shape; it is sized with the square. +
+ { + icons.map((icon) => ( + + + + )) + } +
+
+
+
+ +
+ + + Corner radius + Set --tblr-shape-border-radius to change the corners; the default is 35%. +
+ { + radii.map((item) => ( +
+ + + +
{item.label}
+
+ )) + } +
+
+
+
+ +
+ + + Feature list + A shape above each heading, with the same size and color on every item. +
+ { + features.map((feature) => ( +
+ + + +

{feature.title}

+

{feature.text}

+
+ )) + } +
+
+
+
+ +
+ + + Feature list, inline + A colored shape next to each heading, in a .row with an auto column. +
+ { + featureList.map((feature) => ( +
+
+
+ + + +
+
+

{feature.title}

+

{feature.text}

+
+
+
+ )) + } +
+
+
+
+
+
diff --git a/screenshots/pages/shape.astro b/screenshots/pages/shape.astro new file mode 100644 index 000000000..aa6415a1d --- /dev/null +++ b/screenshots/pages/shape.astro @@ -0,0 +1,39 @@ +--- +// Shape component: a six-item feature grid, each item with a colored shape +// above its heading, the way the marketing pages use it. Six colors so the +// tint and the icon color read as a pair across the palette, at the default +// size a page would use. +import ScreenshotLayout from '../layouts/ScreenshotLayout.astro' +import Card from '@ui/Card.astro' +import CardBody from '@ui/CardBody.astro' +import Icon from '@ui/Icon.astro' + +const features = [ + { icon: 'devices', color: 'blue', title: 'Mobile-optimized', text: 'Every page works on any screen size, from a phone to a wide monitor.' }, + { icon: 'mailbox', color: 'purple', title: 'Tested email clients', text: 'Checked in more than 90 email clients and devices.' }, + { icon: 'palette', color: 'green', title: 'Minimal design', text: 'Clean layouts based on Bootstrap and Material Design principles.' }, + { icon: 'shield-check', color: 'orange', title: 'Secure by default', text: 'Sensible defaults for forms, auth pages and user settings.' }, + { icon: 'chart-bar', color: 'red', title: 'Charts and tables', text: 'Dashboards, data grids and charts that fit in with the rest.' }, + { icon: 'users', color: 'teal', title: 'Built for teams', text: 'Shared components and docs so everyone ships the same UI.' }, +] +--- + + + + +
+ { + features.map((feature) => ( +
+ + + +

{feature.title}

+

{feature.text}

+
+ )) + } +
+
+
+
diff --git a/shared/data/menu.json b/shared/data/menu.json index bf005cd37..0d73574b7 100644 --- a/shared/data/menu.json +++ b/shared/data/menu.json @@ -241,6 +241,11 @@ "title": "Scroll spy", "url": "scroll-spy.html" }, + "shape": { + "title": "Shape", + "url": "shape.html", + "badge": "New" + }, "signal": { "title": "Signal", "url": "signal.html"