From 19eb64f8a4a80edf6e4a848e0136f6b179480bee Mon Sep 17 00:00:00 2001 From: Rui Lopes Date: Wed, 18 Sep 2024 13:03:20 +0100 Subject: [PATCH 1/2] feat: support for tabler icons --- assets/css/components/button.css | 100 ++---------------------------- assets/tailwind.config.js | 39 +++++++++++- lib/atomic_web/components/icon.ex | 8 ++- lib/atomic_web/config.ex | 2 +- mix.exs | 2 + mix.lock | 1 + 6 files changed, 54 insertions(+), 98 deletions(-) diff --git a/assets/css/components/button.css b/assets/css/components/button.css index afe6bc3ab..73abda247 100644 --- a/assets/css/components/button.css +++ b/assets/css/components/button.css @@ -159,19 +159,19 @@ } .atomic-button__icon--xs { - @apply w-3 h-3; + @apply !size-3 } .atomic-button__icon--sm { - @apply w-4 h-4; + @apply !size-4 } .atomic-button__icon--md { - @apply w-5 h-5; + @apply !size-5 } .atomic-button__icon--lg { - @apply w-5 h-5; + @apply !size-5 } .atomic-button__icon--xl { - @apply w-6 h-6; + @apply !size-6 } /* Buttons - with full width */ @@ -185,96 +185,6 @@ @apply flex items-center gap-2 whitespace-nowrap; } -/* Icon Button */ - -.atomic-icon-button { - @apply inline-block p-2 rounded-full; -} - -/* Icon Buttons - colors */ - -.atomic-icon-button--primary { - @apply text-primary-600 dark:text-primary-500; -} -.atomic-icon-button--secondary { - @apply text-secondary-600 dark:text-secondary-500; -} -.atomic-icon-button--gray { - @apply text-gray-600 dark:text-gray-500; -} -.atomic-icon-button--info { - @apply text-info-600 dark:text-info-500; -} -.atomic-icon-button--success { - @apply text-success-600 dark:text-success-500; -} -.atomic-icon-button--warning { - @apply text-warning-600 dark:text-warning-500; -} -.atomic-icon-button--danger { - @apply text-danger-600 dark:text-danger-500; -} - -/* Icon Buttons - background colors */ - -.atomic-icon-button-bg--primary { - @apply hover:bg-primary-50 dark:hover:bg-gray-800; -} -.atomic-icon-button-bg--secondary { - @apply hover:bg-secondary-50 dark:hover:bg-gray-800; -} -.atomic-icon-button-bg--gray { - @apply hover:bg-gray-100 dark:hover:bg-gray-800; -} -.atomic-icon-button-bg--info { - @apply hover:bg-info-50 dark:hover:bg-gray-800; -} -.atomic-icon-button-bg--success { - @apply hover:bg-success-50 dark:hover:bg-gray-800; -} -.atomic-icon-button-bg--warning { - @apply hover:bg-warning-50 dark:hover:bg-gray-800; -} -.atomic-icon-button-bg--danger { - @apply hover:bg-danger-50 dark:hover:bg-gray-800; -} - -/* Icon Button - sizes */ - -.atomic-icon-button--xs { - @apply w-9 h-9; -} -.atomic-icon-button--sm { - @apply w-10 h-10; -} -.atomic-icon-button--md { - @apply w-11 h-11; -} -.atomic-icon-button--lg { - @apply w-12 h-12; -} -.atomic-icon-button--xl { - @apply w-14 h-14; -} - -/* Icon Button - spinner */ - -.atomic-icon-button-spinner--xs { - @apply w-5 h-5; -} -.atomic-icon-button-spinner--sm { - @apply w-6 h-6; -} -.atomic-icon-button-spinner--md { - @apply w-7 h-7; -} -.atomic-icon-button-spinner--lg { - @apply w-8 h-8; -} -.atomic-icon-button-spinner--xl { - @apply w-10 h-10; -} - /* Button - disabled */ .atomic-button--disabled { diff --git a/assets/tailwind.config.js b/assets/tailwind.config.js index 36902c3c6..201fc0ee5 100644 --- a/assets/tailwind.config.js +++ b/assets/tailwind.config.js @@ -89,6 +89,7 @@ module.exports = { } else if (name.endsWith("-micro")) { size = theme("spacing.4") } + return { [`--hero-${name}`]: `url('data:image/svg+xml;utf8,${content}')`, "-webkit-mask": `var(--hero-${name})`, @@ -101,7 +102,43 @@ module.exports = { "height": size } } - }, {values}) + }, { values }) + }), + + // Embeds Tabler icons (https://tablericons.com) into app.css bundle + plugin(function ({ matchComponents, theme }) { + let iconsDir = path.join(__dirname, "../deps/tabler_icons/icons") + let values = {} + let icons = [ + ["", "/outline"], + ["-filled", "/filled"], + ] + icons.forEach(([suffix, dir]) => { + fs.readdirSync(path.join(iconsDir, dir)).forEach(file => { + let name = path.basename(file, ".svg") + suffix + values[name] = { name, fullPath: path.join(iconsDir, dir, file) } + }) + }) + matchComponents({ + "tabler": ({ name, fullPath }) => { + let content = fs.readFileSync(fullPath).toString() + .replace(/\r?\n|\r/g, "") + .replace(/width="[^"]*"/, "") + .replace(/height="[^"]*"/, ""); + + return { + [`--tabler-${name}`]: `url('data:image/svg+xml;utf8,${content}')`, + "-webkit-mask": `var(--tabler-${name})`, + "mask": `var(--tabler-${name})`, + "mask-repeat": "no-repeat", + "background-color": "currentColor", + "vertical-align": "middle", + "display": "inline-block", + "width": theme("spacing.5"), + "height": theme("spacing.5") + } + } + }, { values }) }) ] } diff --git a/lib/atomic_web/components/icon.ex b/lib/atomic_web/components/icon.ex index ee97acc1a..124270b59 100644 --- a/lib/atomic_web/components/icon.ex +++ b/lib/atomic_web/components/icon.ex @@ -2,7 +2,7 @@ defmodule AtomicWeb.Components.Icon do @moduledoc """ A component for rendering icons. - An icon can either be from the Heroicons or Tabler Icons set. + An icon can either be from the [Heroicons](https://heroicons.com) or [Tabler Icons](https://tablericons.com) set. """ use Phoenix.Component @@ -14,4 +14,10 @@ defmodule AtomicWeb.Components.Icon do """ end + + def icon(%{name: "tabler-" <> _} = assigns) do + ~H""" + + """ + end end diff --git a/lib/atomic_web/config.ex b/lib/atomic_web/config.ex index 4b2f3dc34..949f8b9c0 100644 --- a/lib/atomic_web/config.ex +++ b/lib/atomic_web/config.ex @@ -92,7 +92,7 @@ defmodule AtomicWeb.Config do %{ key: :organizations, title: "Organizations", - icon: "hero-building-office", + icon: "tabler-affiliate", url: Routes.organization_index_path(conn, :index), tabs: [] } diff --git a/mix.exs b/mix.exs index 5101de7e2..1b692ebf3 100644 --- a/mix.exs +++ b/mix.exs @@ -75,6 +75,8 @@ defmodule Atomic.MixProject do compile: false, depth: 1, override: true}, + {:tabler_icons, + github: "tabler/tabler-icons", sparse: "icons", app: false, compile: false, depth: 1}, # monitoring {:telemetry_metrics, "~> 0.6"}, diff --git a/mix.lock b/mix.lock index 70db7f132..da0d37fd4 100644 --- a/mix.lock +++ b/mix.lock @@ -64,6 +64,7 @@ "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "swoosh": {:hex, :swoosh, "1.17.0", "4a082a6ce4d60b1f48ffa725c8da0e2304504569ff550f4ed2d088c923039cb0", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mua, "~> 0.2.3", [hex: :mua, repo: "hexpm", optional: true]}, {:multipart, "~> 0.4", [hex: :multipart, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.5 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "659b8bc25f7483b872d051a7f0731fb8d5312165be0d0302a3c783b566b0a290"}, + "tabler_icons": {:git, "https://github.com/tabler/tabler-icons.git", "405bcfffba9cecf08e686145367dcdc9cc44eb5c", [sparse: "icons"]}, "tailwind": {:hex, :tailwind, "0.2.3", "277f08145d407de49650d0a4685dc062174bdd1ae7731c5f1da86163a24dfcdb", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "8e45e7a34a676a7747d04f7913a96c770c85e6be810a1d7f91e713d3a3655b5d"}, "tailwind_formatter": {:hex, :tailwind_formatter, "0.3.7", "2728d031e6803dfddf63f1dd7c64b5b9fd70ffdf635709c50f47589f4fb48861", [:mix], [{:phoenix_live_view, ">= 0.17.6", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}], "hexpm", "3d91ac4d4622505b09c0f4678512281515b4fbe7644f012da1bd2722f5880185"}, "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, From 24cdf1a515a9e6d0259898a77281581972c297ed Mon Sep 17 00:00:00 2001 From: Rui Lopes Date: Wed, 18 Sep 2024 13:08:03 +0100 Subject: [PATCH 2/2] feat: create storybook entries for tabler icons --- storybook/components/icon.story.exs | 34 ++++++++++++++++++----------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/storybook/components/icon.story.exs b/storybook/components/icon.story.exs index 3a3924dbb..d89ddf180 100644 --- a/storybook/components/icon.story.exs +++ b/storybook/components/icon.story.exs @@ -16,37 +16,45 @@ defmodule AtomicWeb.Storybook.Components.Icon do def variations do [ %Variation{ - id: :default, + id: :hero_outline, + description: "Heroicon outline", attributes: %{ name: "hero-academic-cap" } }, %Variation{ - id: :outline, - description: "Outline", + id: :hero_solid, + description: "Heroicon solid", attributes: %{ - name: "hero-academic-cap" + name: "hero-academic-cap-solid" } }, %Variation{ - id: :solid, - description: "Solid", + id: :hero_mini, + description: "Heroicon mini", attributes: %{ - name: "hero-academic-cap-solid" + name: "hero-academic-cap-mini" } }, %Variation{ - id: :mini, - description: "Mini", + id: :hero_micro, + description: "Heroicon micro", attributes: %{ - name: "hero-academic-cap-mini" + name: "hero-academic-cap-micro" } }, %Variation{ - id: :micro, - description: "Micro", + id: :tabler_outline, + description: "Tabler outline", attributes: %{ - name: "hero-academic-cap-micro" + name: "tabler-affiliate" + } + }, + %Variation{ + id: :tabler_filled, + description: "Tabler filled", + attributes: %{ + name: "tabler-affiliate-filled" } } ]