Open derwaldgeist opened 4 months ago
Here is the documentation on the properties that this component requires: https://github.com/FortAwesome/fa-icon-chooser/blob/main/packages/fa-icon-chooser/src/components/fa-icon-chooser/readme.md.
I'm not sure how you are expected to mount this using plain text given some of the properties are javascript functions. I could see a version of this that only requires a version or api token / kit token.
With plain JS, I think you can create the element and add the properties, then mount to the dom. In React, you can provide javascript functions as properties which is what we've done on our project.
Here is what I've done for React (TypeScript):
You need either a version like 6.6.0
or a api token
and kit token
. As far as I can tell the API URL
is just https://api.fontawesome.com
. You can start with the version since that doesn't require authorization. Maybe someone else can provide context as to why we need to provide getUrlText
when it seems like common functionality. :shrug:
import { QueryHandler } from '@fortawesome/fa-icon-chooser/dist/types/components/fa-icon-chooser/fa-icon-chooser';
import { UrlTextFetcher } from '@fortawesome/fa-icon-chooser/dist/types/utils/utils';
import config from 'temp/config';
// See https://github.com/FortAwesome/fa-icon-chooser/blob/main/packages/fa-icon-chooser/dev/runtime.js
// See https://github.com/FortAwesome/fa-icon-chooser/tree/main/packages/fa-icon-chooser-react.
// If a kitToken is provided, authorization is required with `apiToken`.
const {
fontAwesomeApiUrl: apiURL,
fontAwesomeApiToken: apiToken,
fontAwesomeVersion: version,
fontAwesomeKitToken: kitToken,
} = config;
export { version, kitToken };
// Use memory storage for now.
type AccessToken = {
token: string;
expiresAtEpochSeconds: number;
};
let accessToken: AccessToken | undefined = undefined;
// This function loads the Font Awesome library (as Text) which is then executed by the web component.
// Essentially, loads a configurable version of the library.
export const getUrlText: UrlTextFetcher = (url) =>
fetch(url).then((response) => {
if (response.ok) {
return response.text();
} else {
throw new Error(`DEBUG: bad query for url: ${url}`);
}
});
export const getAccessToken = () => {
// If we don't have an apiToken, we don't need to authenticate.
if (!apiToken) {
return Promise.resolve();
}
// If we already have a valid token, we don't need to get another one.
if (accessToken && Math.floor(Date.now() / 1000) <= accessToken.expiresAtEpochSeconds) {
return Promise.resolve();
}
return fetch(`${apiURL}/token`, {
method: 'POST',
headers: {
authorization: `Bearer ${apiToken}`,
},
})
.then((response) => {
if (!response.ok) {
throw new Error('Failed to get an access token.');
}
return response.json();
})
.then((data) => {
accessToken = {
token: data['access_token'],
expiresAtEpochSeconds: Math.floor(Date.now() / 1000) + data['expires_in'],
};
});
};
// Make queries for the Font Awesome chooser.
// This function handles authentication for the web component.
export const handleQuery: QueryHandler = (query, variables) =>
getAccessToken()
.then(() => {
if (kitToken && !accessToken?.token) {
throw new Error(
'When using a kit, you must provide an apiToken so that an authorization token can be obtained.'
);
}
const headers: {
[key: string]: string;
} = {
'Content-Type': 'application/json',
};
if (accessToken) {
headers['Authorization'] = `Bearer ${accessToken.token}`;
}
const cleanedQuery = query.replace(/\s+/g, ' ');
return fetch(apiURL, {
method: 'POST',
headers,
body: JSON.stringify({
query: cleanedQuery,
variables,
}),
});
})
.then((response) => {
if (!response.ok) {
throw new Error('bad query');
}
return response.json();
});
We then load the component with
<FaIconChooser
version={version}
kitToken={kitToken}
handleQuery={handleQuery}
getUrlText={getUrlText}
onFinish={handleResult}
/>
Where handleResult
looks like
const handleResult = (event: CustomEvent<IconChooserResult>): void => {
const prefix = event.detail?.prefix ?? '';
const iconName = event.detail?.iconName ?? '';
//...
};
The Github page claims that there is some setup instructions on this page:
https://github.com/FortAwesome/fa-icon-chooser/blob/main/packages/fa-icon-chooser/src/components/fa-icon-chooser/readme.md
but I can't find any there.
I am trying to embed the web component in Vue and would love to see how the web component has to be hooked up so it works. It would be enough to see this for plain vanilla JS. Yet not everybody is a web component pro :)