Skip to content

Commit 52fd029

Browse files
committed
feat: swap fontpicker combobox for fontpicker with image previews
1 parent e54afff commit 52fd029

File tree

5 files changed

+167
-0
lines changed

5 files changed

+167
-0
lines changed

packages/editor/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"react": "^18.2.0",
5656
"react-dom": "^18.2.0",
5757
"react-draggable-tree": "^0.7.0",
58+
"react-fontpicker-ts": "^0.2.1",
5859
"react-merge-refs": "^2.0.1",
5960
"react-sortablejs": "^6.1.4",
6061
"scroll-into-view-if-needed": "^3.0.10",

packages/editor/src/views/inspector/style/TextPane.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { InspectorTargetContext } from "../components/InspectorTargetContext";
2222
import { projectState } from "../../../state/ProjectState";
2323
import { InspectorComboBox } from "./inputs/InspectorComboBox";
2424
import googleFonts from "@uimix/foundation/src/fonts/GoogleFonts.json";
25+
import { InspectorFontPicker } from "./inputs/InspectorFontPicker";
2526

2627
const googleFontOptions = googleFonts.items.map((item) => ({
2728
value: item.family,
@@ -79,12 +80,20 @@ export const TextPane: React.FC = observer(function TextPane() {
7980
/>
8081
<InspectorTargetContext.Provider value={textSelectables}>
8182
<div className="flex flex-col gap-2">
83+
{/*
8284
<InspectorComboBox
8385
get={(s) => s.style.fontFamily}
8486
set={(s, value) => {
8587
s.style.fontFamily = value ?? "Inter";
8688
}}
8789
options={googleFontOptions}
90+
/> */}
91+
<InspectorFontPicker
92+
get={(s) => s.style.fontFamily}
93+
set={(s, value) => {
94+
s.style.fontFamily = value ?? "Inter";
95+
}}
96+
options={googleFontOptions}
8897
/>
8998
<div className="grid grid-cols-2 gap-2">
9099
<InspectorNumberInput
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* You can customise fontpicker styling using these classes.
3+
* This example makes the fontpicker align better with the project's combobox styling.
4+
* Default styles commented out for reference below.
5+
*/
6+
.fontpicker {
7+
border: unset;
8+
}
9+
.fontpicker {
10+
border: unset;
11+
background: unset;
12+
}
13+
.fontpicker__search {
14+
background-color: #f5f5f5;
15+
}
16+
.fontpicker__popout {
17+
border: 1px solid #e5e5e5;
18+
border-radius: 0.25rem;
19+
background: #f5f5f5;
20+
}
21+
.fontpicker__option {
22+
background: unset;
23+
}
24+
.fontpicker__option.selected {
25+
background: #d4d4d4;
26+
}
27+
.fontpicker__nomatches {
28+
background: unset;
29+
}
30+
.fontpicker__preview {
31+
-webkit-filter: unset;
32+
filter: unset;
33+
}
34+
/*
35+
.fontpicker,
36+
.fontpicker * {
37+
box-sizing: border-box;
38+
}
39+
.fontpicker {
40+
border: 1px solid;
41+
display: block;
42+
position: relative;
43+
background: #333;
44+
}
45+
.fontpicker__preview {
46+
-webkit-filter: invert(100%);
47+
filter: invert(100%);
48+
}
49+
.fontpicker__search {
50+
position: absolute;
51+
top: 0;
52+
left: 0;
53+
width: 100%;
54+
height: 100%;
55+
opacity: 0;
56+
padding: 0 10px;
57+
cursor: pointer;
58+
font-size: 16px;
59+
background-color: #555;
60+
}
61+
.fontpicker__search:focus {
62+
cursor: text;
63+
opacity: 1;
64+
}
65+
.fontpicker__popout {
66+
position: absolute;
67+
top: 100%;
68+
left: 0;
69+
width: 100%;
70+
border: 1px solid;
71+
max-height: calc(12em + 1px);
72+
overflow-y: auto;
73+
overflow-x: hidden;
74+
z-index: 2;
75+
background: #555;
76+
opacity: 0;
77+
transform: scaleY(0.001);
78+
}
79+
.fontpicker__popout.fontpicker__active {
80+
opacity: 1;
81+
transform: scale(1);
82+
}
83+
.fontpicker__option {
84+
background: #555;
85+
}
86+
.fontpicker__option.selected {
87+
background: #6789ab;
88+
}
89+
.fontpicker__nomatches {
90+
height: 2em;
91+
line-height: 2em;
92+
background: #555;
93+
text-align: center;
94+
color: #eee;
95+
}
96+
*/
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { useContext } from "react";
2+
import { action } from "mobx";
3+
import { observer } from "mobx-react-lite";
4+
import { twMerge } from "tailwind-merge";
5+
import FontPicker from 'react-fontpicker-ts';
6+
import 'react-fontpicker-ts/dist/index.css';
7+
import { Mixed, sameOrMixed } from "@uimix/foundation/src/utils/Mixed";
8+
import { Selectable } from "@uimix/model/src/models";
9+
import { InspectorTargetContext } from "../../components/InspectorTargetContext";
10+
import { projectState } from "../../../../state/ProjectState";
11+
import { SelectOption } from "@uimix/foundation/src/components/Select";
12+
import './InspectorFontPicker.css';
13+
14+
export const InspectorFontPicker = observer(function InspectorFontPicker({
15+
className,
16+
get,
17+
set,
18+
options,
19+
}: {
20+
className?: string;
21+
get: (selectable: Selectable) => string | undefined;
22+
set: (selectable: Selectable, value?: string) => void;
23+
options?: readonly SelectOption<string>[];
24+
}) {
25+
const selectables = useContext(InspectorTargetContext);
26+
const value = sameOrMixed(selectables.map((s) => get(s)));
27+
28+
return (
29+
<FontPicker
30+
className={twMerge(
31+
`fontpicker
32+
relative
33+
outline-0 w-full h-7 bg-macaron-uiBackground rounded
34+
focus-within:ring-1 ring-inset ring-macaron-active text-macaron-text text-macaron-base`,
35+
className
36+
)}
37+
googleFonts={options?.map((option: SelectOption<string>) => option.value)}
38+
defaultValue={value === Mixed ? "Mixed" : undefined}
39+
value={action((value: string) => {
40+
for (const selectable of selectables) {
41+
set(selectable, value);
42+
}
43+
projectState.undoManager.stopCapturing();
44+
})}
45+
/>
46+
);
47+
});

pnpm-lock.yaml

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)