diff --git a/index.html b/index.html index e67608f..2ddf104 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,7 @@ Phosphor Icons - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/ipad.svg b/src/assets/ipad.svg index cc63cb5..614c0c1 100644 --- a/src/assets/ipad.svg +++ b/src/assets/ipad.svg @@ -1,53 +1,47 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/map-spec.svg b/src/assets/map-spec.svg new file mode 100644 index 0000000..215abb9 --- /dev/null +++ b/src/assets/map-spec.svg @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/map.svg b/src/assets/map.svg index 5b5e212..795e20d 100644 --- a/src/assets/map.svg +++ b/src/assets/map.svg @@ -1,65 +1,134 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/paperclips-2.svg b/src/assets/paperclips-2.svg new file mode 100644 index 0000000..18eb398 --- /dev/null +++ b/src/assets/paperclips-2.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/paperclips-3.svg b/src/assets/paperclips-3.svg new file mode 100644 index 0000000..279e4dc --- /dev/null +++ b/src/assets/paperclips-3.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/phosphor-logo.svg b/src/assets/phosphor-logo.svg new file mode 100644 index 0000000..c651c82 --- /dev/null +++ b/src/assets/phosphor-logo.svg @@ -0,0 +1,4 @@ + + + diff --git a/src/assets/ruler-marker-spec.svg b/src/assets/ruler-marker-spec.svg new file mode 100644 index 0000000..b99dc19 --- /dev/null +++ b/src/assets/ruler-marker-spec.svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/ruler-marker.svg b/src/assets/ruler-marker.svg new file mode 100644 index 0000000..64530af --- /dev/null +++ b/src/assets/ruler-marker.svg @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/synth-spec.svg b/src/assets/synth-spec.svg new file mode 100644 index 0000000..5780827 --- /dev/null +++ b/src/assets/synth-spec.svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/synth.svg b/src/assets/synth.svg index ab3c4d3..2458d86 100644 --- a/src/assets/synth.svg +++ b/src/assets/synth.svg @@ -1,325 +1,230 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/watch-spec.svg b/src/assets/watch-spec.svg new file mode 100644 index 0000000..d6f75e1 --- /dev/null +++ b/src/assets/watch-spec.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/watch.svg b/src/assets/watch.svg index d34c1b7..80eacbc 100644 --- a/src/assets/watch.svg +++ b/src/assets/watch.svg @@ -1,61 +1,45 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + diff --git a/src/components/App/App.css b/src/components/App/App.css index 8fd7ade..4e9db5c 100644 --- a/src/components/App/App.css +++ b/src/components/App/App.css @@ -1,26 +1,29 @@ :root { - --red: #ff6e60; + --red: #e8612b; --orange: #ff8e51; - --yellow: #ffd171; + --yellow: #f8c666; --pale: #ffe8dc; --peach: #ffd5c0; --sand: #bcadaf; + --vellum: #eeeae3; --foam: #e9ebe2; --lichen: #d2d6c5; --moss: #3c402b; - --moss-shadow: rgba(60, 64, 43, 0.2); - --stone: #1f2310; + --slate: #3e3d3a; + --stone: #343330; --acid: #c4e456; + --green: #1fa647; --darkgreen: #245633; - --blue: #397fff; + --blue: #1f7fea; --purple: #925bff; --eggplant: #35313d; - --neutral: #86838b; - --translucent: rgba(163, 159, 171, 0.1); + --moss-shadow: rgba(60, 64, 43, 0.2); + --shadow: rgba(0, 0, 0, 0.15); --scrim: rgba(255, 255, 255, 0.05); --sheer: rgba(194, 186, 196, 0.25); --soft: rgba(194, 186, 196, 0.7); - --shadow: rgba(0, 0, 0, 0.15); + --translucent: rgba(255, 255, 255, 0.5); + --neutral: #9b9b9b; } body { @@ -31,14 +34,18 @@ body { } ::selection { - color: white; - background-color: black; + color: var(--moss); + background-color: var(--acid); } h2 { font-weight: 400; } +p { + font-size: 16px; +} + img { -moz-user-select: none; -webkit-user-select: none; @@ -49,17 +56,26 @@ img { pre, code { font-family: "IBM Plex Mono", "Courier New", monospace; - font-size: 12px; } pre { box-sizing: border-box; margin: 0; border-radius: 6px; - font-size: 12x; + font-size: 13px; white-space: pre-wrap; } +hr { + display: block; + height: 0px; + border: 0; + border-bottom: 1px solid var(--border-secondary); + margin: 1em 0; + padding: 0; + margin: 8px 0; +} + input { font-family: Manrope, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; @@ -67,21 +83,25 @@ input { button { border: none; - display: flex; + display: inline-flex; align-items: center; justify-content: flex-start; cursor: pointer; } +button:disabled { + cursor: not-allowed !important; +} + button.main-button { - height: 64px; - padding: 0 48px 0 40px; + height: 56px; + padding: 0 32px 0 28px; background-color: white; border-radius: 8px; font-family: Manrope, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; font-weight: 600; - font-size: 20px; + font-size: 16px; line-height: 30px; box-sizing: border-box; color: var(--moss); @@ -103,7 +123,7 @@ button.main-button:active { } button.main-button svg { - margin-right: 12px; + margin-right: 8px; } .button-container { @@ -147,7 +167,7 @@ a.main-link:hover:after { .card { border-radius: 8px; - border: 2px solid var(--translucent); + border: 1px solid var(--border-card); } .primary { @@ -159,3 +179,40 @@ a.main-link:hover:after { color: var(--foreground-card); background-color: var(--background-card); } + +@keyframes bounce { + 0%, + 20%, + 50%, + 80%, + 100% { + transform: translateY(0); + } + 40% { + transform: translateY(-12px); + } + 60% { + transform: translateY(-4px); + } +} + +.bounce { + animation: bounce 1s ease-out 1; +} + +@keyframes spin { + 0%, + 20% { + transform: rotate(0); + } + 40% { + transform: rotate(200deg); + } + 100% { + transform: rotate(540deg); + } +} + +.spin { + animation: spin 1000ms ease-out 1; +} diff --git a/src/components/App/App.tsx b/src/components/App/App.tsx index 8eb4a11..b6e6843 100644 --- a/src/components/App/App.tsx +++ b/src/components/App/App.tsx @@ -8,7 +8,7 @@ import IconGrid from "@/components/IconGrid"; import Footer from "@/components/Footer"; import ErrorBoundary from "@/components/ErrorBoundary"; import Notice from "@/components/Notice"; -import Recipes from "@/components/Recipes"; +// import Recipes from "@/components/Recipes"; import { useIconParameters, usePersistSettings, @@ -29,9 +29,11 @@ const App: React.FC = () => { () => ({ "--foreground": isDark ? "white" : "var(--moss)", "--foreground-card": isDark ? "white" : "var(--moss)", - "--background": isDark ? "var(--stone)" : "var(--foam)", - "--background-card": isDark ? "var(--stone)" : "var(--foam)", - "--background-tab": isDark ? "var(--moss)" : "white", + "--background": isDark ? "var(--slate)" : "var(--vellum)", + "--background-card": isDark ? "var(--stone)" : "var(--vellum)", + "--background-layer": isDark ? "var(--scrim)" : "var(--translucent)", + "--border-card": isDark ? "var(--shadow)" : "var(--moss-shadow)", + "--border-secondary": isDark ? "var(--scrim)" : "var(--moss-shadow)", }), [isDark] ); @@ -49,7 +51,7 @@ const App: React.FC = () => { - + {/* */}
); diff --git a/src/components/Banner/Banner.css b/src/components/Banner/Banner.css index 24452f7..101ec24 100644 --- a/src/components/Banner/Banner.css +++ b/src/components/Banner/Banner.css @@ -10,6 +10,7 @@ color: white; margin: auto; z-index: 1; + pointer-events: none; } .banner { @@ -31,7 +32,7 @@ align-items: center; justify-content: space-between; gap: 20px; - max-width: 560px; + max-width: 600px; margin: auto; padding: 12px 12px 12px 16px; color: var(--moss); @@ -41,6 +42,7 @@ filter: drop-shadow(2px 2px 0 var(--moss-shadow)); font-family: "IBM Plex Mono"; font-size: 14px; + pointer-events: initial; } .banner-button { @@ -61,3 +63,22 @@ align-items: center; gap: 12px; } + +@media screen and (max-width: 719px) { + .banner-container { + padding: 0; + } + + .banner-content { + align-items: flex-start; + border-radius: 0; + border: none; + border-bottom: 1px solid var(--moss); + margin: 0; + max-width: unset; + } + + .message { + align-items: flex-start; + } +} diff --git a/src/components/Footer/Footer.css b/src/components/Footer/Footer.css index 807a54a..935e7b6 100644 --- a/src/components/Footer/Footer.css +++ b/src/components/Footer/Footer.css @@ -10,6 +10,7 @@ footer { border-radius: 50%; z-index: 2; font-size: 56px; + justify-content: center; } #back-to-top-button:active { @@ -18,7 +19,7 @@ footer { } #back-to-top-button svg { - margin-right: unset; + margin-right: 0 !important; } .container { diff --git a/src/components/Header/Header.css b/src/components/Header/Header.css index 169d39c..01c2a21 100644 --- a/src/components/Header/Header.css +++ b/src/components/Header/Header.css @@ -2,7 +2,7 @@ header { overflow: hidden; position: relative; color: var(--moss); - background-color: var(--lichen); + background-color: var(--vellum); } .header-contents { @@ -14,6 +14,28 @@ header { margin: auto; } +@keyframes tickle { + 0% { + transform: none; + } + 50% { + transform: scale(1.1) rotate(-12deg) translateY(-2px); + } + 100% { + transform: scale(1.2) rotate(12deg) translateY(-4px); + } +} + +#logo { + margin-top: 56px; + transition: color 150ms ease; +} + +#logo:hover { + color: var(--sand); + animation: tickle 250ms ease 0ms infinite alternate forwards; +} + .illustrations-top { position: relative; } @@ -22,7 +44,8 @@ header { position: relative; } -.intro { +.intro, +.illustrations-top { margin: 0 8%; max-width: 666px; } @@ -37,20 +60,37 @@ header { cursor: cell; } +#paperclips { + position: absolute; + left: 110px; + top: 152px; +} + +#paperclips-three { + display: initial; + position: absolute; + left: 776px; + top: 370px; +} + .map { position: absolute; - transform: translate(300px, -44px) rotate(-10deg); + top: -44px; + left: 300px; + transform: rotate(-10deg); } .synth { position: absolute; - transform: translate(800px, -274px) rotate(3deg); + top: -235px; + left: 800px; + transform: rotate(3deg); } .ipad { position: absolute; - top: -620px; - left: 500px; + top: -626px; + left: 308px; } .watch { @@ -69,81 +109,45 @@ header { opacity: 0; } -#paperclips-three { - display: none; -} - @media screen and (max-width: 1239px) { .illustrations-top { height: 382px; } - #marker-purple { - position: absolute; - left: 28px; - top: -158px; + .map { + top: -10px; + left: -80px; } - .billiard-ball { - position: absolute; - left: 132px; - top: -98px; + .watch { + top: 8px; + left: 90px; } #paperclips { - position: absolute; - left: 110px; - top: 152px; + display: none; } - - .warning { - position: absolute; - left: 394px; - top: -304px; - } - - .tablet { - position: absolute; - left: 672px; - top: -900px; - } - - /* .ipad { - position: absolute; - top: -571px; - left: 500px; - } */ } @media screen and (min-width: 720px) and (max-width: 1239px) { - .intro { - margin: 0 auto; - } - .illustrations-bottom { - height: 612px; + height: 500px; } - .cutting-mat { - position: absolute; - left: 96px; + .synth { + top: -110px; + left: 620px; } - .receipt { - position: absolute; - left: -36px; - top: 190px; - } - - .calculator { - position: absolute; - left: 632px; - top: 170px; + #paperclips-three { + top: 506px; + left: 550px; } } @media screen and (min-width: 1240px) { - .intro { + .intro, + .illustrations-top { margin: 0 auto 0 140px; } @@ -152,59 +156,7 @@ header { } .illustrations-bottom { - height: 606px; - } - - #marker-purple { - position: absolute; - left: 144px; - top: -158px; - } - - .billiard-ball { - position: absolute; - left: 900px; - top: 400px; - } - - #paperclips { - display: none; - } - - #paperclips-three { - display: initial; - position: absolute; - left: 908px; - top: 360px; - } - - .warning { - position: absolute; - left: 1170px; - top: 400px; - } - - .tablet { - position: absolute; - left: 578px; - top: -900px; - } - - .cutting-mat { - position: absolute; - left: 120px; - } - - .receipt { - position: absolute; - left: -16px; - top: 190px; - } - - .calculator { - position: absolute; - left: 924px; - top: 114px; + height: 550px; } } @@ -215,11 +167,35 @@ header { } .illustrations-top { - height: 352px; + height: 200px; + } + + #paperclips-three { + top: -70px; + left: -167px; + } + + .ipad { + display: none; + } + + .map { + top: 0px; + left: -60px; + } + + .synth { + top: -340px; + left: 400px; + } + + .watch { + top: 0; + left: 100px; } .illustrations-bottom { - display: none; + height: 360px; } .links { diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index 8ac3526..c628bf3 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -6,13 +6,17 @@ import { import Banner from "@/components/Banner"; -import { ReactComponent as MarkerPurple } from "@/assets/marker-purple.svg"; -import { ReactComponent as PaperClips } from "@/assets/paperclips-header-mobile.svg"; -import { ReactComponent as PaperClipsThree } from "@/assets/paperclips-header.svg"; +import { ReactComponent as PhosphorLogo } from "@/assets/phosphor-logo.svg"; +import { ReactComponent as PaperClipsTwo } from "@/assets/paperclips-2.svg"; +import { ReactComponent as PaperClipsThree } from "@/assets/paperclips-3.svg"; import { ReactComponent as IPad } from "@/assets/ipad.svg"; +import { ReactComponent as IPadSpec } from "@/assets/ipad-spec.svg"; import { ReactComponent as Map } from "@/assets/map.svg"; +import { ReactComponent as MapSpec } from "@/assets/map-spec.svg"; import { ReactComponent as Synth } from "@/assets/synth.svg"; -import { ReactComponent as Watch } from "@/assets/watch.svg"; +import { ReactComponent as SynthSpec } from "@/assets/synth-spec.svg"; + +import { Watch, WatchSpec } from "./dynamic/Watch"; import Links from "@/components/Links"; import "./Header.css"; @@ -37,7 +41,7 @@ const Header = (_: HeaderProps) => {
- + Phosphor 2.0 is out, with some big updates and some small API changes. Check our{" "} @@ -51,27 +55,17 @@ const Header = (_: HeaderProps) => {
- - - +

- Phosphor is a flexible icon
- family for interfaces and more. + Phosphor is a flexible icon family for interfaces, diagrams, + presentations — whatever, really.

+ + - + + + + FOOO + + - {/* */} - {/* */} - - {/* */} - {/* */} - - {/* */} - {/* */} +
diff --git a/src/components/Header/dynamic/Watch.tsx b/src/components/Header/dynamic/Watch.tsx new file mode 100644 index 0000000..234a033 --- /dev/null +++ b/src/components/Header/dynamic/Watch.tsx @@ -0,0 +1,681 @@ +import { SVGAttributes } from "react"; + +import { iconCount } from "@/lib/icons"; + +export const Watch = (props: SVGAttributes) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {iconCount} icons + + + + + + + + + + + + + + + + + + + ); +}; + +export const WatchSpec = (props: SVGAttributes) => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {iconCount} icons + + + + + + + + + + + + ); +}; diff --git a/src/components/IconGrid/IconGrid.css b/src/components/IconGrid/IconGrid.css index a08f97b..32021b6 100644 --- a/src/components/IconGrid/IconGrid.css +++ b/src/components/IconGrid/IconGrid.css @@ -1,7 +1,6 @@ .grid-container { position: relative; padding: 32px 16px; - /* min-height: 80vh; */ z-index: 1; content-visibility: auto; color: var(--foreground); @@ -33,52 +32,33 @@ } .grid-item:hover { - background-color: var(--translucent); + background-color: var(--background-layer); } .grid-item:focus { outline: none; - border: 2px solid var(--translucent); + border: 1px solid var(--background-layer); } .grid-item p { font-size: 12px; line-height: 16px; - color: var(--neutral); + opacity: 0.75; margin-top: 12px; text-align: center; } -@media screen and (max-width: 536px) { - .grid-container { - padding: 32px 8px; - } - - .grid-item { - width: 108px; - height: unset; - padding: 4px 0; - justify-content: flex-start; - border: 2px solid transparent; - } - - .grid-item p { - padding: 0 4px; - } -} - .versioning { margin-top: 2px; - opacity: 0.6; + opacity: 0.75; } .snippet { + position: relative; width: 100%; } .snippet pre { - display: flex; - align-items: flex-start; text-overflow: ellipsis; -moz-user-select: all; -webkit-user-select: all; @@ -97,22 +77,14 @@ } } -.snippet span { - flex: 1; -} - .snippet button { - background-color: transparent; + position: absolute; + top: -8px; + right: -8px; margin: 0; - padding: 0; - height: 24px; cursor: pointer; } -.snippet button:disabled { - cursor: not-allowed; -} - .button-row { display: flex; flex-wrap: wrap; @@ -132,6 +104,11 @@ margin-right: 8px; } +.disabled { + color: var(--neutral); + user-select: none; +} + .close-icon { position: absolute; top: 12px; @@ -179,17 +156,24 @@ min-height: 80vh; max-width: 1120px; margin: auto; - white-space: nowrap; } -.empty-list p { - max-width: 80%; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; +.empty-list-box p { margin-bottom: 0; } +.empty-list-box { + max-width: 80%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 16px; + padding: 32px; + border-radius: 8px; + background-color: var(--background-layer); +} + .beacon { position: relative; top: -96px; @@ -201,11 +185,10 @@ aside.detail-footer { margin: auto; max-width: 1120px; display: grid; - grid-template-columns: 232px 1fr; + grid-template-columns: 280px 1fr; gap: 24px; padding: 12px 24px; - height: 136px; - /* filter: drop-shadow(2px 2px 0 var(--moss-shadow)); */ + height: 146px; } figure { @@ -229,18 +212,51 @@ figcaption > p { .detail-preview { display: flex; flex-direction: column; - justify-content: center; - gap: 24px; + justify-content: space-between; + padding-block: 8px; +} + +.detail-meta { + display: flex; + align-items: center; + justify-content: space-between; + gap: 4px; } .detail-actions { - display: flex; - flex-direction: row; + /* display: inline-flex; align-items: center; - gap: 8px; + justify-content: flex-start; */ + display: inline-grid; + grid-template-columns: 66px 66px 92px; + gap: 6px; +} + +.action-button { + color: var(--foreground); + background-color: transparent; + font-size: 11px; + padding: 6px; + border-radius: 4px; +} + +.action-button.text { + padding: 6px 10px 6px 6px; +} + +.action-button:hover { + background-color: var(--sheer) !important; +} + +.detail-actions .action-button svg { + margin-right: 6px; } @media screen and (max-width: 719px) { + .grid-container { + padding: 16px 8px; + } + .close-button { top: 4px; right: 12px; @@ -252,9 +268,21 @@ figcaption > p { display: flex; flex-direction: column; height: 440px; + margin-inline: -10px; + border-radius: 0; } } -.action-button svg { - margin-right: 6px; +@media screen and (max-width: 536px) { + .grid-item { + width: 108px; + height: unset; + padding: 4px 0; + justify-content: flex-start; + border: 1px solid transparent; + } + + .grid-item p { + padding: 0 4px; + } } diff --git a/src/components/IconGrid/IconGrid.tsx b/src/components/IconGrid/IconGrid.tsx index 5bc3e0d..891ab1a 100644 --- a/src/components/IconGrid/IconGrid.tsx +++ b/src/components/IconGrid/IconGrid.tsx @@ -9,10 +9,11 @@ import { iconColorAtom, filteredQueryResultsSelector, isDarkThemeSelector, + searchQueryAtom, } from "@/state"; import Notice from "@/components/Notice"; -import DetailFooter from "./DetailFooter"; +import Panel from "./Panel"; import IconGridItem from "./IconGridItem"; import TagCloud from "./TagCloud"; import "./IconGrid.css"; @@ -34,6 +35,7 @@ const IconGrid = (_: IconGridProps) => { const size = useRecoilValue(iconSizeAtom); const color = useRecoilValue(iconColorAtom); const isDark = useRecoilValue(isDarkThemeSelector); + const query = useRecoilValue(searchQueryAtom); const filteredQueryResults = useRecoilValue(filteredQueryResultsSelector); const originOffset = useRef({ top: 0, left: 0 }); @@ -45,8 +47,15 @@ const IconGrid = (_: IconGridProps) => { if (!filteredQueryResults.length) return ( - - Try searching a category or keyword: + + No results for "{query}". Try searching a category or + keyword: + + } + > ); @@ -66,7 +75,7 @@ const IconGrid = (_: IconGridProps) => { /> ))} - +
); diff --git a/src/components/IconGrid/IconGridItem.tsx b/src/components/IconGrid/IconGridItem.tsx index 505f40d..c0345d0 100644 --- a/src/components/IconGrid/IconGridItem.tsx +++ b/src/components/IconGrid/IconGridItem.tsx @@ -76,7 +76,7 @@ const IconGridItem = (props: IconGridItemProps) => { tabIndex={0} style={{ ...style, - backgroundColor: isOpen ? "var(--translucent)" : undefined, + backgroundColor: isOpen ? "var(--background-layer)" : undefined, }} custom={delayRef} transition={transition} diff --git a/src/components/IconGrid/DetailFooter.tsx b/src/components/IconGrid/Panel.tsx similarity index 52% rename from src/components/IconGrid/DetailFooter.tsx rename to src/components/IconGrid/Panel.tsx index b21c321..9814a60 100644 --- a/src/components/IconGrid/DetailFooter.tsx +++ b/src/components/IconGrid/Panel.tsx @@ -1,4 +1,10 @@ -import React, { useRef, useEffect, CSSProperties, useMemo } from "react"; +import React, { + useRef, + useState, + useEffect, + useMemo, + HTMLAttributes, +} from "react"; import { useRecoilValue, useRecoilState } from "recoil"; import { useHotkeys } from "react-hotkeys-hook"; import { motion, AnimatePresence, Variants } from "framer-motion"; @@ -7,8 +13,10 @@ import { saveAs } from "file-saver"; import { Copy, CheckCircle, - DownloadSimple, + ArrowFatLinesDown, XCircle, + CaretDoubleLeft, + CaretDoubleRight, } from "@phosphor-icons/react"; import ReactGA from "react-ga4"; @@ -41,15 +49,19 @@ const variants: Record = { const RENDERED_SNIPPETS = [ SnippetType.REACT, - SnippetType.VUE, SnippetType.HTML, + SnippetType.VUE, SnippetType.FLUTTER, SnippetType.ELM, ]; -const buttonColor = "#35313D"; -const successColor = "#1FA647"; -const disabledColor = "#B7B7B7"; +enum CopyType { + SVG, + SVG_RAW, + SVG_DATA, + PNG, + PNG_DATA, +} function cloneWithSize(svg: SVGSVGElement, size: number): SVGSVGElement { const sized = svg.cloneNode(true) as SVGSVGElement; @@ -58,20 +70,43 @@ function cloneWithSize(svg: SVGSVGElement, size: number): SVGSVGElement { return sized; } -const DetailFooter = () => { +const ActionButton = ( + props: { + active?: boolean; + label: string; + download?: boolean; + } & HTMLAttributes +) => { + const { active, download, label, ...rest } = props; + const Icon = download ? ArrowFatLinesDown : Copy; + return ( + + ); +}; + +const Panel = () => { const [entry, setSelectionEntry] = useRecoilState(selectionEntryAtom); const weight = useRecoilValue(iconWeightAtom); const size = useRecoilValue(iconSizeAtom); const color = useRecoilValue(iconColorAtom); const isDark = useRecoilValue(isDarkThemeSelector); - const [copied, setCopied] = useTransientState( + const [copied, setCopied] = useTransientState( false, 2000 ); const ref = useRef(null); - const [{ i }, setInitialTab] = useSessionStorage("tab", { i: 0 }); + const [showMoreActions, setShowMoreActions] = useState(false); + + const [i, setInitialTab] = useSessionStorage("tab", 0); const isMobile = useMediaQuery("(max-width: 719px)"); @@ -88,11 +123,6 @@ const DetailFooter = () => { color, }); - const snippetButtonStyle: CSSProperties = - weight === "duotone" - ? { color: disabledColor, userSelect: "none" } - : { color: "currentcolor" }; - const tabs = [ { header: "Tags", @@ -101,9 +131,9 @@ const DetailFooter = () => { name={entry.name} tags={Array.from( new Set([ + ...entry.tags, ...entry.categories, ...entry.name.split("-"), - ...entry.tags, ]) )} /> @@ -117,31 +147,27 @@ const DetailFooter = () => { header: type, content: (
-
-                
+              
+                
                   {isWeightSupported
                     ? snippets[type]
                     : "This weight is not yet supported"}
                 
                 
-              
-              
             
- setInitialTab({ i })} - /> + + ); }; diff --git a/src/components/StyleInput/StyleInput.css b/src/components/StyleInput/StyleInput.css index 279205e..9312a09 100644 --- a/src/components/StyleInput/StyleInput.css +++ b/src/components/StyleInput/StyleInput.css @@ -28,7 +28,7 @@ .react-dropdown-select:focus-within { background-color: white; - color: black; + color: var(--moss); outline: none !important; box-shadow: none !important; } @@ -62,21 +62,21 @@ box-shadow: none; } .react-dropdown-select-item { - color: black; + color: var(--moss); } .react-dropdown-select-item:hover { - background-color: var(--yellow) !important; + background-color: var(--acid) !important; } .react-dropdown-select-item.react-dropdown-select-item-selected, .react-dropdown-select-item.react-dropdown-select-item-active { - color: black !important; - background-color: var(--yellow) !important; + color: var(--moss) !important; + background-color: var(--acid) !important; } .react-dropdown-select-item:focus { - color: black !important; - background-color: var(--yellow) !important; + color: var(--moss) !important; + background-color: var(--acid) !important; } .react-dropdown-select-item.react-dropdown-select-item-disabled { diff --git a/src/components/StyleInput/StyleInput.tsx b/src/components/StyleInput/StyleInput.tsx index c18c285..f5571ec 100644 --- a/src/components/StyleInput/StyleInput.tsx +++ b/src/components/StyleInput/StyleInput.tsx @@ -1,7 +1,7 @@ import { useMemo } from "react"; import { useRecoilState } from "recoil"; import Select from "react-dropdown-select"; -import { PencilLine } from "@phosphor-icons/react"; +import { PencilSimpleLine } from "@phosphor-icons/react"; import { IconStyle } from "@phosphor-icons/core"; import { iconWeightAtom } from "@/state"; @@ -14,32 +14,32 @@ const options: WeightOption[] = [ { key: "Thin", value: IconStyle.THIN, - icon: , + icon: , }, { key: "Light", value: IconStyle.LIGHT, - icon: , + icon: , }, { key: "Regular", value: IconStyle.REGULAR, - icon: , + icon: , }, { key: "Bold", value: IconStyle.BOLD, - icon: , + icon: , }, { key: "Fill", value: IconStyle.FILL, - icon: , + icon: , }, { key: "Duotone", value: IconStyle.DUOTONE, - icon: , + icon: , }, ]; diff --git a/src/components/Tabs/Tabs.css b/src/components/Tabs/Tabs.css index 16a8f48..0aff447 100644 --- a/src/components/Tabs/Tabs.css +++ b/src/components/Tabs/Tabs.css @@ -38,17 +38,17 @@ button.tab:hover:not(.active) { } button.tab.active { - background-color: var(--background-tab); + background-color: var(--background-layer); border-bottom: none; } .tab-content { flex: 1; - height: 77px; - max-height: 77px; + height: 86px; + max-height: 86px; padding: 20px 20px 10px; border-radius: 8px; - background-color: var(--background-tab); + background-color: var(--background-layer); overflow-y: auto; } diff --git a/src/hooks/useSessionStorage.ts b/src/hooks/useSessionStorage.ts index 9ce2453..0b7793b 100644 --- a/src/hooks/useSessionStorage.ts +++ b/src/hooks/useSessionStorage.ts @@ -5,7 +5,7 @@ type Initializer = () => S; type Setter = (prev: S) => S; type Action = S | Setter | Initializer; -function expand(action: Action, prev?: S) { +function expand(action: Action, prev?: S) { if (typeof action === "function") { return (action as Setter)(prev!); } else { @@ -13,13 +13,19 @@ function expand(action: Action, prev?: S) { } } -export default function useSessionStorage( +export default function useSessionStorage( key: string, fallbackState: S | (() => S) ): [S, Dispatch>, (partial: Partial) => void] { const [value, setValue] = useState(() => { let val = sessionStorage.getItem(STORAGE_KEY + key); - if (val) return JSON.parse(val) as S; + if (val) { + try { + return JSON.parse(val) as S; + } catch (_) { + return val as S; + } + } return expand(fallbackState); }); diff --git a/src/lib/index.ts b/src/lib/index.ts index 921793a..f03970b 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -8,7 +8,7 @@ export interface IconEntry extends CoreEntry { export enum SnippetType { REACT = "React", VUE = "Vue", - HTML = "HTML/CSS", + HTML = "Web", FLUTTER = "Flutter", ELM = "Elm", }